| | |
| |
|
| | |
| | |
| | |
| |
|
| | package gob |
| |
|
| | import ( |
| | "math" |
| | "reflect" |
| | ) |
| |
|
| | var decArrayHelper = map[reflect.Kind]decHelper{ |
| | reflect.Bool: decBoolArray, |
| | reflect.Complex64: decComplex64Array, |
| | reflect.Complex128: decComplex128Array, |
| | reflect.Float32: decFloat32Array, |
| | reflect.Float64: decFloat64Array, |
| | reflect.Int: decIntArray, |
| | reflect.Int16: decInt16Array, |
| | reflect.Int32: decInt32Array, |
| | reflect.Int64: decInt64Array, |
| | reflect.Int8: decInt8Array, |
| | reflect.String: decStringArray, |
| | reflect.Uint: decUintArray, |
| | reflect.Uint16: decUint16Array, |
| | reflect.Uint32: decUint32Array, |
| | reflect.Uint64: decUint64Array, |
| | reflect.Uintptr: decUintptrArray, |
| | } |
| |
|
| | var decSliceHelper = map[reflect.Kind]decHelper{ |
| | reflect.Bool: decBoolSlice, |
| | reflect.Complex64: decComplex64Slice, |
| | reflect.Complex128: decComplex128Slice, |
| | reflect.Float32: decFloat32Slice, |
| | reflect.Float64: decFloat64Slice, |
| | reflect.Int: decIntSlice, |
| | reflect.Int16: decInt16Slice, |
| | reflect.Int32: decInt32Slice, |
| | reflect.Int64: decInt64Slice, |
| | reflect.Int8: decInt8Slice, |
| | reflect.String: decStringSlice, |
| | reflect.Uint: decUintSlice, |
| | reflect.Uint16: decUint16Slice, |
| | reflect.Uint32: decUint32Slice, |
| | reflect.Uint64: decUint64Slice, |
| | reflect.Uintptr: decUintptrSlice, |
| | } |
| |
|
| | func decBoolArray(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decBoolSlice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decBoolSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]bool](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding bool array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | slice[i] = state.decodeUint() != 0 |
| | } |
| | return true |
| | } |
| |
|
| | func decComplex64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decComplex64Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decComplex64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]complex64](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding complex64 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | real := float32FromBits(state.decodeUint(), ovfl) |
| | imag := float32FromBits(state.decodeUint(), ovfl) |
| | slice[i] = complex(float32(real), float32(imag)) |
| | } |
| | return true |
| | } |
| |
|
| | func decComplex128Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decComplex128Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decComplex128Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]complex128](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding complex128 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | real := float64FromBits(state.decodeUint()) |
| | imag := float64FromBits(state.decodeUint()) |
| | slice[i] = complex(real, imag) |
| | } |
| | return true |
| | } |
| |
|
| | func decFloat32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decFloat32Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decFloat32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]float32](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding float32 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | slice[i] = float32(float32FromBits(state.decodeUint(), ovfl)) |
| | } |
| | return true |
| | } |
| |
|
| | func decFloat64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decFloat64Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decFloat64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]float64](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding float64 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | slice[i] = float64FromBits(state.decodeUint()) |
| | } |
| | return true |
| | } |
| |
|
| | func decIntArray(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decIntSlice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decIntSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]int](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding int array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeInt() |
| | |
| | if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = int(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decInt16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decInt16Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decInt16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]int16](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding int16 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeInt() |
| | if x < math.MinInt16 || math.MaxInt16 < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = int16(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decInt32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decInt32Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decInt32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]int32](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding int32 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeInt() |
| | if x < math.MinInt32 || math.MaxInt32 < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = int32(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decInt64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decInt64Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decInt64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]int64](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding int64 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | slice[i] = state.decodeInt() |
| | } |
| | return true |
| | } |
| |
|
| | func decInt8Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decInt8Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decInt8Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]int8](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding int8 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeInt() |
| | if x < math.MinInt8 || math.MaxInt8 < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = int8(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decStringArray(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decStringSlice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decStringSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]string](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding string array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | u := state.decodeUint() |
| | n := int(u) |
| | if n < 0 || uint64(n) != u || n > state.b.Len() { |
| | errorf("length of string exceeds input size (%d bytes)", u) |
| | } |
| | if n > state.b.Len() { |
| | errorf("string data too long for buffer: %d", n) |
| | } |
| | |
| | data := state.b.Bytes() |
| | if len(data) < n { |
| | errorf("invalid string length %d: exceeds input size %d", n, len(data)) |
| | } |
| | slice[i] = string(data[:n]) |
| | state.b.Drop(n) |
| | } |
| | return true |
| | } |
| |
|
| | func decUintArray(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decUintSlice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decUintSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]uint](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding uint array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeUint() |
| | |
| | |
| | |
| | slice[i] = uint(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decUint16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decUint16Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decUint16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]uint16](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding uint16 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeUint() |
| | if math.MaxUint16 < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = uint16(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decUint32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decUint32Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decUint32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]uint32](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding uint32 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeUint() |
| | if math.MaxUint32 < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = uint32(x) |
| | } |
| | return true |
| | } |
| |
|
| | func decUint64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decUint64Slice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decUint64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]uint64](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding uint64 array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | slice[i] = state.decodeUint() |
| | } |
| | return true |
| | } |
| |
|
| | func decUintptrArray(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | |
| | if !v.CanAddr() { |
| | return false |
| | } |
| | return decUintptrSlice(state, v.Slice(0, v.Len()), length, ovfl) |
| | } |
| |
|
| | func decUintptrSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool { |
| | slice, ok := reflect.TypeAssert[[]uintptr](v) |
| | if !ok { |
| | |
| | return false |
| | } |
| | for i := 0; i < length; i++ { |
| | if state.b.Len() == 0 { |
| | errorf("decoding uintptr array or slice: length exceeds input size (%d elements)", length) |
| | } |
| | if i >= len(slice) { |
| | |
| | growSlice(v, &slice, length) |
| | } |
| | x := state.decodeUint() |
| | if uint64(^uintptr(0)) < x { |
| | error_(ovfl) |
| | } |
| | slice[i] = uintptr(x) |
| | } |
| | return true |
| | } |
| |
|
| | |
| | |
| | func growSlice[E any](v reflect.Value, ps *[]E, length int) { |
| | var zero E |
| | s := *ps |
| | s = append(s, zero) |
| | cp := cap(s) |
| | if cp > length { |
| | cp = length |
| | } |
| | s = s[:cp] |
| | v.Set(reflect.ValueOf(s)) |
| | *ps = s |
| | } |
| |
|