]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/asn1: return error instead of dereferencing nil *big.Int in marshaling
authorHiroshi Ioka <hirochachacha@gmail.com>
Sun, 16 Oct 2016 05:31:18 +0000 (14:31 +0900)
committerAdam Langley <agl@golang.org>
Mon, 17 Oct 2016 22:29:32 +0000 (22:29 +0000)
Fixes #17461

Change-Id: I9954f6ae46c7e15560d7460841be8f2bc37233a9
Reviewed-on: https://go-review.googlesource.com/31121
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/encoding/asn1/asn1_test.go
src/encoding/asn1/marshal.go
src/encoding/asn1/marshal_test.go

index 81f4dba8c290cd2e641166a83d13c0717efea15d..8ee46d4565300901d7d7f8092fb89897a960f4b4 100644 (file)
@@ -132,7 +132,11 @@ func TestParseBigInt(t *testing.T) {
                        if ret.String() != test.base10 {
                                t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
                        }
-                       e := makeBigInt(ret)
+                       e, err := makeBigInt(ret)
+                       if err != nil {
+                               t.Errorf("%d: err=%q", i, err)
+                               continue
+                       }
                        result := make([]byte, e.Len())
                        e.Encode(result)
                        if !bytes.Equal(result, test.in) {
index f0664d3d46b1eb9a9af06bb1e0636d6e225d9f67..444c7f364209ba397a4b5204b78b2baf7a3c652d 100644 (file)
@@ -150,7 +150,11 @@ func appendBase128Int(dst []byte, n int64) []byte {
        return dst
 }
 
-func makeBigInt(n *big.Int) encoder {
+func makeBigInt(n *big.Int) (encoder, error) {
+       if n == nil {
+               return nil, StructuralError{"empty integer"}
+       }
+
        if n.Sign() < 0 {
                // A negative number has to be converted to two's-complement
                // form. So we'll invert and subtract 1. If the
@@ -163,20 +167,20 @@ func makeBigInt(n *big.Int) encoder {
                        bytes[i] ^= 0xff
                }
                if len(bytes) == 0 || bytes[0]&0x80 == 0 {
-                       return multiEncoder([]encoder{byteFFEncoder, bytesEncoder(bytes)})
+                       return multiEncoder([]encoder{byteFFEncoder, bytesEncoder(bytes)}), nil
                }
-               return bytesEncoder(bytes)
+               return bytesEncoder(bytes), nil
        } else if n.Sign() == 0 {
                // Zero is written as a single 0 zero rather than no bytes.
-               return byte00Encoder
+               return byte00Encoder, nil
        } else {
                bytes := n.Bytes()
                if len(bytes) > 0 && bytes[0]&0x80 != 0 {
                        // We'll have to pad this with 0x00 in order to stop it
                        // looking like a negative number.
-                       return multiEncoder([]encoder{byte00Encoder, bytesEncoder(bytes)})
+                       return multiEncoder([]encoder{byte00Encoder, bytesEncoder(bytes)}), nil
                }
-               return bytesEncoder(bytes)
+               return bytesEncoder(bytes), nil
        }
 }
 
@@ -409,7 +413,7 @@ func makeBody(value reflect.Value, params fieldParameters) (e encoder, err error
        case objectIdentifierType:
                return makeObjectIdentifier(value.Interface().(ObjectIdentifier))
        case bigIntType:
-               return makeBigInt(value.Interface().(*big.Int)), nil
+               return makeBigInt(value.Interface().(*big.Int))
        }
 
        switch v := value; v.Kind() {
index 6af770fcc3424e67c72c1e6f76026dd2a7083d7f..10db1aa575afea00dee83128de81e9077e40d376 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "encoding/hex"
        "math/big"
+       "strings"
        "testing"
        "time"
 )
@@ -167,6 +168,29 @@ func TestMarshal(t *testing.T) {
        }
 }
 
+type marshalErrTest struct {
+       in  interface{}
+       err string
+}
+
+var marshalErrTests = []marshalErrTest{
+       {bigIntStruct{nil}, "empty integer"},
+}
+
+func TestMarshalError(t *testing.T) {
+       for i, test := range marshalErrTests {
+               _, err := Marshal(test.in)
+               if err == nil {
+                       t.Errorf("#%d should fail, but success", i)
+                       continue
+               }
+
+               if !strings.Contains(err.Error(), test.err) {
+                       t.Errorf("#%d got: %v want %v", i, err, test.err)
+               }
+       }
+}
+
 func TestInvalidUTF8(t *testing.T) {
        _, err := Marshal(string([]byte{0xff, 0xff}))
        if err == nil {