diff options
Diffstat (limited to 'libgo/go/asn1')
-rw-r--r-- | libgo/go/asn1/asn1.go | 84 | ||||
-rw-r--r-- | libgo/go/asn1/asn1_test.go | 14 | ||||
-rw-r--r-- | libgo/go/asn1/common.go | 12 | ||||
-rw-r--r-- | libgo/go/asn1/marshal.go | 64 | ||||
-rw-r--r-- | libgo/go/asn1/marshal_test.go | 24 |
5 files changed, 116 insertions, 82 deletions
diff --git a/libgo/go/asn1/asn1.go b/libgo/go/asn1/asn1.go index c531451..5f470ae 100644 --- a/libgo/go/asn1/asn1.go +++ b/libgo/go/asn1/asn1.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The asn1 package implements parsing of DER-encoded ASN.1 data structures, +// Package asn1 implements parsing of DER-encoded ASN.1 data structures, // as defined in ITU-T Rec X.690. // // See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,'' @@ -373,7 +373,7 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i // parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse // a number of ASN.1 values from the given byte array and returns them as a // slice of Go values of the given type. -func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflect.Type) (ret *reflect.SliceValue, err os.Error) { +func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err os.Error) { expectedTag, compoundType, ok := getUniversalType(elemType) if !ok { err = StructuralError{"unknown Go type for slice"} @@ -409,7 +409,7 @@ func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflec params := fieldParameters{} offset := 0 for i := 0; i < numElements; i++ { - offset, err = parseField(ret.Elem(i), bytes, offset, params) + offset, err = parseField(ret.Index(i), bytes, offset, params) if err != nil { return } @@ -418,13 +418,13 @@ func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflec } var ( - bitStringType = reflect.Typeof(BitString{}) - objectIdentifierType = reflect.Typeof(ObjectIdentifier{}) - enumeratedType = reflect.Typeof(Enumerated(0)) - flagType = reflect.Typeof(Flag(false)) - timeType = reflect.Typeof(&time.Time{}) - rawValueType = reflect.Typeof(RawValue{}) - rawContentsType = reflect.Typeof(RawContent(nil)) + bitStringType = reflect.TypeOf(BitString{}) + objectIdentifierType = reflect.TypeOf(ObjectIdentifier{}) + enumeratedType = reflect.TypeOf(Enumerated(0)) + flagType = reflect.TypeOf(Flag(false)) + timeType = reflect.TypeOf(&time.Time{}) + rawValueType = reflect.TypeOf(RawValue{}) + rawContentsType = reflect.TypeOf(RawContent(nil)) ) // invalidLength returns true iff offset + length > sliceLength, or if the @@ -461,13 +461,12 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam } result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]} offset += t.length - v.(*reflect.StructValue).Set(reflect.NewValue(result).(*reflect.StructValue)) + v.Set(reflect.ValueOf(result)) return } // Deal with the ANY type. - if ifaceType, ok := fieldType.(*reflect.InterfaceType); ok && ifaceType.NumMethod() == 0 { - ifaceValue := v.(*reflect.InterfaceValue) + if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 { var t tagAndLength t, offset, err = parseTagAndLength(bytes, offset) if err != nil { @@ -506,7 +505,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam return } if result != nil { - ifaceValue.Set(reflect.NewValue(result)) + v.Set(reflect.ValueOf(result)) } return } @@ -536,9 +535,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam err = StructuralError{"Zero length explicit tag was not an asn1.Flag"} return } - - flagValue := v.(*reflect.BoolValue) - flagValue.Set(true) + v.SetBool(true) return } } else { @@ -606,23 +603,20 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam switch fieldType { case objectIdentifierType: newSlice, err1 := parseObjectIdentifier(innerBytes) - sliceValue := v.(*reflect.SliceValue) - sliceValue.Set(reflect.MakeSlice(sliceValue.Type().(*reflect.SliceType), len(newSlice), len(newSlice))) + v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice))) if err1 == nil { - reflect.Copy(sliceValue, reflect.NewValue(newSlice).(reflect.ArrayOrSliceValue)) + reflect.Copy(v, reflect.ValueOf(newSlice)) } err = err1 return case bitStringType: - structValue := v.(*reflect.StructValue) bs, err1 := parseBitString(innerBytes) if err1 == nil { - structValue.Set(reflect.NewValue(bs).(*reflect.StructValue)) + v.Set(reflect.ValueOf(bs)) } err = err1 return case timeType: - ptrValue := v.(*reflect.PtrValue) var time *time.Time var err1 os.Error if universalTag == tagUTCTime { @@ -631,55 +625,53 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam time, err1 = parseGeneralizedTime(innerBytes) } if err1 == nil { - ptrValue.Set(reflect.NewValue(time).(*reflect.PtrValue)) + v.Set(reflect.ValueOf(time)) } err = err1 return case enumeratedType: parsedInt, err1 := parseInt(innerBytes) - enumValue := v.(*reflect.IntValue) if err1 == nil { - enumValue.Set(int64(parsedInt)) + v.SetInt(int64(parsedInt)) } err = err1 return case flagType: - flagValue := v.(*reflect.BoolValue) - flagValue.Set(true) + v.SetBool(true) return } - switch val := v.(type) { - case *reflect.BoolValue: + switch val := v; val.Kind() { + case reflect.Bool: parsedBool, err1 := parseBool(innerBytes) if err1 == nil { - val.Set(parsedBool) + val.SetBool(parsedBool) } err = err1 return - case *reflect.IntValue: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch val.Type().Kind() { case reflect.Int: parsedInt, err1 := parseInt(innerBytes) if err1 == nil { - val.Set(int64(parsedInt)) + val.SetInt(int64(parsedInt)) } err = err1 return case reflect.Int64: parsedInt, err1 := parseInt64(innerBytes) if err1 == nil { - val.Set(parsedInt) + val.SetInt(parsedInt) } err = err1 return } - case *reflect.StructValue: - structType := fieldType.(*reflect.StructType) + case reflect.Struct: + structType := fieldType if structType.NumField() > 0 && structType.Field(0).Type == rawContentsType { bytes := bytes[initOffset:offset] - val.Field(0).SetValue(reflect.NewValue(RawContent(bytes))) + val.Field(0).Set(reflect.ValueOf(RawContent(bytes))) } innerOffset := 0 @@ -697,11 +689,11 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam // adding elements to the end has been used in X.509 as the // version numbers have increased. return - case *reflect.SliceValue: - sliceType := fieldType.(*reflect.SliceType) + case reflect.Slice: + sliceType := fieldType if sliceType.Elem().Kind() == reflect.Uint8 { val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes))) - reflect.Copy(val, reflect.NewValue(innerBytes).(reflect.ArrayOrSliceValue)) + reflect.Copy(val, reflect.ValueOf(innerBytes)) return } newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem()) @@ -710,7 +702,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam } err = err1 return - case *reflect.StringValue: + case reflect.String: var v string switch universalTag { case tagPrintableString: @@ -729,7 +721,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)} } if err == nil { - val.Set(v) + val.SetString(v) } return } @@ -748,9 +740,9 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { if params.defaultValue == nil { return } - switch val := v.(type) { - case *reflect.IntValue: - val.Set(*params.defaultValue) + switch val := v; val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + val.SetInt(*params.defaultValue) } return } @@ -806,7 +798,7 @@ func Unmarshal(b []byte, val interface{}) (rest []byte, err os.Error) { // UnmarshalWithParams allows field parameters to be specified for the // top-level element. The form of the params is the same as the field tags. func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err os.Error) { - v := reflect.NewValue(val).(*reflect.PtrValue).Elem() + v := reflect.ValueOf(val).Elem() offset, err := parseField(v, b, 0, parseFieldParameters(params)) if err != nil { return nil, err diff --git a/libgo/go/asn1/asn1_test.go b/libgo/go/asn1/asn1_test.go index b776765..78f5628 100644 --- a/libgo/go/asn1/asn1_test.go +++ b/libgo/go/asn1/asn1_test.go @@ -267,11 +267,6 @@ func TestParseFieldParameters(t *testing.T) { } } -type unmarshalTest struct { - in []byte - out interface{} -} - type TestObjectIdentifierStruct struct { OID ObjectIdentifier } @@ -290,7 +285,10 @@ type TestElementsAfterString struct { A, B int } -var unmarshalTestData []unmarshalTest = []unmarshalTest{ +var unmarshalTestData = []struct { + in []byte + out interface{} +}{ {[]byte{0x02, 0x01, 0x42}, newInt(0x42)}, {[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}}, {[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}}, @@ -309,9 +307,7 @@ var unmarshalTestData []unmarshalTest = []unmarshalTest{ func TestUnmarshal(t *testing.T) { for i, test := range unmarshalTestData { - pv := reflect.MakeZero(reflect.NewValue(test.out).Type()) - zv := reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem()) - pv.(*reflect.PtrValue).PointTo(zv) + pv := reflect.New(reflect.TypeOf(test.out).Elem()) val := pv.Interface() _, err := Unmarshal(test.in, val) if err != nil { diff --git a/libgo/go/asn1/common.go b/libgo/go/asn1/common.go index f2254a4..1589877 100644 --- a/libgo/go/asn1/common.go +++ b/libgo/go/asn1/common.go @@ -133,14 +133,14 @@ func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) { case enumeratedType: return tagEnum, false, true } - switch t := t.(type) { - case *reflect.BoolType: + switch t.Kind() { + case reflect.Bool: return tagBoolean, false, true - case *reflect.IntType: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return tagInteger, false, true - case *reflect.StructType: + case reflect.Struct: return tagSequence, true, true - case *reflect.SliceType: + case reflect.Slice: if t.Elem().Kind() == reflect.Uint8 { return tagOctetString, false, true } @@ -148,7 +148,7 @@ func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) { return tagSet, true, true } return tagSequence, true, true - case *reflect.StringType: + case reflect.String: return tagPrintableString, false, true } return 0, false, false diff --git a/libgo/go/asn1/marshal.go b/libgo/go/asn1/marshal.go index 57b8f20..a3e1145 100644 --- a/libgo/go/asn1/marshal.go +++ b/libgo/go/asn1/marshal.go @@ -125,6 +125,28 @@ func int64Length(i int64) (numBytes int) { return } +func marshalLength(out *forkableWriter, i int) (err os.Error) { + n := lengthLength(i) + + for ; n > 0; n-- { + err = out.WriteByte(byte(i >> uint((n-1)*8))) + if err != nil { + return + } + } + + return nil +} + +func lengthLength(i int) (numBytes int) { + numBytes = 1 + for i > 255 { + numBytes++ + i >>= 8 + } + return +} + func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err os.Error) { b := uint8(t.class) << 6 if t.isCompound { @@ -149,12 +171,12 @@ func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err os.Error) { } if t.length >= 128 { - l := int64Length(int64(t.length)) + l := lengthLength(t.length) err = out.WriteByte(0x80 | byte(l)) if err != nil { return } - err = marshalInt64(out, int64(t.length)) + err = marshalLength(out, t.length) if err != nil { return } @@ -314,28 +336,28 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter return marshalObjectIdentifier(out, value.Interface().(ObjectIdentifier)) } - switch v := value.(type) { - case *reflect.BoolValue: - if v.Get() { + switch v := value; v.Kind() { + case reflect.Bool: + if v.Bool() { return out.WriteByte(255) } else { return out.WriteByte(0) } - case *reflect.IntValue: - return marshalInt64(out, int64(v.Get())) - case *reflect.StructValue: - t := v.Type().(*reflect.StructType) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return marshalInt64(out, int64(v.Int())) + case reflect.Struct: + t := v.Type() startingField := 0 // If the first element of the structure is a non-empty // RawContents, then we don't bother serialising the rest. if t.NumField() > 0 && t.Field(0).Type == rawContentsType { - s := v.Field(0).(*reflect.SliceValue) + s := v.Field(0) if s.Len() > 0 { bytes := make([]byte, s.Len()) for i := 0; i < s.Len(); i++ { - bytes[i] = uint8(s.Elem(i).(*reflect.UintValue).Get()) + bytes[i] = uint8(s.Index(i).Uint()) } /* The RawContents will contain the tag and * length fields but we'll also be writing @@ -357,12 +379,12 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter } } return - case *reflect.SliceValue: - sliceType := v.Type().(*reflect.SliceType) + case reflect.Slice: + sliceType := v.Type() if sliceType.Elem().Kind() == reflect.Uint8 { bytes := make([]byte, v.Len()) for i := 0; i < v.Len(); i++ { - bytes[i] = uint8(v.Elem(i).(*reflect.UintValue).Get()) + bytes[i] = uint8(v.Index(i).Uint()) } _, err = out.Write(bytes) return @@ -372,17 +394,17 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter for i := 0; i < v.Len(); i++ { var pre *forkableWriter pre, out = out.fork() - err = marshalField(pre, v.Elem(i), params) + err = marshalField(pre, v.Index(i), params) if err != nil { return } } return - case *reflect.StringValue: + case reflect.String: if params.stringType == tagIA5String { - return marshalIA5String(out, v.Get()) + return marshalIA5String(out, v.String()) } else { - return marshalPrintableString(out, v.Get()) + return marshalPrintableString(out, v.String()) } return } @@ -392,7 +414,7 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err os.Error) { // If the field is an interface{} then recurse into it. - if v, ok := v.(*reflect.InterfaceValue); ok && v.Type().(*reflect.InterfaceType).NumMethod() == 0 { + if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 { return marshalField(out, v.Elem(), params) } @@ -406,7 +428,7 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) return } - if params.optional && reflect.DeepEqual(v.Interface(), reflect.MakeZero(v.Type()).Interface()) { + if params.optional && reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) { return } @@ -471,7 +493,7 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) // Marshal returns the ASN.1 encoding of val. func Marshal(val interface{}) ([]byte, os.Error) { var out bytes.Buffer - v := reflect.NewValue(val) + v := reflect.ValueOf(val) f := newForkableWriter() err := marshalField(f, v, fieldParameters{}) if err != nil { diff --git a/libgo/go/asn1/marshal_test.go b/libgo/go/asn1/marshal_test.go index 85eafc9..cd165d2 100644 --- a/libgo/go/asn1/marshal_test.go +++ b/libgo/go/asn1/marshal_test.go @@ -77,6 +77,30 @@ var marshalTests = []marshalTest{ {ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"}, {ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"}, {"test", "130474657374"}, + { + "" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 127 times 'x' + "137f" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "78787878787878787878787878787878787878787878787878787878787878", + }, + { + "" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 128 times 'x' + "138180" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "7878787878787878787878787878787878787878787878787878787878787878" + + "7878787878787878787878787878787878787878787878787878787878787878", + }, {ia5StringTest{"test"}, "3006160474657374"}, {printableStringTest{"test"}, "3006130474657374"}, {printableStringTest{"test*"}, "30071305746573742a"}, |