| | |
| | |
| | |
| |
|
| | |
| |
|
| | package gob |
| |
|
| | import ( |
| | "encoding" |
| | "errors" |
| | "internal/saferio" |
| | "io" |
| | "math" |
| | "math/bits" |
| | "reflect" |
| | ) |
| |
|
| | var ( |
| | errBadUint = errors.New("gob: encoded unsigned integer out of range") |
| | errBadType = errors.New("gob: unknown type id or corrupted data") |
| | errRange = errors.New("gob: bad data: field numbers out of bounds") |
| | ) |
| |
|
| | type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool |
| |
|
| | |
| | |
| | type decoderState struct { |
| | dec *Decoder |
| | |
| | |
| | b *decBuffer |
| | fieldnum int |
| | next *decoderState |
| | } |
| |
|
| | |
| | |
| | type decBuffer struct { |
| | data []byte |
| | offset int |
| | } |
| |
|
| | func (d *decBuffer) Read(p []byte) (int, error) { |
| | n := copy(p, d.data[d.offset:]) |
| | if n == 0 && len(p) != 0 { |
| | return 0, io.EOF |
| | } |
| | d.offset += n |
| | return n, nil |
| | } |
| |
|
| | func (d *decBuffer) Drop(n int) { |
| | if n > d.Len() { |
| | panic("drop") |
| | } |
| | d.offset += n |
| | } |
| |
|
| | func (d *decBuffer) ReadByte() (byte, error) { |
| | if d.offset >= len(d.data) { |
| | return 0, io.EOF |
| | } |
| | c := d.data[d.offset] |
| | d.offset++ |
| | return c, nil |
| | } |
| |
|
| | func (d *decBuffer) Len() int { |
| | return len(d.data) - d.offset |
| | } |
| |
|
| | func (d *decBuffer) Bytes() []byte { |
| | return d.data[d.offset:] |
| | } |
| |
|
| | |
| | func (d *decBuffer) SetBytes(data []byte) { |
| | d.data = data |
| | d.offset = 0 |
| | } |
| |
|
| | func (d *decBuffer) Reset() { |
| | d.data = d.data[0:0] |
| | d.offset = 0 |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) newDecoderState(buf *decBuffer) *decoderState { |
| | d := dec.freeList |
| | if d == nil { |
| | d = new(decoderState) |
| | d.dec = dec |
| | } else { |
| | dec.freeList = d.next |
| | } |
| | d.b = buf |
| | return d |
| | } |
| |
|
| | func (dec *Decoder) freeDecoderState(d *decoderState) { |
| | d.next = dec.freeList |
| | dec.freeList = d |
| | } |
| |
|
| | func overflow(name string) error { |
| | return errors.New(`value for "` + name + `" out of range`) |
| | } |
| |
|
| | |
| | |
| | func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) { |
| | width = 1 |
| | n, err := io.ReadFull(r, buf[0:width]) |
| | if n == 0 { |
| | return |
| | } |
| | b := buf[0] |
| | if b <= 0x7f { |
| | return uint64(b), width, nil |
| | } |
| | n = -int(int8(b)) |
| | if n > uint64Size { |
| | err = errBadUint |
| | return |
| | } |
| | width, err = io.ReadFull(r, buf[0:n]) |
| | if err != nil { |
| | if err == io.EOF { |
| | err = io.ErrUnexpectedEOF |
| | } |
| | return |
| | } |
| | |
| | for _, b := range buf[0:width] { |
| | x = x<<8 | uint64(b) |
| | } |
| | width++ |
| | return |
| | } |
| |
|
| | |
| | |
| | func (state *decoderState) decodeUint() (x uint64) { |
| | b, err := state.b.ReadByte() |
| | if err != nil { |
| | error_(err) |
| | } |
| | if b <= 0x7f { |
| | return uint64(b) |
| | } |
| | n := -int(int8(b)) |
| | if n > uint64Size { |
| | error_(errBadUint) |
| | } |
| | buf := state.b.Bytes() |
| | if len(buf) < n { |
| | errorf("invalid uint data length %d: exceeds input size %d", n, len(buf)) |
| | } |
| | |
| | |
| | for _, b := range buf[0:n] { |
| | x = x<<8 | uint64(b) |
| | } |
| | state.b.Drop(n) |
| | return x |
| | } |
| |
|
| | |
| | |
| | func (state *decoderState) decodeInt() int64 { |
| | x := state.decodeUint() |
| | if x&1 != 0 { |
| | return ^int64(x >> 1) |
| | } |
| | return int64(x >> 1) |
| | } |
| |
|
| | |
| | |
| | |
| | func (state *decoderState) getLength() (int, bool) { |
| | n := int(state.decodeUint()) |
| | if n < 0 || state.b.Len() < n || tooBig <= n { |
| | return 0, false |
| | } |
| | return n, true |
| | } |
| |
|
| | |
| | type decOp func(i *decInstr, state *decoderState, v reflect.Value) |
| |
|
| | |
| | type decInstr struct { |
| | op decOp |
| | field int |
| | index []int |
| | ovfl error |
| | } |
| |
|
| | |
| | func ignoreUint(i *decInstr, state *decoderState, v reflect.Value) { |
| | state.decodeUint() |
| | } |
| |
|
| | |
| | |
| | func ignoreTwoUints(i *decInstr, state *decoderState, v reflect.Value) { |
| | state.decodeUint() |
| | state.decodeUint() |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | func decAlloc(v reflect.Value) reflect.Value { |
| | for v.Kind() == reflect.Pointer { |
| | if v.IsNil() { |
| | v.Set(reflect.New(v.Type().Elem())) |
| | } |
| | v = v.Elem() |
| | } |
| | return v |
| | } |
| |
|
| | |
| | func decBool(i *decInstr, state *decoderState, value reflect.Value) { |
| | value.SetBool(state.decodeUint() != 0) |
| | } |
| |
|
| | |
| | func decInt8(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeInt() |
| | if v < math.MinInt8 || math.MaxInt8 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetInt(v) |
| | } |
| |
|
| | |
| | func decUint8(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeUint() |
| | if math.MaxUint8 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetUint(v) |
| | } |
| |
|
| | |
| | func decInt16(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeInt() |
| | if v < math.MinInt16 || math.MaxInt16 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetInt(v) |
| | } |
| |
|
| | |
| | func decUint16(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeUint() |
| | if math.MaxUint16 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetUint(v) |
| | } |
| |
|
| | |
| | func decInt32(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeInt() |
| | if v < math.MinInt32 || math.MaxInt32 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetInt(v) |
| | } |
| |
|
| | |
| | func decUint32(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeUint() |
| | if math.MaxUint32 < v { |
| | error_(i.ovfl) |
| | } |
| | value.SetUint(v) |
| | } |
| |
|
| | |
| | func decInt64(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeInt() |
| | value.SetInt(v) |
| | } |
| |
|
| | |
| | func decUint64(i *decInstr, state *decoderState, value reflect.Value) { |
| | v := state.decodeUint() |
| | value.SetUint(v) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func float64FromBits(u uint64) float64 { |
| | v := bits.ReverseBytes64(u) |
| | return math.Float64frombits(v) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func float32FromBits(u uint64, ovfl error) float64 { |
| | v := float64FromBits(u) |
| | av := v |
| | if av < 0 { |
| | av = -av |
| | } |
| | |
| | if math.MaxFloat32 < av && av <= math.MaxFloat64 { |
| | error_(ovfl) |
| | } |
| | return v |
| | } |
| |
|
| | |
| | |
| | func decFloat32(i *decInstr, state *decoderState, value reflect.Value) { |
| | value.SetFloat(float32FromBits(state.decodeUint(), i.ovfl)) |
| | } |
| |
|
| | |
| | |
| | func decFloat64(i *decInstr, state *decoderState, value reflect.Value) { |
| | value.SetFloat(float64FromBits(state.decodeUint())) |
| | } |
| |
|
| | |
| | |
| | |
| | func decComplex64(i *decInstr, state *decoderState, value reflect.Value) { |
| | real := float32FromBits(state.decodeUint(), i.ovfl) |
| | imag := float32FromBits(state.decodeUint(), i.ovfl) |
| | value.SetComplex(complex(real, imag)) |
| | } |
| |
|
| | |
| | |
| | |
| | func decComplex128(i *decInstr, state *decoderState, value reflect.Value) { |
| | real := float64FromBits(state.decodeUint()) |
| | imag := float64FromBits(state.decodeUint()) |
| | value.SetComplex(complex(real, imag)) |
| | } |
| |
|
| | |
| | |
| | |
| | func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) { |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("bad %s slice length: %d", value.Type(), n) |
| | } |
| | if value.Cap() < n { |
| | safe := saferio.SliceCap[byte](uint64(n)) |
| | if safe < 0 { |
| | errorf("%s slice too big: %d elements", value.Type(), n) |
| | } |
| | value.Set(reflect.MakeSlice(value.Type(), safe, safe)) |
| | ln := safe |
| | i := 0 |
| | for i < n { |
| | if i >= ln { |
| | |
| | |
| | |
| | |
| | |
| | value.Grow(1) |
| | } |
| | |
| | |
| | ln = value.Cap() |
| | if ln > n { |
| | ln = n |
| | } |
| | value.SetLen(ln) |
| | sub := value.Slice(i, ln) |
| | if _, err := state.b.Read(sub.Bytes()); err != nil { |
| | errorf("error decoding []byte at %d: %s", i, err) |
| | } |
| | i = ln |
| | } |
| | } else { |
| | value.SetLen(n) |
| | if _, err := state.b.Read(value.Bytes()); err != nil { |
| | errorf("error decoding []byte: %s", err) |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | func decString(i *decInstr, state *decoderState, value reflect.Value) { |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("bad %s slice length: %d", value.Type(), n) |
| | } |
| | |
| | data := state.b.Bytes() |
| | if len(data) < n { |
| | errorf("invalid string length %d: exceeds input size %d", n, len(data)) |
| | } |
| | s := string(data[:n]) |
| | state.b.Drop(n) |
| | value.SetString(s) |
| | } |
| |
|
| | |
| | func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) { |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("slice length too large") |
| | } |
| | bn := state.b.Len() |
| | if bn < n { |
| | errorf("invalid slice length %d: exceeds input size %d", n, bn) |
| | } |
| | state.b.Drop(n) |
| | } |
| |
|
| | |
| |
|
| | |
| | |
| | type decEngine struct { |
| | instr []decInstr |
| | numInstr int |
| | } |
| |
|
| | |
| | |
| | |
| | func (dec *Decoder) decodeSingle(engine *decEngine, value reflect.Value) { |
| | state := dec.newDecoderState(&dec.buf) |
| | defer dec.freeDecoderState(state) |
| | state.fieldnum = singletonField |
| | if state.decodeUint() != 0 { |
| | errorf("decode: corrupted data: non-zero delta for singleton") |
| | } |
| | instr := &engine.instr[singletonField] |
| | instr.op(instr, state, value) |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func (dec *Decoder) decodeStruct(engine *decEngine, value reflect.Value) { |
| | state := dec.newDecoderState(&dec.buf) |
| | defer dec.freeDecoderState(state) |
| | state.fieldnum = -1 |
| | for state.b.Len() > 0 { |
| | delta := int(state.decodeUint()) |
| | if delta < 0 { |
| | errorf("decode: corrupted data: negative delta") |
| | } |
| | if delta == 0 { |
| | break |
| | } |
| | if state.fieldnum >= len(engine.instr)-delta { |
| | error_(errRange) |
| | } |
| | fieldnum := state.fieldnum + delta |
| | instr := &engine.instr[fieldnum] |
| | var field reflect.Value |
| | if instr.index != nil { |
| | |
| | field = value.FieldByIndex(instr.index) |
| | if field.Kind() == reflect.Pointer { |
| | field = decAlloc(field) |
| | } |
| | } |
| | instr.op(instr, state, field) |
| | state.fieldnum = fieldnum |
| | } |
| | } |
| |
|
| | var noValue reflect.Value |
| |
|
| | |
| | func (dec *Decoder) ignoreStruct(engine *decEngine) { |
| | state := dec.newDecoderState(&dec.buf) |
| | defer dec.freeDecoderState(state) |
| | state.fieldnum = -1 |
| | for state.b.Len() > 0 { |
| | delta := int(state.decodeUint()) |
| | if delta < 0 { |
| | errorf("ignore decode: corrupted data: negative delta") |
| | } |
| | if delta == 0 { |
| | break |
| | } |
| | fieldnum := state.fieldnum + delta |
| | if fieldnum >= len(engine.instr) { |
| | error_(errRange) |
| | } |
| | instr := &engine.instr[fieldnum] |
| | instr.op(instr, state, noValue) |
| | state.fieldnum = fieldnum |
| | } |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) ignoreSingle(engine *decEngine) { |
| | state := dec.newDecoderState(&dec.buf) |
| | defer dec.freeDecoderState(state) |
| | state.fieldnum = singletonField |
| | delta := int(state.decodeUint()) |
| | if delta != 0 { |
| | errorf("decode: corrupted data: non-zero delta for singleton") |
| | } |
| | instr := &engine.instr[singletonField] |
| | instr.op(instr, state, noValue) |
| | } |
| |
|
| | |
| | func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) { |
| | if helper != nil && helper(state, value, length, ovfl) { |
| | return |
| | } |
| | instr := &decInstr{elemOp, 0, nil, ovfl} |
| | isPtr := value.Type().Elem().Kind() == reflect.Pointer |
| | ln := value.Len() |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= ln { |
| | |
| | |
| | value.Grow(1) |
| | cp := value.Cap() |
| | if cp > length { |
| | cp = length |
| | } |
| | value.SetLen(cp) |
| | ln = cp |
| | } |
| | v := value.Index(i) |
| | if isPtr { |
| | v = decAlloc(v) |
| | } |
| | elemOp(instr, state, v) |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | func (dec *Decoder) decodeArray(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) { |
| | if n := state.decodeUint(); n != uint64(length) { |
| | errorf("length mismatch in decodeArray") |
| | } |
| | dec.decodeArrayHelper(state, value, elemOp, length, ovfl, helper) |
| | } |
| |
|
| | |
| | func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, instr *decInstr) reflect.Value { |
| | v := value |
| | if isPtr { |
| | v = decAlloc(value) |
| | } |
| |
|
| | op(instr, state, v) |
| | return value |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) { |
| | n := int(state.decodeUint()) |
| | if value.IsNil() { |
| | value.Set(reflect.MakeMapWithSize(mtyp, n)) |
| | } |
| | keyIsPtr := mtyp.Key().Kind() == reflect.Pointer |
| | elemIsPtr := mtyp.Elem().Kind() == reflect.Pointer |
| | keyInstr := &decInstr{keyOp, 0, nil, ovfl} |
| | elemInstr := &decInstr{elemOp, 0, nil, ovfl} |
| | keyP := reflect.New(mtyp.Key()) |
| | elemP := reflect.New(mtyp.Elem()) |
| | for i := 0; i < n; i++ { |
| | key := decodeIntoValue(state, keyOp, keyIsPtr, keyP.Elem(), keyInstr) |
| | elem := decodeIntoValue(state, elemOp, elemIsPtr, elemP.Elem(), elemInstr) |
| | value.SetMapIndex(key, elem) |
| | keyP.Elem().SetZero() |
| | elemP.Elem().SetZero() |
| | } |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) { |
| | instr := &decInstr{elemOp, 0, nil, errors.New("no error")} |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | elemOp(instr, state, noValue) |
| | } |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) { |
| | if n := state.decodeUint(); n != uint64(length) { |
| | errorf("length mismatch in ignoreArray") |
| | } |
| | dec.ignoreArrayHelper(state, elemOp, length) |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) { |
| | n := int(state.decodeUint()) |
| | keyInstr := &decInstr{keyOp, 0, nil, errors.New("no error")} |
| | elemInstr := &decInstr{elemOp, 0, nil, errors.New("no error")} |
| | for i := 0; i < n; i++ { |
| | keyOp(keyInstr, state, noValue) |
| | elemOp(elemInstr, state, noValue) |
| | } |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp decOp, ovfl error, helper decHelper) { |
| | u := state.decodeUint() |
| | typ := value.Type() |
| | size := uint64(typ.Elem().Size()) |
| | nBytes := u * size |
| | n := int(u) |
| | |
| | if n < 0 || uint64(n) != u || nBytes > tooBig || (size > 0 && nBytes/size != u) { |
| | |
| | |
| | errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size) |
| | } |
| | if value.Cap() < n { |
| | safe := saferio.SliceCapWithSize(size, uint64(n)) |
| | if safe < 0 { |
| | errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size) |
| | } |
| | value.Set(reflect.MakeSlice(typ, safe, safe)) |
| | } else { |
| | value.SetLen(n) |
| | } |
| | dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper) |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) { |
| | dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint())) |
| | } |
| |
|
| | |
| | |
| | |
| | func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, value reflect.Value) { |
| | |
| | nr := state.decodeUint() |
| | if nr > 1<<31 { |
| | errorf("invalid type name length %d", nr) |
| | } |
| | if nr > uint64(state.b.Len()) { |
| | errorf("invalid type name length %d: exceeds input size", nr) |
| | } |
| | n := int(nr) |
| | name := state.b.Bytes()[:n] |
| | state.b.Drop(n) |
| | |
| | if len(name) == 0 { |
| | |
| | value.SetZero() |
| | return |
| | } |
| | if len(name) > 1024 { |
| | errorf("name too long (%d bytes): %.20q...", len(name), name) |
| | } |
| | |
| | typi, ok := nameToConcreteType.Load(string(name)) |
| | if !ok { |
| | errorf("name not registered for interface: %q", name) |
| | } |
| | typ := typi.(reflect.Type) |
| |
|
| | |
| | concreteId := dec.decodeTypeSequence(true) |
| | if concreteId < 0 { |
| | error_(dec.err) |
| | } |
| | |
| | |
| | state.decodeUint() |
| | |
| | v := allocValue(typ) |
| | dec.decodeValue(concreteId, v) |
| | if dec.err != nil { |
| | error_(dec.err) |
| | } |
| | |
| | |
| | if !typ.AssignableTo(ityp) { |
| | errorf("%s is not assignable to type %s", typ, ityp) |
| | } |
| | |
| | value.Set(v) |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreInterface(state *decoderState) { |
| | |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("bad interface encoding: name too large for buffer") |
| | } |
| | bn := state.b.Len() |
| | if bn < n { |
| | errorf("invalid interface value length %d: exceeds input size %d", n, bn) |
| | } |
| | state.b.Drop(n) |
| | id := dec.decodeTypeSequence(true) |
| | if id < 0 { |
| | error_(dec.err) |
| | } |
| | |
| | n, ok = state.getLength() |
| | if !ok { |
| | errorf("bad interface encoding: data length too large for buffer") |
| | } |
| | state.b.Drop(n) |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) { |
| | |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("GobDecoder: length too large for buffer") |
| | } |
| | b := state.b.Bytes() |
| | if len(b) < n { |
| | errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, len(b)) |
| | } |
| | b = b[:n] |
| | state.b.Drop(n) |
| | var err error |
| | |
| | switch ut.externalDec { |
| | case xGob: |
| | gobDecoder, _ := reflect.TypeAssert[GobDecoder](value) |
| | err = gobDecoder.GobDecode(b) |
| | case xBinary: |
| | binaryUnmarshaler, _ := reflect.TypeAssert[encoding.BinaryUnmarshaler](value) |
| | err = binaryUnmarshaler.UnmarshalBinary(b) |
| | case xText: |
| | textUnmarshaler, _ := reflect.TypeAssert[encoding.TextUnmarshaler](value) |
| | err = textUnmarshaler.UnmarshalText(b) |
| | } |
| | if err != nil { |
| | error_(err) |
| | } |
| | } |
| |
|
| | |
| | func (dec *Decoder) ignoreGobDecoder(state *decoderState) { |
| | |
| | n, ok := state.getLength() |
| | if !ok { |
| | errorf("GobDecoder: length too large for buffer") |
| | } |
| | bn := state.b.Len() |
| | if bn < n { |
| | errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, bn) |
| | } |
| | state.b.Drop(n) |
| | } |
| |
|
| | |
| | var decOpTable = [...]decOp{ |
| | reflect.Bool: decBool, |
| | reflect.Int8: decInt8, |
| | reflect.Int16: decInt16, |
| | reflect.Int32: decInt32, |
| | reflect.Int64: decInt64, |
| | reflect.Uint8: decUint8, |
| | reflect.Uint16: decUint16, |
| | reflect.Uint32: decUint32, |
| | reflect.Uint64: decUint64, |
| | reflect.Float32: decFloat32, |
| | reflect.Float64: decFloat64, |
| | reflect.Complex64: decComplex64, |
| | reflect.Complex128: decComplex128, |
| | reflect.String: decString, |
| | } |
| |
|
| | |
| | var decIgnoreOpMap = map[typeId]decOp{ |
| | tBool: ignoreUint, |
| | tInt: ignoreUint, |
| | tUint: ignoreUint, |
| | tFloat: ignoreUint, |
| | tBytes: ignoreUint8Array, |
| | tString: ignoreUint8Array, |
| | tComplex: ignoreTwoUints, |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) *decOp { |
| | ut := userType(rt) |
| | |
| | if ut.externalDec != 0 { |
| | return dec.gobDecodeOpFor(ut) |
| | } |
| |
|
| | |
| | |
| | if opPtr := inProgress[rt]; opPtr != nil { |
| | return opPtr |
| | } |
| | typ := ut.base |
| | var op decOp |
| | k := typ.Kind() |
| | if int(k) < len(decOpTable) { |
| | op = decOpTable[k] |
| | } |
| | if op == nil { |
| | inProgress[rt] = &op |
| | |
| | switch t := typ; t.Kind() { |
| | case reflect.Array: |
| | name = "element of " + name |
| | elemId := dec.wireType[wireId].ArrayT.Elem |
| | elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress) |
| | ovfl := overflow(name) |
| | helper := decArrayHelper[t.Elem().Kind()] |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.decodeArray(state, value, *elemOp, t.Len(), ovfl, helper) |
| | } |
| |
|
| | case reflect.Map: |
| | keyId := dec.wireType[wireId].MapT.Key |
| | elemId := dec.wireType[wireId].MapT.Elem |
| | keyOp := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress) |
| | elemOp := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress) |
| | ovfl := overflow(name) |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.decodeMap(t, state, value, *keyOp, *elemOp, ovfl) |
| | } |
| |
|
| | case reflect.Slice: |
| | name = "element of " + name |
| | if t.Elem().Kind() == reflect.Uint8 { |
| | op = decUint8Slice |
| | break |
| | } |
| | var elemId typeId |
| | if tt := builtinIdToType(wireId); tt != nil { |
| | elemId = tt.(*sliceType).Elem |
| | } else { |
| | elemId = dec.wireType[wireId].SliceT.Elem |
| | } |
| | elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress) |
| | ovfl := overflow(name) |
| | helper := decSliceHelper[t.Elem().Kind()] |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.decodeSlice(state, value, *elemOp, ovfl, helper) |
| | } |
| |
|
| | case reflect.Struct: |
| | |
| | ut := userType(typ) |
| | enginePtr, err := dec.getDecEnginePtr(wireId, ut) |
| | if err != nil { |
| | error_(err) |
| | } |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | |
| | dec.decodeStruct(*enginePtr, value) |
| | } |
| | case reflect.Interface: |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.decodeInterface(t, state, value) |
| | } |
| | } |
| | } |
| | if op == nil { |
| | errorf("decode can't handle type %s", rt) |
| | } |
| | return &op |
| | } |
| |
|
| | var maxIgnoreNestingDepth = 10000 |
| |
|
| | |
| | func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp { |
| | |
| | dec.ignoreDepth++ |
| | defer func() { dec.ignoreDepth-- }() |
| | if dec.ignoreDepth > maxIgnoreNestingDepth { |
| | error_(errors.New("invalid nesting depth")) |
| | } |
| | |
| | |
| | if opPtr := inProgress[wireId]; opPtr != nil { |
| | return opPtr |
| | } |
| | op, ok := decIgnoreOpMap[wireId] |
| | if !ok { |
| | inProgress[wireId] = &op |
| | if wireId == tInterface { |
| | |
| | |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.ignoreInterface(state) |
| | } |
| | return &op |
| | } |
| | |
| | wire := dec.wireType[wireId] |
| | switch { |
| | case wire == nil: |
| | errorf("bad data: undefined type %s", wireId.string()) |
| | case wire.ArrayT != nil: |
| | elemId := wire.ArrayT.Elem |
| | elemOp := dec.decIgnoreOpFor(elemId, inProgress) |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len) |
| | } |
| |
|
| | case wire.MapT != nil: |
| | keyId := dec.wireType[wireId].MapT.Key |
| | elemId := dec.wireType[wireId].MapT.Elem |
| | keyOp := dec.decIgnoreOpFor(keyId, inProgress) |
| | elemOp := dec.decIgnoreOpFor(elemId, inProgress) |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.ignoreMap(state, *keyOp, *elemOp) |
| | } |
| |
|
| | case wire.SliceT != nil: |
| | elemId := wire.SliceT.Elem |
| | elemOp := dec.decIgnoreOpFor(elemId, inProgress) |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.ignoreSlice(state, *elemOp) |
| | } |
| |
|
| | case wire.StructT != nil: |
| | |
| | enginePtr, err := dec.getIgnoreEnginePtr(wireId) |
| | if err != nil { |
| | error_(err) |
| | } |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | |
| | state.dec.ignoreStruct(*enginePtr) |
| | } |
| |
|
| | case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil: |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | state.dec.ignoreGobDecoder(state) |
| | } |
| | } |
| | } |
| | if op == nil { |
| | errorf("bad data: ignore can't handle type %s", wireId.string()) |
| | } |
| | return &op |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) *decOp { |
| | rcvrType := ut.user |
| | if ut.decIndir == -1 { |
| | rcvrType = reflect.PointerTo(rcvrType) |
| | } else if ut.decIndir > 0 { |
| | for i := int8(0); i < ut.decIndir; i++ { |
| | rcvrType = rcvrType.Elem() |
| | } |
| | } |
| | var op decOp |
| | op = func(i *decInstr, state *decoderState, value reflect.Value) { |
| | |
| | if value.Kind() != reflect.Pointer && rcvrType.Kind() == reflect.Pointer { |
| | value = value.Addr() |
| | } |
| | state.dec.decodeGobDecoder(ut, state, value) |
| | } |
| | return &op |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool { |
| | if rhs, ok := inProgress[fr]; ok { |
| | return rhs == fw |
| | } |
| | inProgress[fr] = fw |
| | ut := userType(fr) |
| | wire, ok := dec.wireType[fw] |
| | |
| | |
| | |
| | |
| | |
| | |
| | if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) || |
| | (ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) || |
| | (ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) { |
| | return false |
| | } |
| | if ut.externalDec != 0 { |
| | return true |
| | } |
| | switch t := ut.base; t.Kind() { |
| | default: |
| | |
| | return false |
| | case reflect.Bool: |
| | return fw == tBool |
| | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| | return fw == tInt |
| | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |
| | return fw == tUint |
| | case reflect.Float32, reflect.Float64: |
| | return fw == tFloat |
| | case reflect.Complex64, reflect.Complex128: |
| | return fw == tComplex |
| | case reflect.String: |
| | return fw == tString |
| | case reflect.Interface: |
| | return fw == tInterface |
| | case reflect.Array: |
| | if !ok || wire.ArrayT == nil { |
| | return false |
| | } |
| | array := wire.ArrayT |
| | return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress) |
| | case reflect.Map: |
| | if !ok || wire.MapT == nil { |
| | return false |
| | } |
| | MapType := wire.MapT |
| | return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress) |
| | case reflect.Slice: |
| | |
| | if t.Elem().Kind() == reflect.Uint8 { |
| | return fw == tBytes |
| | } |
| | |
| | var sw *sliceType |
| | if tt := builtinIdToType(fw); tt != nil { |
| | sw, _ = tt.(*sliceType) |
| | } else if wire != nil { |
| | sw = wire.SliceT |
| | } |
| | elem := userType(t.Elem()).base |
| | return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress) |
| | case reflect.Struct: |
| | return true |
| | } |
| | } |
| |
|
| | |
| | func (dec *Decoder) typeString(remoteId typeId) string { |
| | typeLock.Lock() |
| | defer typeLock.Unlock() |
| | if t := idToType(remoteId); t != nil { |
| | |
| | return t.string() |
| | } |
| | return dec.wireType[remoteId].string() |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) { |
| | rt := ut.user |
| | engine = new(decEngine) |
| | engine.instr = make([]decInstr, 1) |
| | name := rt.String() |
| | if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) { |
| | remoteType := dec.typeString(remoteId) |
| | |
| | if ut.base.Kind() == reflect.Interface && remoteId != tInterface { |
| | return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType) |
| | } |
| | return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType) |
| | } |
| | op := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp)) |
| | ovfl := errors.New(`value for "` + name + `" out of range`) |
| | engine.instr[singletonField] = decInstr{*op, singletonField, nil, ovfl} |
| | engine.numInstr = 1 |
| | return |
| | } |
| |
|
| | |
| | func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine { |
| | engine := new(decEngine) |
| | engine.instr = make([]decInstr, 1) |
| | op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp)) |
| | ovfl := overflow(dec.typeString(remoteId)) |
| | engine.instr[0] = decInstr{*op, 0, nil, ovfl} |
| | engine.numInstr = 1 |
| | return engine |
| | } |
| |
|
| | |
| | |
| | func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) { |
| | defer catchError(&err) |
| | rt := ut.base |
| | srt := rt |
| | if srt.Kind() != reflect.Struct || ut.externalDec != 0 { |
| | return dec.compileSingle(remoteId, ut) |
| | } |
| | var wireStruct *structType |
| | |
| | |
| | if t := builtinIdToType(remoteId); t != nil { |
| | wireStruct, _ = t.(*structType) |
| | } else { |
| | wire := dec.wireType[remoteId] |
| | if wire == nil { |
| | error_(errBadType) |
| | } |
| | wireStruct = wire.StructT |
| | } |
| | if wireStruct == nil { |
| | errorf("type mismatch in decoder: want struct type %s; got non-struct", rt) |
| | } |
| | engine = new(decEngine) |
| | engine.instr = make([]decInstr, len(wireStruct.Field)) |
| | seen := make(map[reflect.Type]*decOp) |
| | |
| | for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ { |
| | wireField := wireStruct.Field[fieldnum] |
| | if wireField.Name == "" { |
| | errorf("empty name for remote field of type %s", wireStruct.Name) |
| | } |
| | ovfl := overflow(wireField.Name) |
| | |
| | localField, present := srt.FieldByName(wireField.Name) |
| | |
| | if !present || !isExported(wireField.Name) { |
| | op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp)) |
| | engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl} |
| | continue |
| | } |
| | if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) { |
| | errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name) |
| | } |
| | op := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen) |
| | engine.instr[fieldnum] = decInstr{*op, fieldnum, localField.Index, ovfl} |
| | engine.numInstr++ |
| | } |
| | return |
| | } |
| |
|
| | |
| | func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) { |
| | rt := ut.user |
| | decoderMap, ok := dec.decoderCache[rt] |
| | if !ok { |
| | decoderMap = make(map[typeId]**decEngine) |
| | dec.decoderCache[rt] = decoderMap |
| | } |
| | if enginePtr, ok = decoderMap[remoteId]; !ok { |
| | |
| | enginePtr = new(*decEngine) |
| | decoderMap[remoteId] = enginePtr |
| | *enginePtr, err = dec.compileDec(remoteId, ut) |
| | if err != nil { |
| | delete(decoderMap, remoteId) |
| | } |
| | } |
| | return |
| | } |
| |
|
| | |
| | type emptyStruct struct{} |
| |
|
| | var emptyStructType = reflect.TypeFor[emptyStruct]() |
| |
|
| | |
| | func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) { |
| | var ok bool |
| | if enginePtr, ok = dec.ignorerCache[wireId]; !ok { |
| | |
| | enginePtr = new(*decEngine) |
| | dec.ignorerCache[wireId] = enginePtr |
| | wire := dec.wireType[wireId] |
| | if wire != nil && wire.StructT != nil { |
| | *enginePtr, err = dec.compileDec(wireId, userType(emptyStructType)) |
| | } else { |
| | *enginePtr = dec.compileIgnoreSingle(wireId) |
| | } |
| | if err != nil { |
| | delete(dec.ignorerCache, wireId) |
| | } |
| | } |
| | return |
| | } |
| |
|
| | |
| | func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) { |
| | defer catchError(&dec.err) |
| | |
| | if !value.IsValid() { |
| | dec.decodeIgnoredValue(wireId) |
| | return |
| | } |
| | |
| | ut := userType(value.Type()) |
| | base := ut.base |
| | var enginePtr **decEngine |
| | enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut) |
| | if dec.err != nil { |
| | return |
| | } |
| | value = decAlloc(value) |
| | engine := *enginePtr |
| | if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 { |
| | wt := dec.wireType[wireId] |
| | if engine.numInstr == 0 && st.NumField() > 0 && |
| | wt != nil && len(wt.StructT.Field) > 0 { |
| | name := base.Name() |
| | errorf("type mismatch: no fields matched compiling decoder for %s", name) |
| | } |
| | dec.decodeStruct(engine, value) |
| | } else { |
| | dec.decodeSingle(engine, value) |
| | } |
| | } |
| |
|
| | |
| | func (dec *Decoder) decodeIgnoredValue(wireId typeId) { |
| | var enginePtr **decEngine |
| | enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId) |
| | if dec.err != nil { |
| | return |
| | } |
| | wire := dec.wireType[wireId] |
| | if wire != nil && wire.StructT != nil { |
| | dec.ignoreStruct(*enginePtr) |
| | } else { |
| | dec.ignoreSingle(*enginePtr) |
| | } |
| | } |
| |
|
| | const ( |
| | intBits = 32 << (^uint(0) >> 63) |
| | uintptrBits = 32 << (^uintptr(0) >> 63) |
| | ) |
| |
|
| | func init() { |
| | var iop, uop decOp |
| | switch intBits { |
| | case 32: |
| | iop = decInt32 |
| | uop = decUint32 |
| | case 64: |
| | iop = decInt64 |
| | uop = decUint64 |
| | default: |
| | panic("gob: unknown size of int/uint") |
| | } |
| | decOpTable[reflect.Int] = iop |
| | decOpTable[reflect.Uint] = uop |
| |
|
| | |
| | switch uintptrBits { |
| | case 32: |
| | uop = decUint32 |
| | case 64: |
| | uop = decUint64 |
| | default: |
| | panic("gob: unknown size of uintptr") |
| | } |
| | decOpTable[reflect.Uintptr] = uop |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func allocValue(t reflect.Type) reflect.Value { |
| | return reflect.New(t).Elem() |
| | } |
| |
|