src/encoding/gob/decode.go GO 1,319 lines View on github.com → Search inside
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45//go:generate go run decgen.go -output dec_helpers.go67package gob89import (10	"encoding"11	"errors"12	"internal/saferio"13	"io"14	"math"15	"math/bits"16	"reflect"17)1819var (20	errBadUint = errors.New("gob: encoded unsigned integer out of range")21	errBadType = errors.New("gob: unknown type id or corrupted data")22	errRange   = errors.New("gob: bad data: field numbers out of bounds")23)2425type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool2627// decoderState is the execution state of an instance of the decoder. A new state28// is created for nested objects.29type decoderState struct {30	dec *Decoder31	// The buffer is stored with an extra indirection because it may be replaced32	// if we load a type during decode (when reading an interface value).33	b        *decBuffer34	fieldnum int           // the last field number read.35	next     *decoderState // for free list36}3738// decBuffer is an extremely simple, fast implementation of a read-only byte buffer.39// It is initialized by calling Size and then copying the data into the slice returned by Bytes().40type decBuffer struct {41	data   []byte42	offset int // Read offset.43}4445func (d *decBuffer) Read(p []byte) (int, error) {46	n := copy(p, d.data[d.offset:])47	if n == 0 && len(p) != 0 {48		return 0, io.EOF49	}50	d.offset += n51	return n, nil52}5354func (d *decBuffer) Drop(n int) {55	if n > d.Len() {56		panic("drop")57	}58	d.offset += n59}6061func (d *decBuffer) ReadByte() (byte, error) {62	if d.offset >= len(d.data) {63		return 0, io.EOF64	}65	c := d.data[d.offset]66	d.offset++67	return c, nil68}6970func (d *decBuffer) Len() int {71	return len(d.data) - d.offset72}7374func (d *decBuffer) Bytes() []byte {75	return d.data[d.offset:]76}7778// SetBytes sets the buffer to the bytes, discarding any existing data.79func (d *decBuffer) SetBytes(data []byte) {80	d.data = data81	d.offset = 082}8384func (d *decBuffer) Reset() {85	d.data = d.data[0:0]86	d.offset = 087}8889// We pass the bytes.Buffer separately for easier testing of the infrastructure90// without requiring a full Decoder.91func (dec *Decoder) newDecoderState(buf *decBuffer) *decoderState {92	d := dec.freeList93	if d == nil {94		d = new(decoderState)95		d.dec = dec96	} else {97		dec.freeList = d.next98	}99	d.b = buf100	return d101}102103func (dec *Decoder) freeDecoderState(d *decoderState) {104	d.next = dec.freeList105	dec.freeList = d106}107108func overflow(name string) error {109	return errors.New(`value for "` + name + `" out of range`)110}111112// decodeUintReader reads an encoded unsigned integer from an io.Reader.113// Used only by the Decoder to read the message length.114func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) {115	width = 1116	n, err := io.ReadFull(r, buf[0:width])117	if n == 0 {118		return119	}120	b := buf[0]121	if b <= 0x7f {122		return uint64(b), width, nil123	}124	n = -int(int8(b))125	if n > uint64Size {126		err = errBadUint127		return128	}129	width, err = io.ReadFull(r, buf[0:n])130	if err != nil {131		if err == io.EOF {132			err = io.ErrUnexpectedEOF133		}134		return135	}136	// Could check that the high byte is zero but it's not worth it.137	for _, b := range buf[0:width] {138		x = x<<8 | uint64(b)139	}140	width++ // +1 for length byte141	return142}143144// decodeUint reads an encoded unsigned integer from state.r.145// Does not check for overflow.146func (state *decoderState) decodeUint() (x uint64) {147	b, err := state.b.ReadByte()148	if err != nil {149		error_(err)150	}151	if b <= 0x7f {152		return uint64(b)153	}154	n := -int(int8(b))155	if n > uint64Size {156		error_(errBadUint)157	}158	buf := state.b.Bytes()159	if len(buf) < n {160		errorf("invalid uint data length %d: exceeds input size %d", n, len(buf))161	}162	// Don't need to check error; it's safe to loop regardless.163	// Could check that the high byte is zero but it's not worth it.164	for _, b := range buf[0:n] {165		x = x<<8 | uint64(b)166	}167	state.b.Drop(n)168	return x169}170171// decodeInt reads an encoded signed integer from state.r.172// Does not check for overflow.173func (state *decoderState) decodeInt() int64 {174	x := state.decodeUint()175	if x&1 != 0 {176		return ^int64(x >> 1)177	}178	return int64(x >> 1)179}180181// getLength decodes the next uint and makes sure it is a possible182// size for a data item that follows, which means it must fit in a183// non-negative int and fit in the buffer.184func (state *decoderState) getLength() (int, bool) {185	n := int(state.decodeUint())186	if n < 0 || state.b.Len() < n || tooBig <= n {187		return 0, false188	}189	return n, true190}191192// decOp is the signature of a decoding operator for a given type.193type decOp func(i *decInstr, state *decoderState, v reflect.Value)194195// The 'instructions' of the decoding machine196type decInstr struct {197	op    decOp198	field int   // field number of the wire type199	index []int // field access indices for destination type200	ovfl  error // error message for overflow/underflow (for arrays, of the elements)201}202203// ignoreUint discards a uint value with no destination.204func ignoreUint(i *decInstr, state *decoderState, v reflect.Value) {205	state.decodeUint()206}207208// ignoreTwoUints discards a uint value with no destination. It's used to skip209// complex values.210func ignoreTwoUints(i *decInstr, state *decoderState, v reflect.Value) {211	state.decodeUint()212	state.decodeUint()213}214215// Since the encoder writes no zeros, if we arrive at a decoder we have216// a value to extract and store. The field number has already been read217// (it's how we knew to call this decoder).218// Each decoder is responsible for handling any indirections associated219// with the data structure. If any pointer so reached is nil, allocation must220// be done.221222// decAlloc takes a value and returns a settable value that can223// be assigned to. If the value is a pointer, decAlloc guarantees it points to storage.224// The callers to the individual decoders are expected to have used decAlloc.225// The individual decoders don't need it.226func decAlloc(v reflect.Value) reflect.Value {227	for v.Kind() == reflect.Pointer {228		if v.IsNil() {229			v.Set(reflect.New(v.Type().Elem()))230		}231		v = v.Elem()232	}233	return v234}235236// decBool decodes a uint and stores it as a boolean in value.237func decBool(i *decInstr, state *decoderState, value reflect.Value) {238	value.SetBool(state.decodeUint() != 0)239}240241// decInt8 decodes an integer and stores it as an int8 in value.242func decInt8(i *decInstr, state *decoderState, value reflect.Value) {243	v := state.decodeInt()244	if v < math.MinInt8 || math.MaxInt8 < v {245		error_(i.ovfl)246	}247	value.SetInt(v)248}249250// decUint8 decodes an unsigned integer and stores it as a uint8 in value.251func decUint8(i *decInstr, state *decoderState, value reflect.Value) {252	v := state.decodeUint()253	if math.MaxUint8 < v {254		error_(i.ovfl)255	}256	value.SetUint(v)257}258259// decInt16 decodes an integer and stores it as an int16 in value.260func decInt16(i *decInstr, state *decoderState, value reflect.Value) {261	v := state.decodeInt()262	if v < math.MinInt16 || math.MaxInt16 < v {263		error_(i.ovfl)264	}265	value.SetInt(v)266}267268// decUint16 decodes an unsigned integer and stores it as a uint16 in value.269func decUint16(i *decInstr, state *decoderState, value reflect.Value) {270	v := state.decodeUint()271	if math.MaxUint16 < v {272		error_(i.ovfl)273	}274	value.SetUint(v)275}276277// decInt32 decodes an integer and stores it as an int32 in value.278func decInt32(i *decInstr, state *decoderState, value reflect.Value) {279	v := state.decodeInt()280	if v < math.MinInt32 || math.MaxInt32 < v {281		error_(i.ovfl)282	}283	value.SetInt(v)284}285286// decUint32 decodes an unsigned integer and stores it as a uint32 in value.287func decUint32(i *decInstr, state *decoderState, value reflect.Value) {288	v := state.decodeUint()289	if math.MaxUint32 < v {290		error_(i.ovfl)291	}292	value.SetUint(v)293}294295// decInt64 decodes an integer and stores it as an int64 in value.296func decInt64(i *decInstr, state *decoderState, value reflect.Value) {297	v := state.decodeInt()298	value.SetInt(v)299}300301// decUint64 decodes an unsigned integer and stores it as a uint64 in value.302func decUint64(i *decInstr, state *decoderState, value reflect.Value) {303	v := state.decodeUint()304	value.SetUint(v)305}306307// Floating-point numbers are transmitted as uint64s holding the bits308// of the underlying representation. They are sent byte-reversed, with309// the exponent end coming out first, so integer floating point numbers310// (for example) transmit more compactly. This routine does the311// unswizzling.312func float64FromBits(u uint64) float64 {313	v := bits.ReverseBytes64(u)314	return math.Float64frombits(v)315}316317// float32FromBits decodes an unsigned integer, treats it as a 32-bit floating-point318// number, and returns it. It's a helper function for float32 and complex64.319// It returns a float64 because that's what reflection needs, but its return320// value is known to be accurately representable in a float32.321func float32FromBits(u uint64, ovfl error) float64 {322	v := float64FromBits(u)323	av := v324	if av < 0 {325		av = -av326	}327	// +Inf is OK in both 32- and 64-bit floats. Underflow is always OK.328	if math.MaxFloat32 < av && av <= math.MaxFloat64 {329		error_(ovfl)330	}331	return v332}333334// decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point335// number, and stores it in value.336func decFloat32(i *decInstr, state *decoderState, value reflect.Value) {337	value.SetFloat(float32FromBits(state.decodeUint(), i.ovfl))338}339340// decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point341// number, and stores it in value.342func decFloat64(i *decInstr, state *decoderState, value reflect.Value) {343	value.SetFloat(float64FromBits(state.decodeUint()))344}345346// decComplex64 decodes a pair of unsigned integers, treats them as a347// pair of floating point numbers, and stores them as a complex64 in value.348// The real part comes first.349func decComplex64(i *decInstr, state *decoderState, value reflect.Value) {350	real := float32FromBits(state.decodeUint(), i.ovfl)351	imag := float32FromBits(state.decodeUint(), i.ovfl)352	value.SetComplex(complex(real, imag))353}354355// decComplex128 decodes a pair of unsigned integers, treats them as a356// pair of floating point numbers, and stores them as a complex128 in value.357// The real part comes first.358func decComplex128(i *decInstr, state *decoderState, value reflect.Value) {359	real := float64FromBits(state.decodeUint())360	imag := float64FromBits(state.decodeUint())361	value.SetComplex(complex(real, imag))362}363364// decUint8Slice decodes a byte slice and stores in value a slice header365// describing the data.366// uint8 slices are encoded as an unsigned count followed by the raw bytes.367func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) {368	n, ok := state.getLength()369	if !ok {370		errorf("bad %s slice length: %d", value.Type(), n)371	}372	if value.Cap() < n {373		safe := saferio.SliceCap[byte](uint64(n))374		if safe < 0 {375			errorf("%s slice too big: %d elements", value.Type(), n)376		}377		value.Set(reflect.MakeSlice(value.Type(), safe, safe))378		ln := safe379		i := 0380		for i < n {381			if i >= ln {382				// We didn't allocate the entire slice,383				// due to using saferio.SliceCap.384				// Grow the slice for one more element.385				// The slice is full, so this should386				// bump up the capacity.387				value.Grow(1)388			}389			// Copy into s up to the capacity or n,390			// whichever is less.391			ln = value.Cap()392			if ln > n {393				ln = n394			}395			value.SetLen(ln)396			sub := value.Slice(i, ln)397			if _, err := state.b.Read(sub.Bytes()); err != nil {398				errorf("error decoding []byte at %d: %s", i, err)399			}400			i = ln401		}402	} else {403		value.SetLen(n)404		if _, err := state.b.Read(value.Bytes()); err != nil {405			errorf("error decoding []byte: %s", err)406		}407	}408}409410// decString decodes byte array and stores in value a string header411// describing the data.412// Strings are encoded as an unsigned count followed by the raw bytes.413func decString(i *decInstr, state *decoderState, value reflect.Value) {414	n, ok := state.getLength()415	if !ok {416		errorf("bad %s slice length: %d", value.Type(), n)417	}418	// Read the data.419	data := state.b.Bytes()420	if len(data) < n {421		errorf("invalid string length %d: exceeds input size %d", n, len(data))422	}423	s := string(data[:n])424	state.b.Drop(n)425	value.SetString(s)426}427428// ignoreUint8Array skips over the data for a byte slice value with no destination.429func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) {430	n, ok := state.getLength()431	if !ok {432		errorf("slice length too large")433	}434	bn := state.b.Len()435	if bn < n {436		errorf("invalid slice length %d: exceeds input size %d", n, bn)437	}438	state.b.Drop(n)439}440441// Execution engine442443// The encoder engine is an array of instructions indexed by field number of the incoming444// decoder. It is executed with random access according to field number.445type decEngine struct {446	instr    []decInstr447	numInstr int // the number of active instructions448}449450// decodeSingle decodes a top-level value that is not a struct and stores it in value.451// Such values are preceded by a zero, making them have the memory layout of a452// struct field (although with an illegal field number).453func (dec *Decoder) decodeSingle(engine *decEngine, value reflect.Value) {454	state := dec.newDecoderState(&dec.buf)455	defer dec.freeDecoderState(state)456	state.fieldnum = singletonField457	if state.decodeUint() != 0 {458		errorf("decode: corrupted data: non-zero delta for singleton")459	}460	instr := &engine.instr[singletonField]461	instr.op(instr, state, value)462}463464// decodeStruct decodes a top-level struct and stores it in value.465// Indir is for the value, not the type. At the time of the call it may466// differ from ut.indir, which was computed when the engine was built.467// This state cannot arise for decodeSingle, which is called directly468// from the user's value, not from the innards of an engine.469func (dec *Decoder) decodeStruct(engine *decEngine, value reflect.Value) {470	state := dec.newDecoderState(&dec.buf)471	defer dec.freeDecoderState(state)472	state.fieldnum = -1473	for state.b.Len() > 0 {474		delta := int(state.decodeUint())475		if delta < 0 {476			errorf("decode: corrupted data: negative delta")477		}478		if delta == 0 { // struct terminator is zero delta fieldnum479			break480		}481		if state.fieldnum >= len(engine.instr)-delta { // subtract to compare without overflow482			error_(errRange)483		}484		fieldnum := state.fieldnum + delta485		instr := &engine.instr[fieldnum]486		var field reflect.Value487		if instr.index != nil {488			// Otherwise the field is unknown to us and instr.op is an ignore op.489			field = value.FieldByIndex(instr.index)490			if field.Kind() == reflect.Pointer {491				field = decAlloc(field)492			}493		}494		instr.op(instr, state, field)495		state.fieldnum = fieldnum496	}497}498499var noValue reflect.Value500501// ignoreStruct discards the data for a struct with no destination.502func (dec *Decoder) ignoreStruct(engine *decEngine) {503	state := dec.newDecoderState(&dec.buf)504	defer dec.freeDecoderState(state)505	state.fieldnum = -1506	for state.b.Len() > 0 {507		delta := int(state.decodeUint())508		if delta < 0 {509			errorf("ignore decode: corrupted data: negative delta")510		}511		if delta == 0 { // struct terminator is zero delta fieldnum512			break513		}514		fieldnum := state.fieldnum + delta515		if fieldnum >= len(engine.instr) {516			error_(errRange)517		}518		instr := &engine.instr[fieldnum]519		instr.op(instr, state, noValue)520		state.fieldnum = fieldnum521	}522}523524// ignoreSingle discards the data for a top-level non-struct value with no525// destination. It's used when calling Decode with a nil value.526func (dec *Decoder) ignoreSingle(engine *decEngine) {527	state := dec.newDecoderState(&dec.buf)528	defer dec.freeDecoderState(state)529	state.fieldnum = singletonField530	delta := int(state.decodeUint())531	if delta != 0 {532		errorf("decode: corrupted data: non-zero delta for singleton")533	}534	instr := &engine.instr[singletonField]535	instr.op(instr, state, noValue)536}537538// decodeArrayHelper does the work for decoding arrays and slices.539func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {540	if helper != nil && helper(state, value, length, ovfl) {541		return542	}543	instr := &decInstr{elemOp, 0, nil, ovfl}544	isPtr := value.Type().Elem().Kind() == reflect.Pointer545	ln := value.Len()546	for i := 0; i < length; i++ {547		if state.b.Len() == 0 {548			errorf("decoding array or slice: length exceeds input size (%d elements)", length)549		}550		if i >= ln {551			// This is a slice that we only partially allocated.552			// Grow it up to length.553			value.Grow(1)554			cp := value.Cap()555			if cp > length {556				cp = length557			}558			value.SetLen(cp)559			ln = cp560		}561		v := value.Index(i)562		if isPtr {563			v = decAlloc(v)564		}565		elemOp(instr, state, v)566	}567}568569// decodeArray decodes an array and stores it in value.570// The length is an unsigned integer preceding the elements. Even though the length is redundant571// (it's part of the type), it's a useful check and is included in the encoding.572func (dec *Decoder) decodeArray(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {573	if n := state.decodeUint(); n != uint64(length) {574		errorf("length mismatch in decodeArray")575	}576	dec.decodeArrayHelper(state, value, elemOp, length, ovfl, helper)577}578579// decodeIntoValue is a helper for map decoding.580func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, instr *decInstr) reflect.Value {581	v := value582	if isPtr {583		v = decAlloc(value)584	}585586	op(instr, state, v)587	return value588}589590// decodeMap decodes a map and stores it in value.591// Maps are encoded as a length followed by key:value pairs.592// Because the internals of maps are not visible to us, we must593// use reflection rather than pointer magic.594func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {595	n := int(state.decodeUint())596	if value.IsNil() {597		// This is a map, not a slice, but capping the598		// size works either way.599		safe := saferio.SliceCapWithSize(uint64(mtyp.Elem().Size()), uint64(n))600		if safe < 0 {601			safe = 1602		}603		value.Set(reflect.MakeMapWithSize(mtyp, safe))604	}605	keyIsPtr := mtyp.Key().Kind() == reflect.Pointer606	elemIsPtr := mtyp.Elem().Kind() == reflect.Pointer607	keyInstr := &decInstr{keyOp, 0, nil, ovfl}608	elemInstr := &decInstr{elemOp, 0, nil, ovfl}609	keyP := reflect.New(mtyp.Key())610	elemP := reflect.New(mtyp.Elem())611	for i := 0; i < n; i++ {612		key := decodeIntoValue(state, keyOp, keyIsPtr, keyP.Elem(), keyInstr)613		elem := decodeIntoValue(state, elemOp, elemIsPtr, elemP.Elem(), elemInstr)614		value.SetMapIndex(key, elem)615		keyP.Elem().SetZero()616		elemP.Elem().SetZero()617	}618}619620// ignoreArrayHelper does the work for discarding arrays and slices.621func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {622	instr := &decInstr{elemOp, 0, nil, errors.New("no error")}623	for i := 0; i < length; i++ {624		if state.b.Len() == 0 {625			errorf("decoding array or slice: length exceeds input size (%d elements)", length)626		}627		elemOp(instr, state, noValue)628	}629}630631// ignoreArray discards the data for an array value with no destination.632func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) {633	if n := state.decodeUint(); n != uint64(length) {634		errorf("length mismatch in ignoreArray")635	}636	dec.ignoreArrayHelper(state, elemOp, length)637}638639// ignoreMap discards the data for a map value with no destination.640func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {641	n := int(state.decodeUint())642	keyInstr := &decInstr{keyOp, 0, nil, errors.New("no error")}643	elemInstr := &decInstr{elemOp, 0, nil, errors.New("no error")}644	for i := 0; i < n; i++ {645		keyOp(keyInstr, state, noValue)646		elemOp(elemInstr, state, noValue)647	}648}649650// decodeSlice decodes a slice and stores it in value.651// Slices are encoded as an unsigned length followed by the elements.652func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp decOp, ovfl error, helper decHelper) {653	u := state.decodeUint()654	typ := value.Type()655	size := uint64(typ.Elem().Size())656	nBytes := u * size657	n := int(u)658	// Take care with overflow in this calculation.659	if n < 0 || uint64(n) != u || nBytes > tooBig || (size > 0 && nBytes/size != u) {660		// We don't check n against buffer length here because if it's a slice661		// of interfaces, there will be buffer reloads.662		errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)663	}664	if value.Cap() < n {665		safe := saferio.SliceCapWithSize(size, uint64(n))666		if safe < 0 {667			errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)668		}669		value.Set(reflect.MakeSlice(typ, safe, safe))670	} else {671		value.SetLen(n)672	}673	dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper)674}675676// ignoreSlice skips over the data for a slice value with no destination.677func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) {678	dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint()))679}680681// decodeInterface decodes an interface value and stores it in value.682// Interfaces are encoded as the name of a concrete type followed by a value.683// If the name is empty, the value is nil and no value is sent.684func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, value reflect.Value) {685	// Read the name of the concrete type.686	nr := state.decodeUint()687	if nr > 1<<31 { // zero is permissible for anonymous types688		errorf("invalid type name length %d", nr)689	}690	if nr > uint64(state.b.Len()) {691		errorf("invalid type name length %d: exceeds input size", nr)692	}693	n := int(nr)694	name := state.b.Bytes()[:n]695	state.b.Drop(n)696	// Allocate the destination interface value.697	if len(name) == 0 {698		// Copy the nil interface value to the target.699		value.SetZero()700		return701	}702	if len(name) > 1024 {703		errorf("name too long (%d bytes): %.20q...", len(name), name)704	}705	// The concrete type must be registered.706	typi, ok := nameToConcreteType.Load(string(name))707	if !ok {708		errorf("name not registered for interface: %q", name)709	}710	typ := typi.(reflect.Type)711712	// Read the type id of the concrete value.713	concreteId := dec.decodeTypeSequence(true)714	if concreteId < 0 {715		error_(dec.err)716	}717	// Byte count of value is next; we don't care what it is (it's there718	// in case we want to ignore the value by skipping it completely).719	state.decodeUint()720	// Read the concrete value.721	v := allocValue(typ)722	dec.decodeValue(concreteId, v)723	if dec.err != nil {724		error_(dec.err)725	}726	// Assign the concrete value to the interface.727	// Tread carefully; it might not satisfy the interface.728	if !typ.AssignableTo(ityp) {729		errorf("%s is not assignable to type %s", typ, ityp)730	}731	// Copy the interface value to the target.732	value.Set(v)733}734735// ignoreInterface discards the data for an interface value with no destination.736func (dec *Decoder) ignoreInterface(state *decoderState) {737	// Read the name of the concrete type.738	n, ok := state.getLength()739	if !ok {740		errorf("bad interface encoding: name too large for buffer")741	}742	bn := state.b.Len()743	if bn < n {744		errorf("invalid interface value length %d: exceeds input size %d", n, bn)745	}746	state.b.Drop(n)747	id := dec.decodeTypeSequence(true)748	if id < 0 {749		error_(dec.err)750	}751	// At this point, the decoder buffer contains a delimited value. Just toss it.752	n, ok = state.getLength()753	if !ok {754		errorf("bad interface encoding: data length too large for buffer")755	}756	state.b.Drop(n)757}758759// decodeGobDecoder decodes something implementing the GobDecoder interface.760// The data is encoded as a byte slice.761func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) {762	// Read the bytes for the value.763	n, ok := state.getLength()764	if !ok {765		errorf("GobDecoder: length too large for buffer")766	}767	b := state.b.Bytes()768	if len(b) < n {769		errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, len(b))770	}771	b = b[:n]772	state.b.Drop(n)773	var err error774	// We know it's one of these.775	switch ut.externalDec {776	case xGob:777		gobDecoder, _ := reflect.TypeAssert[GobDecoder](value)778		err = gobDecoder.GobDecode(b)779	case xBinary:780		binaryUnmarshaler, _ := reflect.TypeAssert[encoding.BinaryUnmarshaler](value)781		err = binaryUnmarshaler.UnmarshalBinary(b)782	case xText:783		textUnmarshaler, _ := reflect.TypeAssert[encoding.TextUnmarshaler](value)784		err = textUnmarshaler.UnmarshalText(b)785	}786	if err != nil {787		error_(err)788	}789}790791// ignoreGobDecoder discards the data for a GobDecoder value with no destination.792func (dec *Decoder) ignoreGobDecoder(state *decoderState) {793	// Read the bytes for the value.794	n, ok := state.getLength()795	if !ok {796		errorf("GobDecoder: length too large for buffer")797	}798	bn := state.b.Len()799	if bn < n {800		errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, bn)801	}802	state.b.Drop(n)803}804805// Index by Go types.806var decOpTable = [...]decOp{807	reflect.Bool:       decBool,808	reflect.Int8:       decInt8,809	reflect.Int16:      decInt16,810	reflect.Int32:      decInt32,811	reflect.Int64:      decInt64,812	reflect.Uint8:      decUint8,813	reflect.Uint16:     decUint16,814	reflect.Uint32:     decUint32,815	reflect.Uint64:     decUint64,816	reflect.Float32:    decFloat32,817	reflect.Float64:    decFloat64,818	reflect.Complex64:  decComplex64,819	reflect.Complex128: decComplex128,820	reflect.String:     decString,821}822823// Indexed by gob types.  tComplex will be added during type.init().824var decIgnoreOpMap = map[typeId]decOp{825	tBool:    ignoreUint,826	tInt:     ignoreUint,827	tUint:    ignoreUint,828	tFloat:   ignoreUint,829	tBytes:   ignoreUint8Array,830	tString:  ignoreUint8Array,831	tComplex: ignoreTwoUints,832}833834// decOpFor returns the decoding op for the base type under rt and835// the indirection count to reach it.836func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) *decOp {837	ut := userType(rt)838	// If the type implements GobEncoder, we handle it without further processing.839	if ut.externalDec != 0 {840		return dec.gobDecodeOpFor(ut)841	}842843	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).844	// Return the pointer to the op we're already building.845	if opPtr := inProgress[rt]; opPtr != nil {846		return opPtr847	}848	typ := ut.base849	var op decOp850	k := typ.Kind()851	if int(k) < len(decOpTable) {852		op = decOpTable[k]853	}854	if op == nil {855		inProgress[rt] = &op856		// Special cases857		switch t := typ; t.Kind() {858		case reflect.Array:859			name = "element of " + name860			elemId := dec.wireType[wireId].ArrayT.Elem861			elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)862			ovfl := overflow(name)863			helper := decArrayHelper[t.Elem().Kind()]864			op = func(i *decInstr, state *decoderState, value reflect.Value) {865				state.dec.decodeArray(state, value, *elemOp, t.Len(), ovfl, helper)866			}867868		case reflect.Map:869			keyId := dec.wireType[wireId].MapT.Key870			elemId := dec.wireType[wireId].MapT.Elem871			keyOp := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress)872			elemOp := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress)873			ovfl := overflow(name)874			op = func(i *decInstr, state *decoderState, value reflect.Value) {875				state.dec.decodeMap(t, state, value, *keyOp, *elemOp, ovfl)876			}877878		case reflect.Slice:879			name = "element of " + name880			if t.Elem().Kind() == reflect.Uint8 {881				op = decUint8Slice882				break883			}884			var elemId typeId885			if tt := builtinIdToType(wireId); tt != nil {886				elemId = tt.(*sliceType).Elem887			} else {888				elemId = dec.wireType[wireId].SliceT.Elem889			}890			elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)891			ovfl := overflow(name)892			helper := decSliceHelper[t.Elem().Kind()]893			op = func(i *decInstr, state *decoderState, value reflect.Value) {894				state.dec.decodeSlice(state, value, *elemOp, ovfl, helper)895			}896897		case reflect.Struct:898			// Generate a closure that calls out to the engine for the nested type.899			ut := userType(typ)900			enginePtr, err := dec.getDecEnginePtr(wireId, ut)901			if err != nil {902				error_(err)903			}904			op = func(i *decInstr, state *decoderState, value reflect.Value) {905				// indirect through enginePtr to delay evaluation for recursive structs.906				dec.decodeStruct(*enginePtr, value)907			}908		case reflect.Interface:909			op = func(i *decInstr, state *decoderState, value reflect.Value) {910				state.dec.decodeInterface(t, state, value)911			}912		}913	}914	if op == nil {915		errorf("decode can't handle type %s", rt)916	}917	return &op918}919920var maxIgnoreNestingDepth = 10000921922// decIgnoreOpFor returns the decoding op for a field that has no destination.923func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp {924	// Track how deep we've recursed trying to skip nested ignored fields.925	dec.ignoreDepth++926	defer func() { dec.ignoreDepth-- }()927	if dec.ignoreDepth > maxIgnoreNestingDepth {928		error_(errors.New("invalid nesting depth"))929	}930	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).931	// Return the pointer to the op we're already building.932	if opPtr := inProgress[wireId]; opPtr != nil {933		return opPtr934	}935	op, ok := decIgnoreOpMap[wireId]936	if !ok {937		inProgress[wireId] = &op938		if wireId == tInterface {939			// Special case because it's a method: the ignored item might940			// define types and we need to record their state in the decoder.941			op = func(i *decInstr, state *decoderState, value reflect.Value) {942				state.dec.ignoreInterface(state)943			}944			return &op945		}946		// Special cases947		wire := dec.wireType[wireId]948		switch {949		case wire == nil:950			errorf("bad data: undefined type %s", wireId.string())951		case wire.ArrayT != nil:952			elemId := wire.ArrayT.Elem953			elemOp := dec.decIgnoreOpFor(elemId, inProgress)954			op = func(i *decInstr, state *decoderState, value reflect.Value) {955				state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len)956			}957958		case wire.MapT != nil:959			keyId := dec.wireType[wireId].MapT.Key960			elemId := dec.wireType[wireId].MapT.Elem961			keyOp := dec.decIgnoreOpFor(keyId, inProgress)962			elemOp := dec.decIgnoreOpFor(elemId, inProgress)963			op = func(i *decInstr, state *decoderState, value reflect.Value) {964				state.dec.ignoreMap(state, *keyOp, *elemOp)965			}966967		case wire.SliceT != nil:968			elemId := wire.SliceT.Elem969			elemOp := dec.decIgnoreOpFor(elemId, inProgress)970			op = func(i *decInstr, state *decoderState, value reflect.Value) {971				state.dec.ignoreSlice(state, *elemOp)972			}973974		case wire.StructT != nil:975			// Generate a closure that calls out to the engine for the nested type.976			enginePtr, err := dec.getIgnoreEnginePtr(wireId)977			if err != nil {978				error_(err)979			}980			op = func(i *decInstr, state *decoderState, value reflect.Value) {981				// indirect through enginePtr to delay evaluation for recursive structs982				state.dec.ignoreStruct(*enginePtr)983			}984985		case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil:986			op = func(i *decInstr, state *decoderState, value reflect.Value) {987				state.dec.ignoreGobDecoder(state)988			}989		}990	}991	if op == nil {992		errorf("bad data: ignore can't handle type %s", wireId.string())993	}994	return &op995}996997// gobDecodeOpFor returns the op for a type that is known to implement998// GobDecoder.999func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) *decOp {1000	rcvrType := ut.user1001	if ut.decIndir == -1 {1002		rcvrType = reflect.PointerTo(rcvrType)1003	} else if ut.decIndir > 0 {1004		for i := int8(0); i < ut.decIndir; i++ {1005			rcvrType = rcvrType.Elem()1006		}1007	}1008	var op decOp1009	op = func(i *decInstr, state *decoderState, value reflect.Value) {1010		// We now have the base type. We need its address if the receiver is a pointer.1011		if value.Kind() != reflect.Pointer && rcvrType.Kind() == reflect.Pointer {1012			value = value.Addr()1013		}1014		state.dec.decodeGobDecoder(ut, state, value)1015	}1016	return &op1017}10181019// compatibleType asks: Are these two gob Types compatible?1020// Answers the question for basic types, arrays, maps and slices, plus1021// GobEncoder/Decoder pairs.1022// Structs are considered ok; fields will be checked later.1023func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool {1024	if rhs, ok := inProgress[fr]; ok {1025		return rhs == fw1026	}1027	inProgress[fr] = fw1028	ut := userType(fr)1029	wire, ok := dec.wireType[fw]1030	// If wire was encoded with an encoding method, fr must have that method.1031	// And if not, it must not.1032	// At most one of the booleans in ut is set.1033	// We could possibly relax this constraint in the future in order to1034	// choose the decoding method using the data in the wireType.1035	// The parentheses look odd but are correct.1036	if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||1037		(ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) ||1038		(ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {1039		return false1040	}1041	if ut.externalDec != 0 { // This test trumps all others.1042		return true1043	}1044	switch t := ut.base; t.Kind() {1045	default:1046		// chan, etc: cannot handle.1047		return false1048	case reflect.Bool:1049		return fw == tBool1050	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:1051		return fw == tInt1052	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:1053		return fw == tUint1054	case reflect.Float32, reflect.Float64:1055		return fw == tFloat1056	case reflect.Complex64, reflect.Complex128:1057		return fw == tComplex1058	case reflect.String:1059		return fw == tString1060	case reflect.Interface:1061		return fw == tInterface1062	case reflect.Array:1063		if !ok || wire.ArrayT == nil {1064			return false1065		}1066		array := wire.ArrayT1067		return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress)1068	case reflect.Map:1069		if !ok || wire.MapT == nil {1070			return false1071		}1072		MapType := wire.MapT1073		return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress)1074	case reflect.Slice:1075		// Is it an array of bytes?1076		if t.Elem().Kind() == reflect.Uint8 {1077			return fw == tBytes1078		}1079		// Extract and compare element types.1080		var sw *sliceType1081		if tt := builtinIdToType(fw); tt != nil {1082			sw, _ = tt.(*sliceType)1083		} else if wire != nil {1084			sw = wire.SliceT1085		}1086		elem := userType(t.Elem()).base1087		return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress)1088	case reflect.Struct:1089		return true1090	}1091}10921093// typeString returns a human-readable description of the type identified by remoteId.1094func (dec *Decoder) typeString(remoteId typeId) string {1095	typeLock.Lock()1096	defer typeLock.Unlock()1097	if t := idToType(remoteId); t != nil {1098		// globally known type.1099		return t.string()1100	}1101	return dec.wireType[remoteId].string()1102}11031104// compileSingle compiles the decoder engine for a non-struct top-level value, including1105// GobDecoders.1106func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {1107	rt := ut.user1108	engine = new(decEngine)1109	engine.instr = make([]decInstr, 1) // one item1110	name := rt.String()                // best we can do1111	if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {1112		remoteType := dec.typeString(remoteId)1113		// Common confusing case: local interface type, remote concrete type.1114		if ut.base.Kind() == reflect.Interface && remoteId != tInterface {1115			return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)1116		}1117		return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)1118	}1119	op := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))1120	ovfl := errors.New(`value for "` + name + `" out of range`)1121	engine.instr[singletonField] = decInstr{*op, singletonField, nil, ovfl}1122	engine.numInstr = 11123	return1124}11251126// compileIgnoreSingle compiles the decoder engine for a non-struct top-level value that will be discarded.1127func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine {1128	engine := new(decEngine)1129	engine.instr = make([]decInstr, 1) // one item1130	op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp))1131	ovfl := overflow(dec.typeString(remoteId))1132	engine.instr[0] = decInstr{*op, 0, nil, ovfl}1133	engine.numInstr = 11134	return engine1135}11361137// compileDec compiles the decoder engine for a value. If the value is not a struct,1138// it calls out to compileSingle.1139func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {1140	defer catchError(&err)1141	rt := ut.base1142	srt := rt1143	if srt.Kind() != reflect.Struct || ut.externalDec != 0 {1144		return dec.compileSingle(remoteId, ut)1145	}1146	var wireStruct *structType1147	// Builtin types can come from global pool; the rest must be defined by the decoder.1148	// Also we know we're decoding a struct now, so the client must have sent one.1149	if t := builtinIdToType(remoteId); t != nil {1150		wireStruct, _ = t.(*structType)1151	} else {1152		wire := dec.wireType[remoteId]1153		if wire == nil {1154			error_(errBadType)1155		}1156		wireStruct = wire.StructT1157	}1158	if wireStruct == nil {1159		errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)1160	}1161	engine = new(decEngine)1162	engine.instr = make([]decInstr, len(wireStruct.Field))1163	seen := make(map[reflect.Type]*decOp)1164	// Loop over the fields of the wire type.1165	for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ {1166		wireField := wireStruct.Field[fieldnum]1167		if wireField.Name == "" {1168			errorf("empty name for remote field of type %s", wireStruct.Name)1169		}1170		ovfl := overflow(wireField.Name)1171		// Find the field of the local type with the same name.1172		localField, present := srt.FieldByName(wireField.Name)1173		// TODO(r): anonymous names1174		if !present || !isExported(wireField.Name) {1175			op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp))1176			engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl}1177			continue1178		}1179		if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {1180			errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name)1181		}1182		op := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen)1183		engine.instr[fieldnum] = decInstr{*op, fieldnum, localField.Index, ovfl}1184		engine.numInstr++1185	}1186	return1187}11881189// getDecEnginePtr returns the engine for the specified type.1190func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) {1191	rt := ut.user1192	decoderMap, ok := dec.decoderCache[rt]1193	if !ok {1194		decoderMap = make(map[typeId]**decEngine)1195		dec.decoderCache[rt] = decoderMap1196	}1197	if enginePtr, ok = decoderMap[remoteId]; !ok {1198		// To handle recursive types, mark this engine as underway before compiling.1199		enginePtr = new(*decEngine)1200		decoderMap[remoteId] = enginePtr1201		*enginePtr, err = dec.compileDec(remoteId, ut)1202		if err != nil {1203			delete(decoderMap, remoteId)1204		}1205	}1206	return1207}12081209// emptyStruct is the type we compile into when ignoring a struct value.1210type emptyStruct struct{}12111212var emptyStructType = reflect.TypeFor[emptyStruct]()12131214// getIgnoreEnginePtr returns the engine for the specified type when the value is to be discarded.1215func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {1216	var ok bool1217	if enginePtr, ok = dec.ignorerCache[wireId]; !ok {1218		// To handle recursive types, mark this engine as underway before compiling.1219		enginePtr = new(*decEngine)1220		dec.ignorerCache[wireId] = enginePtr1221		wire := dec.wireType[wireId]1222		if wire != nil && wire.StructT != nil {1223			*enginePtr, err = dec.compileDec(wireId, userType(emptyStructType))1224		} else {1225			*enginePtr = dec.compileIgnoreSingle(wireId)1226		}1227		if err != nil {1228			delete(dec.ignorerCache, wireId)1229		}1230	}1231	return1232}12331234// decodeValue decodes the data stream representing a value and stores it in value.1235func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) {1236	defer catchError(&dec.err)1237	// If the value is nil, it means we should just ignore this item.1238	if !value.IsValid() {1239		dec.decodeIgnoredValue(wireId)1240		return1241	}1242	// Dereference down to the underlying type.1243	ut := userType(value.Type())1244	base := ut.base1245	var enginePtr **decEngine1246	enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)1247	if dec.err != nil {1248		return1249	}1250	value = decAlloc(value)1251	engine := *enginePtr1252	if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {1253		wt := dec.wireType[wireId]1254		if engine.numInstr == 0 && st.NumField() > 0 &&1255			wt != nil && len(wt.StructT.Field) > 0 {1256			name := base.Name()1257			errorf("type mismatch: no fields matched compiling decoder for %s", name)1258		}1259		dec.decodeStruct(engine, value)1260	} else {1261		dec.decodeSingle(engine, value)1262	}1263}12641265// decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it.1266func (dec *Decoder) decodeIgnoredValue(wireId typeId) {1267	var enginePtr **decEngine1268	enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId)1269	if dec.err != nil {1270		return1271	}1272	wire := dec.wireType[wireId]1273	if wire != nil && wire.StructT != nil {1274		dec.ignoreStruct(*enginePtr)1275	} else {1276		dec.ignoreSingle(*enginePtr)1277	}1278}12791280const (1281	intBits     = 32 << (^uint(0) >> 63)1282	uintptrBits = 32 << (^uintptr(0) >> 63)1283)12841285func init() {1286	var iop, uop decOp1287	switch intBits {1288	case 32:1289		iop = decInt321290		uop = decUint321291	case 64:1292		iop = decInt641293		uop = decUint641294	default:1295		panic("gob: unknown size of int/uint")1296	}1297	decOpTable[reflect.Int] = iop1298	decOpTable[reflect.Uint] = uop12991300	// Finally uintptr1301	switch uintptrBits {1302	case 32:1303		uop = decUint321304	case 64:1305		uop = decUint641306	default:1307		panic("gob: unknown size of uintptr")1308	}1309	decOpTable[reflect.Uintptr] = uop1310}13111312// Gob depends on being able to take the address1313// of zeroed Values it creates, so use this wrapper instead1314// of the standard reflect.Zero.1315// Each call allocates once.1316func allocValue(t reflect.Type) reflect.Value {1317	return reflect.New(t).Elem()1318}

Code quality findings 14

Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Defer inside loop; deferred calls accumulate until the function returns, not until the loop iteration ends. This can cause resource leaks
warning correctness defer-in-loop
defer dec.freeDecoderState(state)
Defer inside loop; deferred calls accumulate until the function returns, not until the loop iteration ends. This can cause resource leaks
warning correctness defer-in-loop
defer dec.freeDecoderState(state)
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Declared map variable without initialization; writing to a nil map causes a panic. Use make() to initialize
warning correctness nil-map-write
var decIgnoreOpMap = map[typeId]decOp{
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Blank identifier discarding results; verify intentional ignoring of return values
warning correctness blank-identifier-discard
sw, _ = tt.(*sliceType)
Blank identifier discarding results; verify intentional ignoring of return values
warning correctness blank-identifier-discard
wireStruct, _ = t.(*structType)
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Map created without size hint before being populated in a loop; provide capacity hint to reduce allocations
info performance map-without-size-hint
seen := make(map[reflect.Type]*decOp)
Hidden side effects; favor explicit initialization in main() or functions
info correctness func-init
func init() {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.