// everything by any means.
import (
+ "errors"
"fmt"
"math/big"
"reflect"
// don't distinguish between ordered and unordered objects in this code.
func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
offset = initOffset
+ // parseTagAndLength should not be called without at least a single
+ // byte to read. Thus this check is for robustness:
+ if offset >= len(bytes) {
+ err = errors.New("asn1: internal error in parseTagAndLength")
+ return
+ }
b := bytes[offset]
offset++
ret.class = int(b >> 6)
if params.application {
expectedClass = classApplication
}
+ if offset == len(bytes) {
+ err = StructuralError{"explicit tag has no child"}
+ return
+ }
if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
if t.length > 0 {
t, offset, err = parseTagAndLength(bytes, offset)
t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
}
}
+
+type truncatedExplicitTagTest struct {
+ Test int `asn1:"explicit,tag:0"`
+}
+
+func TestTruncatedExplicitTag(t *testing.T) {
+ // This crashed Unmarshal in the past. See #11154.
+ der := []byte{
+ 0x30, // SEQUENCE
+ 0x02, // two bytes long
+ 0xa0, // context-specific, tag 0
+ 0x30, // 48 bytes long
+ }
+
+ var result truncatedExplicitTagTest
+ if _, err := Unmarshal(der, &result); err == nil {
+ t.Error("Unmarshal returned without error")
+ }
+}