Commit 6b4828a2 authored by Constantin Konstantinidis's avatar Constantin Konstantinidis Committed by Filippo Valsorda

encoding/asn1: fix returned type for an Object Identifier

Unmarshal/Marshal/Unmarshal was not idempotent as the Object Identifier
type was not returned through the interface. The limit case OID = 0
returns an error. The zero OID is 0.0

A test is fixed to use the Object Identifier type.
Other related test are added.

Fixes #11130

Change-Id: I15483a3126066c9b99cf5bd9c4b0cc15ec1d61ca
Reviewed-on: https://go-review.googlesource.com/113837
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarFilippo Valsorda <filippo@golang.org>
parent c4f9fa1f
...@@ -250,7 +250,7 @@ func (oi ObjectIdentifier) String() string { ...@@ -250,7 +250,7 @@ func (oi ObjectIdentifier) String() string {
// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
// returns it. An object identifier is a sequence of variable length integers // returns it. An object identifier is a sequence of variable length integers
// that are assigned in a hierarchy. // that are assigned in a hierarchy.
func parseObjectIdentifier(bytes []byte) (s []int, err error) { func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) {
if len(bytes) == 0 { if len(bytes) == 0 {
err = SyntaxError{"zero length OBJECT IDENTIFIER"} err = SyntaxError{"zero length OBJECT IDENTIFIER"}
return return
......
...@@ -227,7 +227,7 @@ func TestBitStringRightAlign(t *testing.T) { ...@@ -227,7 +227,7 @@ func TestBitStringRightAlign(t *testing.T) {
type objectIdentifierTest struct { type objectIdentifierTest struct {
in []byte in []byte
ok bool ok bool
out []int out ObjectIdentifier // has base type[]int
} }
var objectIdentifierTestData = []objectIdentifierTest{ var objectIdentifierTestData = []objectIdentifierTest{
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"strings" "strings"
"testing" "testing"
"time" "time"
"reflect"
) )
type intStruct struct { type intStruct struct {
...@@ -253,6 +254,62 @@ func TestInvalidUTF8(t *testing.T) { ...@@ -253,6 +254,62 @@ func TestInvalidUTF8(t *testing.T) {
} }
} }
func TestMarshalOID(t *testing.T) {
var marshalTestsOID = []marshalTest{
{[]byte("\x06\x01\x30"), "0403060130"}, // bytes format returns a byte sequence \x04
// {ObjectIdentifier([]int{0}), "060100"}, // returns an error as OID 0.0 has the same encoding
{[]byte("\x06\x010"), "0403060130"}, // same as above "\x06\x010" = "\x06\x01" + "0"
{ObjectIdentifier([]int{2,999,3}), "0603883703"}, // Example of ITU-T X.690
{ObjectIdentifier([]int{0,0}), "060100"}, // zero OID
}
for i, test := range marshalTestsOID {
data, err := Marshal(test.in)
if err != nil {
t.Errorf("#%d failed: %s", i, err)
}
out, _ := hex.DecodeString(test.out)
if !bytes.Equal(out, data) {
t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out)
}
}
}
func TestIssue11130(t *testing.T) {
data := []byte("\x06\x010") // == \x06\x01\x30 == OID = 0 (the figure)
var v interface{}
// v has Zero value here and Elem() would panic
_, err := Unmarshal(data, &v)
if err != nil {
t.Errorf("%v", err)
return
}
if reflect.TypeOf(v).String() != reflect.TypeOf(ObjectIdentifier{}).String() {
t.Errorf("marshal OID returned an invalid type")
return
}
data1, err := Marshal(v)
if err != nil {
t.Errorf("%v", err)
return
}
if !bytes.Equal(data,data1) {
t.Errorf("got: %q, want: %q \n", data1, data)
return
}
var v1 interface{}
_, err = Unmarshal(data1, &v1)
if err != nil {
t.Errorf("%v", err)
return
}
if !reflect.DeepEqual(v, v1) {
t.Errorf("got: %#v data=%q , want : %#v data=%q\n ", v1, data1, v, data)
}
}
func BenchmarkMarshal(b *testing.B) { func BenchmarkMarshal(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment