From 3fc76766602b71c68955a7e96fb3615403aacc16 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Fri, 16 Dec 2016 09:52:28 +0100 Subject: [PATCH 1/4] Add logging to test cases --- asn1_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asn1_test.go b/asn1_test.go index eebb0a9..f8af6f5 100644 --- a/asn1_test.go +++ b/asn1_test.go @@ -4,6 +4,7 @@ import ( "math/big" "reflect" "testing" + "fmt" ) // isBytesEqual compares two byte arrays/slices. @@ -26,9 +27,14 @@ type testCase struct { expected []byte } +func (t testCase) String() string { + return fmt.Sprintf("testCase: value %#v (%T) expects %#v", t.value, t.value, t.expected) +} + // testEncode encodes an object and compares with the expected bytes. func testEncode(t *testing.T, ctx *Context, options string, tests ...testCase) { for _, test := range tests { + t.Logf("Testing case: %v", test) data, err := ctx.EncodeWithOptions(test.value, options) if err != nil { t.Fatal(err) From ba7f356913242e692f7e4b5c5399919374d73b8b Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Fri, 16 Dec 2016 09:52:51 +0100 Subject: [PATCH 2/4] Fix encoding of interfaces that are pointers Currently fails for *big.Int --- encode.go | 5 +---- types.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/encode.go b/encode.go index 964441d..5a88cb6 100644 --- a/encode.go +++ b/encode.go @@ -37,10 +37,7 @@ func (ctx *Context) EncodeWithOptions(obj interface{}, options string) (data []b func (ctx *Context) encode(value reflect.Value, opts *fieldOptions) (*rawValue, error) { // Skip the interface type - switch value.Kind() { - case reflect.Interface: - value = value.Elem() - } + value = getActualType(value) // If a value is missing the default value is used empty := isEmpty(value) diff --git a/types.go b/types.go index 8e54ab5..799d40f 100644 --- a/types.go +++ b/types.go @@ -347,6 +347,18 @@ func (ctx *Context) decodeNull(data []byte, value reflect.Value) error { * Helper functions */ +// getActualType recursively gets the underlying type of Interfaces and Pointers. +func getActualType(value reflect.Value) reflect.Value { + for { + switch value.Kind() { + case reflect.Ptr, reflect.Interface: + value = value.Elem() + default: + return value + } + } +} + func checkInt(ctx *Context, data []byte) error { if ctx.der.decoding { if len(data) >= 2 { From 6c846cf57fb9e29a006efbac0285a6623adef7fa Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Fri, 16 Dec 2016 10:12:59 +0100 Subject: [PATCH 3/4] Don't get underlying value for *big.Int --- types.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types.go b/types.go index 799d40f..7aec372 100644 --- a/types.go +++ b/types.go @@ -350,8 +350,11 @@ func (ctx *Context) decodeNull(data []byte, value reflect.Value) error { // getActualType recursively gets the underlying type of Interfaces and Pointers. func getActualType(value reflect.Value) reflect.Value { for { + if value.Type() == bigIntType { + return value + } switch value.Kind() { - case reflect.Ptr, reflect.Interface: + case reflect.Interface, reflect.Ptr: value = value.Elem() default: return value From cb307609138a45d094a95345652e8a176698adc3 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Fri, 16 Dec 2016 10:20:45 +0100 Subject: [PATCH 4/4] Add test case for a pointer interface --- asn1_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/asn1_test.go b/asn1_test.go index f8af6f5..b54d1b1 100644 --- a/asn1_test.go +++ b/asn1_test.go @@ -676,3 +676,30 @@ func TestArraySlice(t *testing.T) { ctx := NewContext() testEncodeDecode(t, ctx, "", testCases...) } + +func TestPointerInterface(t *testing.T) { + type I interface {} + type Type struct { + A int + B string + C bool + } + var obj I + obj = &Type{1, "abc", true} + ctx := NewContext() + // We cannot use testSimple because the type is I + data, err := ctx.Encode(obj) + if err != nil { + t.Fatal(err) + } + value := new(Type) + rest, err := ctx.Decode(data, value) + if err != nil { + t.Fatal(err) + } + if len(rest) > 0 { + t.Fatalf("Unexpected remaining bytes when decoding \"%v\": %#v\n", + obj, rest) + } + checkEqual(t, obj, value) +}