diff --git a/CHANGELOG.md b/CHANGELOG.md index 628a15aeb2..41cb224721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## HEAD +* Fix `tls.Unmarshal` decoding a `Uint24` field from the start of the buffer instead of the field's offset by @robstradling * Switch Ed25519 import from deprecated `golang.org/x/crypto/ed25519` to stdlib `crypto/ed25519` by @JasonPowr * Added `--emit_proxy_headers` flag to ctfe by @mhutchinson diff --git a/tls/tls.go b/tls/tls.go index a48c998f48..dd7356ab29 100644 --- a/tls/tls.go +++ b/tls/tls.go @@ -336,7 +336,7 @@ func parseField(v reflect.Value, data []byte, initOffset int, info *fieldInfo) ( if len(rest) < 3 { return offset, syntaxError{info.fieldName(), "truncated uint24"} } - v.SetUint(uint64(data[0])<<16 | uint64(data[1])<<8 | uint64(data[2])) + v.SetUint(uint64(rest[0])<<16 | uint64(rest[1])<<8 | uint64(rest[2])) offset += 3 return offset, nil case uint32Type: diff --git a/tls/tls_test.go b/tls/tls_test.go index fd20874421..9215e10c63 100644 --- a/tls/tls_test.go +++ b/tls/tls_test.go @@ -68,6 +68,11 @@ type testSliceOfSlices struct { Inners []testInnerType `tls:"minlen:0,maxlen:65535"` } +type testUint24AtOffset struct { + Prefix uint16 + Val Uint24 +} + func TestMarshalUnmarshalRoundTrip(t *testing.T) { thing := testStruct{Data: []byte{0x01, 0x02, 0x03}, IntVal: 42, Other: [4]byte{1, 2, 3, 4}, Enum: 17} data, err := Marshal(thing) @@ -187,6 +192,7 @@ func TestUnmarshalMarshalWithParamsRoundTrip(t *testing.T) { // Note that maxval is just used to give enum size; it's not policed {"20", "maxval:18", newEnum(32)}, {"020a0b", "minlen:1,maxlen:5", &[]byte{0xa, 0xb}}, + {"0a0b010203", "", &testUint24AtOffset{Prefix: 0x0a0b, Val: 0x010203}}, {"020a0b0101010203040011", "", &testStruct{Data: []byte{0xa, 0xb}, IntVal: 0x101, Other: [4]byte{1, 2, 3, 4}, Enum: 17}}, {"000102", "", &testVariant{Which: 0, Val16: newUint16(0x0102)}}, {"0101020304", "", &testVariant{Which: 1, Val32: newUint32(0x01020304)}},