Browse Source

codec: some overflow and 0-length container fixes, and cbor tests.

- fix overflow decoding int64 from uint64
- decode 0-length containers as 0-length(not as nil)
- cbor: treat undefined as nil
- create test to run against cbor test vectors (from https://github.com/cbor/test-vectors/)
Ugorji Nwoke 11 years ago
parent
commit
c476cf2bad
12 changed files with 596 additions and 84 deletions
  1. 19 13
      codec/binc.go
  2. 33 24
      codec/cbor.go
  3. 88 11
      codec/cbor_test.go
  4. 2 0
      codec/codecs_test.go
  5. 1 8
      codec/decode.go
  6. 4 0
      codec/ext_dep_test.go
  7. 384 0
      codec/fast-path.go
  8. 10 0
      codec/gen-fast-path.go
  9. 18 2
      codec/helper.go
  10. 9 4
      codec/msgpack.go
  11. 24 21
      codec/simple.go
  12. 4 1
      codec/test-cbor-goldens.json

+ 19 - 13
codec/binc.go

@@ -485,17 +485,14 @@ func (d *bincDecDriver) decUint() (v uint64) {
 	return
 }
 
-func (d *bincDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
+func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
 	switch d.vd {
 	case bincVdPosInt:
 		ui = d.decUint()
-		i = int64(ui)
 	case bincVdNegInt:
 		ui = d.decUint()
-		i = -(int64(ui))
 		neg = true
 	case bincVdSmallInt:
-		i = int64(d.vs) + 1
 		ui = uint64(d.vs) + 1
 	case bincVdSpecial:
 		switch d.vs {
@@ -504,7 +501,6 @@ func (d *bincDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
 		case bincSpNegOne:
 			neg = true
 			ui = 1
-			i = -1
 		default:
 			decErr("numeric decode fails for special value: d.vs: 0x%x", d.vs)
 		}
@@ -515,16 +511,21 @@ func (d *bincDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
 }
 
 func (d *bincDecDriver) decodeInt(bitsize uint8) (i int64) {
-	_, i, _ = d.decIntAny()
+	ui, neg := d.decCheckInteger()
+	if neg {
+		i = -checkOverflowUint64ToInt64(ui)
+	} else {
+		i = checkOverflowUint64ToInt64(ui)
+	}
 	checkOverflow(0, i, bitsize)
 	d.bdRead = false
 	return
 }
 
 func (d *bincDecDriver) decodeUint(bitsize uint8) (ui uint64) {
-	ui, i, neg := d.decIntAny()
+	ui, neg := d.decCheckInteger()
 	if neg {
-		decErr("Assigning negative signed value: %v, to unsigned type", i)
+		decErr("Assigning negative signed value to unsigned type")
 	}
 	checkOverflow(ui, 0, bitsize)
 	d.bdRead = false
@@ -550,8 +551,7 @@ func (d *bincDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
 	case bincVdFloat:
 		f = d.decFloat()
 	default:
-		_, i, _ := d.decIntAny()
-		f = float64(i)
+		f = float64(d.decodeInt(64))
 	}
 	checkOverflowFloat32(f, chkOverflow32)
 	d.bdRead = false
@@ -671,8 +671,12 @@ func (d *bincDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 		decErr("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x",
 			bincVdString, bincVdByteArray, d.vd)
 	}
-	if clen > 0 {
-		// if no contents in stream, don't update the passed byteslice
+	if clen >= 0 {
+		if bs == nil {
+			bs = []byte{}
+			bsOut = bs
+			changed = true
+		}
 		if len(bs) != clen {
 			if len(bs) > clen {
 				bs = bs[:clen]
@@ -682,7 +686,9 @@ func (d *bincDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 			bsOut = bs
 			changed = true
 		}
-		d.r.readb(bs)
+		if len(bs) > 0 {
+			d.r.readb(bs)
+		}
 	}
 	d.bdRead = false
 	return

+ 33 - 24
codec/cbor.go

@@ -229,7 +229,8 @@ func (d *cborDecDriver) currentEncodedType() valueType {
 }
 
 func (d *cborDecDriver) tryDecodeAsNil() bool {
-	if d.bd == cborBdNil {
+	// treat Nil and Undefined as nil values
+	if d.bd == cborBdNil || d.bd == cborBdUndefined {
 		d.bdRead = false
 		return true
 	}
@@ -260,41 +261,42 @@ func (d *cborDecDriver) decUint() (ui uint64) {
 		case 0x1b:
 			ui = uint64(d.r.readUint64())
 		default:
-			decErr("decIntAny: Invalid descriptor: %v", d.bd)
+			decErr("decUint: Invalid descriptor: %v", d.bd)
 		}
 	}
 	return
 }
 
-func (d *cborDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
+func (d *cborDecDriver) decCheckInteger() (neg bool) {
 	switch major := d.bd >> 5; major {
 	case cborMajorUint:
 	case cborMajorNegInt:
 		neg = true
 	default:
-		decErr("decIntAny: invalid major: %v (bd: %v)", major, d.bd)
-	}
-	ui = d.decUint()
-	if neg {
-		i = -int64(ui + 1)
-	} else {
-		i = int64(ui)
+		decErr("invalid major: %v (bd: %v)", major, d.bd)
 	}
 	return
 }
 
 func (d *cborDecDriver) decodeInt(bitsize uint8) (i int64) {
-	_, i, _ = d.decIntAny()
+	neg := d.decCheckInteger()
+	ui := d.decUint()
+	// check if this number can be converted to an int without overflow
+	if neg {
+		i = -checkOverflowUint64ToInt64(ui + 1)
+	} else {
+		i = checkOverflowUint64ToInt64(ui)
+	}
 	checkOverflow(0, i, bitsize)
 	d.bdRead = false
 	return
 }
 
 func (d *cborDecDriver) decodeUint(bitsize uint8) (ui uint64) {
-	ui, i, neg := d.decIntAny()
-	if neg {
-		decErr("Assigning negative signed value: %v, to unsigned type", i)
+	if d.decCheckInteger() {
+		decErr("Assigning negative signed value to unsigned type")
 	}
+	ui = d.decUint()
 	checkOverflow(ui, 0, bitsize)
 	d.bdRead = false
 	return
@@ -310,8 +312,7 @@ func (d *cborDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
 		f = math.Float64frombits(d.r.readUint64())
 	default:
 		if d.bd >= cborBaseUint && d.bd < cborBaseBytes {
-			_, i, _ := d.decIntAny()
-			f = float64(i)
+			f = float64(d.decodeInt(64))
 		} else {
 			decErr("Float only valid from float16/32/64: Invalid descriptor: %v", d.bd)
 		}
@@ -382,6 +383,10 @@ func (d *cborDecDriver) decodeString() (s string) {
 
 func (d *cborDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
+		if bs == nil {
+			bs = []byte{}
+			changed = true
+		}
 		bsOut = d.decIndefiniteBytes(bs[:0])
 		if len(bsOut) != len(bs) {
 			changed = true
@@ -389,8 +394,12 @@ func (d *cborDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 		return
 	}
 	clen := d.decLen()
-	if clen > 0 {
-		// if no contents in stream, don't update the passed byteslice
+	if clen >= 0 {
+		if bs == nil {
+			bs = []byte{}
+			bsOut = bs
+			changed = true
+		}
 		if len(bs) != clen {
 			if len(bs) > clen {
 				bs = bs[:clen]
@@ -400,7 +409,9 @@ func (d *cborDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 			bsOut = bs
 			changed = true
 		}
-		d.r.readb(bs)
+		if len(bs) > 0 {
+			d.r.readb(bs)
+		}
 	}
 	d.bdRead = false
 	return
@@ -458,18 +469,16 @@ func (d *cborDecDriver) decodeNaked(de *Decoder) (v interface{}, vt valueType, d
 	default:
 		switch {
 		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
-			ui, i, _ := d.decIntAny()
 			if d.h.SignedInteger {
 				vt = valueTypeInt
-				v = i
+				v = d.decodeInt(64)
 			} else {
 				vt = valueTypeUint
-				v = ui
+				v = d.decodeUint(64)
 			}
 		case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
 			vt = valueTypeInt
-			_, i, _ := d.decIntAny()
-			v = i
+			v = d.decodeInt(64)
 		case d.bd >= cborBaseBytes && d.bd < cborBaseString:
 			vt = valueTypeBytes
 			v, _ = d.decodeBytes(nil)

+ 88 - 11
codec/cbor_test.go

@@ -7,8 +7,11 @@ import (
 	"bytes"
 	"encoding/hex"
 	"encoding/json"
+	"math"
 	"os"
+	"regexp"
 	"strconv"
+	"strings"
 	"testing"
 )
 
@@ -86,15 +89,24 @@ func TestCborIndefiniteLength(t *testing.T) {
 }
 
 type testCborGolden struct {
-	Base64    string      `json:"cbor"`
-	Hex       string      `json:"hex"`
-	Roundtrip bool        `json:"roundtrip"`
-	Decoded   interface{} `json:"decoded"`
+	Base64     string      `json:"cbor"`
+	Hex        string      `json:"hex"`
+	Roundtrip  bool        `json:"roundtrip"`
+	Decoded    interface{} `json:"decoded"`
+	Diagnostic string      `json:"diagnostic"`
+	Skip       bool        `json:"skip"`
 }
 
-// __TestCborGoldens is disabled because it includes numbers outside the range of int64/uint64
+// Only run this within ext dep tests.
+// It skips some tests and requires private setup of deepEqual.
+// Some tests are skipped because they include numbers outside the range of int64/uint64
 // and it doesn't support diagnostic checking.
-func __TestCborGoldens(t *testing.T) {
+func doTestCborGoldens(t *testing.T) {
+	oldMapType := testCborH.MapType
+	defer func() {
+		testCborH.MapType = oldMapType
+	}()
+	testCborH.MapType = testMapStrIntfTyp
 	// decode test-cbor-goldens.json into a list of []*testCborGolden
 	// for each one,
 	// - decode hex into []byte bs
@@ -114,7 +126,35 @@ func __TestCborGoldens(t *testing.T) {
 		logT(t, "error json decoding test-cbor-goldens.json: %v", err)
 		failT(t)
 	}
+
+	tagregex := regexp.MustCompile(`[\d]+\(.+?\)`)
+	hexregex := regexp.MustCompile(`h'([0-9a-fA-F]*)'`)
 	for i, g := range gs {
+		// fmt.Printf("%v, skip: %v, isTag: %v, %s\n", i, g.Skip, tagregex.MatchString(g.Diagnostic), g.Diagnostic)
+		// skip tags or simple or those with prefix, as we can't verify them.
+		if g.Skip || strings.HasPrefix(g.Diagnostic, "simple(") || tagregex.MatchString(g.Diagnostic) {
+			// fmt.Printf("%v: skipped\n", i)
+			continue
+		}
+		// println(i, "g.Diagnostic", g.Diagnostic)
+		if hexregex.MatchString(g.Diagnostic) {
+			// println(i, "g.Diagnostic matched hex")
+			if s2 := g.Diagnostic[2 : len(g.Diagnostic)-1]; s2 == "" {
+				g.Decoded = []byte{}
+			} else if bs2, err2 := hex.DecodeString(s2); err2 == nil {
+				g.Decoded = bs2
+			}
+			// fmt.Printf("%v: hex: %v\n", i, g.Decoded)
+		}
+		// if g.Diagnostic != "" {
+		// 	if strings.HasPrefix(g.Diagnostic, "simple(") {
+		// 		continue
+		// 	}
+		// 	// if regex matches num(stuff), then it is a tag and ignore it ...
+		// 	if tagregex.MatchString(g.Diagnostic) {
+		// 		continue
+		// 	}
+		// }
 		bs, err := hex.DecodeString(g.Hex)
 		if err != nil {
 			logT(t, "[%v] error hex decoding %s [%v]: %v", i, g.Hex, err)
@@ -168,11 +208,48 @@ func __TestCborGoldens(t *testing.T) {
 				continue
 			}
 		}
-		if err = deepEqual(g.Decoded, v); err != nil {
-			logT(t, "[%v] deepEqual error: %v", i, err)
-			logT(t, "    ....... GOLDEN:  (%T) %#v", g.Decoded, g.Decoded)
-			logT(t, "    ....... DECODED: (%T) %#v", v, v)
-			failT(t)
+		// check the diagnostics to compare
+		switch g.Diagnostic {
+		case "Infinity":
+			b := math.IsInf(v.(float64), 1)
+			testCborError(t, i, math.Inf(1), v, nil, &b)
+		case "-Infinity":
+			b := math.IsInf(v.(float64), -1)
+			testCborError(t, i, math.Inf(-1), v, nil, &b)
+		case "NaN":
+			// println(i, "checking NaN")
+			b := math.IsNaN(v.(float64))
+			testCborError(t, i, math.NaN(), v, nil, &b)
+		case "undefined":
+			b := v == nil
+			testCborError(t, i, nil, v, nil, &b)
+		default:
+			testCborError(t, i, g.Decoded, v, deepEqual(g.Decoded, v), nil)
+			// if false { // if match simple(number)
+			// } else if false { // if match h'XYZ'
+			// } else { // check deepequal
+			// 	testCborError(t, i, g.Decoded, v, deepEqual(g.Decoded, v), nil)
+			// }
 		}
 	}
 }
+
+func testCborError(t *testing.T, i int, v0, v1 interface{}, err error, equal *bool) {
+	if err == nil && equal == nil {
+		// fmt.Printf("%v testCborError passed (err and equal nil)\n", i)
+		return
+	}
+	if err != nil {
+		logT(t, "[%v] deepEqual error: %v", i, err)
+		logT(t, "    ....... GOLDEN:  (%T) %#v", v0, v0)
+		logT(t, "    ....... DECODED: (%T) %#v", v1, v1)
+		failT(t)
+	}
+	if equal != nil && !*equal {
+		logT(t, "[%v] values not equal", i)
+		logT(t, "    ....... GOLDEN:  (%T) %#v", v0, v0)
+		logT(t, "    ....... DECODED: (%T) %#v", v1, v1)
+		failT(t)
+	}
+	// fmt.Printf("%v testCborError passed (checks passed)\n", i)
+}

+ 2 - 0
codec/codecs_test.go

@@ -172,6 +172,8 @@ func (x testCborTimeExt) UpdateExt(rv reflect.Value, v interface{}) {
 		tt = time.Unix(0, v2).UTC()
 	case uint64:
 		tt = time.Unix(0, int64(v2)).UTC()
+	//case float64:
+	//case string:
 	default:
 		panic(fmt.Sprintf("unsupported format for time conversion: expecting int64/uint64; got %T", v))
 	}

+ 1 - 8
codec/decode.go

@@ -450,7 +450,6 @@ func (f *decFnInfo) kSlice(rv reflect.Value) {
 	containerLen, containerLenS := decContLens(f.dd, currEncodedType)
 
 	// an array can never return a nil slice. so no need to check f.array here.
-
 	if rv.IsNil() {
 		if containerLenS < 0 {
 			rv.Set(reflect.MakeSlice(f.ti.rt, 0, 0))
@@ -460,6 +459,7 @@ func (f *decFnInfo) kSlice(rv reflect.Value) {
 	}
 
 	if containerLen == 0 {
+		rv.SetLen(0)
 		return
 	}
 
@@ -922,13 +922,6 @@ func decContLens(dd decDriver, currEncodedType valueType) (containerLen, contain
 	return
 }
 
-// func decToInt64(ui uint64) int64 {
-// 	if ui2 := ui & 0x7fffffffffffffff; ui2 > math.MaxInt64 {
-// 		decErr("uint64 value greater than max int64; got %v", ui2)
-// 	}
-// 	return int64(ui)
-// }
-
 func decErr(format string, params ...interface{}) {
 	doPanic(msgTagDec, format, params...)
 }

+ 4 - 0
codec/ext_dep_test.go

@@ -70,6 +70,10 @@ func TestCborPythonGenStreams(t *testing.T) {
 	doTestPythonGenStreams(t, "cbor", testCborH)
 }
 
+func TestCborGoldens(t *testing.T) {
+	doTestCborGoldens(t)
+}
+
 func TestMsgpackRpcSpecGoClientToPythonSvc(t *testing.T) {
 	doTestMsgpackRpcSpecGoClientToPythonSvc(t)
 }

File diff suppressed because it is too large
+ 384 - 0
codec/fast-path.go


+ 10 - 0
codec/gen-fast-path.go

@@ -136,6 +136,12 @@ func (f *decFnInfo) {{ .MethodName false }}(rv reflect.Value) {
 
 	_, containerLenS := decContLens(f.dd, vtype)
 	if containerLenS == 0 {
+		if v == nil {
+			v = []{{ .Elem }}{}
+		} else {
+			v = v[:0]
+		}
+		*vp = v
 		return
 	}
 	if v == nil {
@@ -202,6 +208,10 @@ func (f *decFnInfo) {{ .MethodName false }}(rv reflect.Value) {
 
 	containerLen := f.dd.readMapLen()
 	if containerLen == 0 {
+		if v == nil {
+			v = map[{{ .MapKey }}]{{ .Elem }}{}
+			*vp = v
+		}
 		return
 	}
 	if xaddr && v == nil {

+ 18 - 2
codec/helper.go

@@ -150,7 +150,7 @@ type Handle interface {
 }
 
 // RawExt represents raw unprocessed extension data.
-// Some codecs will decode extension data as a RawExt if there is no registered extension for the tag.
+// Some codecs will decode extension data as a *RawExt if there is no registered extension for the tag.
 //
 // Only one of Data or Value is nil. If Data is nil, then the content of the RawExt is in the Value.
 type RawExt struct {
@@ -546,7 +546,7 @@ func checkOverflowFloat32(f float64, doCheck bool) {
 
 func checkOverflow(ui uint64, i int64, bitsize uint8) {
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
-	if bitsize == 0 {
+	if bitsize == 0 || bitsize >= 64 {
 		return
 	}
 	if i != 0 {
@@ -560,3 +560,19 @@ func checkOverflow(ui uint64, i int64, bitsize uint8) {
 		}
 	}
 }
+
+func checkOverflowUint64ToInt64(ui uint64) int64 {
+	//e.g. -127 to 128 for int8
+	pos := (ui >> 63) == 0
+	ui2 := ui & 0x7fffffffffffffff
+	if pos {
+		if ui2 > math.MaxInt64 {
+			decErr("uint64 value greater than max int64; got %v", ui2)
+		}
+	} else {
+		if ui2 > math.MaxInt64-1 {
+			decErr("uint64 value less than min int64; got %v", ui2)
+		}
+	}
+	return int64(ui)
+}

+ 9 - 4
codec/msgpack.go

@@ -527,10 +527,13 @@ func (d *msgpackDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 	// 	changed = true
 	// 	panic("length cannot be zero. this cannot be nil.")
 	// }
-	if clen > 0 {
-		// if no contents in stream, don't update the passed byteslice
+	if clen >= 0 {
+		if bs == nil {
+			bs = []byte{}
+			bsOut = bs
+			changed = true
+		}
 		if len(bs) != clen {
-			// Return changed=true if length of passed slice diff from length of bytes in stream
 			if len(bs) > clen {
 				bs = bs[:clen]
 			} else {
@@ -539,7 +542,9 @@ func (d *msgpackDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 			bsOut = bs
 			changed = true
 		}
-		d.r.readb(bs)
+		if len(bs) > 0 {
+			d.r.readb(bs)
+		}
 	}
 	d.bdRead = false
 	return

+ 24 - 21
codec/simple.go

@@ -210,35 +210,29 @@ func (d *simpleDecDriver) tryDecodeAsNil() bool {
 	return false
 }
 
-func (d *simpleDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
+// 		i = int64(ui)
+
+func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
 	switch d.bd {
 	case simpleVdPosInt:
 		ui = uint64(d.r.readn1())
-		i = int64(ui)
 	case simpleVdPosInt + 1:
 		ui = uint64(d.r.readUint16())
-		i = int64(ui)
 	case simpleVdPosInt + 2:
 		ui = uint64(d.r.readUint32())
-		i = int64(ui)
 	case simpleVdPosInt + 3:
 		ui = uint64(d.r.readUint64())
-		i = int64(ui)
 	case simpleVdNegInt:
 		ui = uint64(d.r.readn1())
-		i = -(int64(ui))
 		neg = true
 	case simpleVdNegInt + 1:
 		ui = uint64(d.r.readUint16())
-		i = -(int64(ui))
 		neg = true
 	case simpleVdNegInt + 2:
 		ui = uint64(d.r.readUint32())
-		i = -(int64(ui))
 		neg = true
 	case simpleVdNegInt + 3:
 		ui = uint64(d.r.readUint64())
-		i = -(int64(ui))
 		neg = true
 	default:
 		decErr("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
@@ -251,16 +245,21 @@ func (d *simpleDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
 }
 
 func (d *simpleDecDriver) decodeInt(bitsize uint8) (i int64) {
-	_, i, _ = d.decIntAny()
+	ui, neg := d.decCheckInteger()
+	if neg {
+		i = -checkOverflowUint64ToInt64(ui)
+	} else {
+		i = checkOverflowUint64ToInt64(ui)
+	}
 	checkOverflow(0, i, bitsize)
 	d.bdRead = false
 	return
 }
 
 func (d *simpleDecDriver) decodeUint(bitsize uint8) (ui uint64) {
-	ui, i, neg := d.decIntAny()
+	ui, neg := d.decCheckInteger()
 	if neg {
-		decErr("Assigning negative signed value: %v, to unsigned type", i)
+		decErr("Assigning negative signed value to unsigned type")
 	}
 	checkOverflow(ui, 0, bitsize)
 	d.bdRead = false
@@ -275,8 +274,7 @@ func (d *simpleDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
 		f = math.Float64frombits(d.r.readUint64())
 	default:
 		if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
-			_, i, _ := d.decIntAny()
-			f = float64(i)
+			f = float64(d.decodeInt(64))
 		} else {
 			decErr("Float only valid from float32/64: Invalid descriptor: %v", d.bd)
 		}
@@ -337,9 +335,14 @@ func (d *simpleDecDriver) decodeString() (s string) {
 }
 
 func (d *simpleDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
-	if clen := d.decLen(); clen > 0 {
+	if clen := d.decLen(); clen >= 0 {
 		// if no contents in stream, don't update the passed byteslice
 		if len(bs) != clen {
+			if bs == nil {
+				bs = []byte{}
+				bsOut = bs
+				changed = true
+			}
 			if len(bs) > clen {
 				bs = bs[:clen]
 			} else {
@@ -348,7 +351,9 @@ func (d *simpleDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 			bsOut = bs
 			changed = true
 		}
-		d.r.readb(bs)
+		if len(bs) > 0 {
+			d.r.readb(bs)
+		}
 	}
 	d.bdRead = false
 	return
@@ -401,18 +406,16 @@ func (d *simpleDecDriver) decodeNaked(_ *Decoder) (v interface{}, vt valueType,
 		vt = valueTypeBool
 		v = true
 	case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
-		ui, i, _ := d.decIntAny()
 		if d.h.SignedInteger {
 			vt = valueTypeInt
-			v = i
+			v = d.decodeInt(64)
 		} else {
 			vt = valueTypeUint
-			v = ui
+			v = d.decodeUint(64)
 		}
 	case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
 		vt = valueTypeInt
-		_, i, _ := d.decIntAny()
-		v = i
+		v = d.decodeInt(64)
 	case simpleVdFloat32:
 		vt = valueTypeFloat
 		v = d.decodeFloat(true)

+ 4 - 1
codec/test-cbor-goldens.json

@@ -75,7 +75,8 @@
     "cbor": "O///////////",
     "hex": "3bffffffffffffffff",
     "roundtrip": true,
-    "decoded": -18446744073709551616
+    "decoded": -18446744073709551616,
+    "skip": true
   },
   {
     "cbor": "w0kBAAAAAAAAAAA=",
@@ -448,6 +449,7 @@
     "cbor": "ogECAwQ=",
     "hex": "a201020304",
     "roundtrip": true,
+    "skip": true,
     "diagnostic": "{1: 2, 3: 4}"
   },
   {
@@ -489,6 +491,7 @@
     "cbor": "X0IBAkMDBAX/",
     "hex": "5f42010243030405ff",
     "roundtrip": false,
+    "skip": true,
     "diagnostic": "(_ h'0102', h'030405')"
   },
   {

Some files were not shown because too many files changed in this diff