mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-09-11 05:08:44 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20a5c6c0b6 |
No files matched your search
@@ -75,7 +75,7 @@ require (
|
||||
github.com/rogpeppe/go-internal v1.16.0
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/rs/zerolog v1.35.1
|
||||
github.com/shamaton/msgpack/v2 v2.4.1
|
||||
github.com/shamaton/msgpack/v2 v2.4.2
|
||||
github.com/sirupsen/logrus v1.10.1
|
||||
github.com/spf13/afero v1.15.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
|
||||
@@ -1102,8 +1102,8 @@ github.com/sethvargo/go-diceware v0.6.0 h1:B3nhMhbBP7KwtTQ7hHRIOmv5FqeD8bJs77RFr
|
||||
github.com/sethvargo/go-diceware v0.6.0/go.mod h1:lHmdB0xuWaJ06KCraW6bztRT+71Dp+lsXQvborhhsBc=
|
||||
github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU=
|
||||
github.com/sethvargo/go-password v0.4.0/go.mod h1:PO3nYHwUpcHPR0F9woy7a4abZPvzRuqJr0GaeIYTm3k=
|
||||
github.com/shamaton/msgpack/v2 v2.4.1 h1:JtJ141QoQ3NqgPDsjq2v9VXlaON8SiQOwEaoNLEK/MQ=
|
||||
github.com/shamaton/msgpack/v2 v2.4.1/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
|
||||
github.com/shamaton/msgpack/v2 v2.4.2 h1:ukiqiwF8rIb8EG6hD8iPha3g85AC7EdCxFyobDj6oHk=
|
||||
github.com/shamaton/msgpack/v2 v2.4.2/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs=
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## [v2.4.2](https://github.com/shamaton/msgpack/compare/v2.4.1...v2.4.2) - 2026-08-30
|
||||
- fix: bound streaming decoder allocations against declared lengths (v2) by @shamaton in https://github.com/shamaton/msgpack/pull/115
|
||||
|
||||
## [v2.4.1](https://github.com/shamaton/msgpack/commits/v2.4.1) - 2026-05-14
|
||||
- fix: backport ext frame bounds validation to v2 by @shamaton in https://github.com/shamaton/msgpack/pull/66
|
||||
- Add tagpr configuration for v2 by @shamaton in https://github.com/shamaton/msgpack/pull/67
|
||||
- Format v2 branch files by @shamaton in https://github.com/shamaton/msgpack/pull/69
|
||||
+14
-7
@@ -39,8 +39,12 @@ func (d *decoder) asBinWithCode(code byte, k reflect.Kind) ([]byte, error) {
|
||||
if err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
l, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
// avoid common buffer reference
|
||||
return d.copySizeN(int(binary.BigEndian.Uint32(bs)))
|
||||
return d.copySizeN(l)
|
||||
}
|
||||
|
||||
return emptyBytes, d.errorTemplate(code, k)
|
||||
@@ -52,11 +56,14 @@ func (d *decoder) asBinStringWithCode(code byte, k reflect.Kind) (string, error)
|
||||
}
|
||||
|
||||
func (d *decoder) copySizeN(n int) ([]byte, error) {
|
||||
bs, err := d.readSizeN(n)
|
||||
if err != nil {
|
||||
return emptyBytes, err
|
||||
if n <= len(d.buf.Data) {
|
||||
bs, err := d.readSizeN(n)
|
||||
if err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
v := make([]byte, n)
|
||||
copy(v, bs)
|
||||
return v, nil
|
||||
}
|
||||
v := make([]byte, n)
|
||||
copy(v, bs)
|
||||
return v, nil
|
||||
return d.readSizeN(n)
|
||||
}
|
||||
+3
-2
@@ -145,8 +145,9 @@ func (d *decoder) decodeWithCode(code byte, rv reflect.Value) error {
|
||||
}
|
||||
|
||||
// create slice dynamically
|
||||
tmpSlice := reflect.MakeSlice(rv.Type(), l, l)
|
||||
tmpSlice := reflect.MakeSlice(rv.Type(), 0, initialSliceCap(l, rv.Type().Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
tmpSlice = reflect.Append(tmpSlice, reflect.Zero(rv.Type().Elem()))
|
||||
v := tmpSlice.Index(i)
|
||||
if v.Kind() == reflect.Struct {
|
||||
structCode, err := d.readSize1()
|
||||
@@ -259,7 +260,7 @@ func (d *decoder) decodeWithCode(code byte, rv reflect.Value) error {
|
||||
key := rv.Type().Key()
|
||||
value := rv.Type().Elem()
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.MakeMapWithSize(rv.Type(), l))
|
||||
rv.Set(reflect.MakeMapWithSize(rv.Type(), initialMapCapForType(l, key, value)))
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
k := reflect.New(key).Elem()
|
||||
|
||||
+4
-1
@@ -146,7 +146,10 @@ func (d *decoder) readIfExtType(code byte) (innerType int8, data []byte, err err
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
size := int(binary.BigEndian.Uint32(bs))
|
||||
size, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
typ, err := d.readSize1()
|
||||
if err != nil {
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxPreallocBytes bounds the initial allocation made from an
|
||||
// attacker-declared byte length (Bin/Str/Ext payloads) before any
|
||||
// payload byte has been read. Larger declared lengths are read
|
||||
// incrementally and grown only as bytes actually arrive.
|
||||
maxPreallocBytes = 256 << 10 // 256 KiB
|
||||
|
||||
// maxPreallocMapSize bounds the entry hint used to pre-size a map
|
||||
// from an attacker-declared pair count before any pair is decoded.
|
||||
maxPreallocMapSize = 8192
|
||||
)
|
||||
|
||||
// errDeclaredLengthTooLarge is returned when a declared 32-bit length cannot
|
||||
// be represented as a non-negative int (32-bit platforms).
|
||||
var errDeclaredLengthTooLarge = errors.New("declared length is too large")
|
||||
|
||||
// lengthFromUint32 converts a MessagePack-declared 32-bit length to int,
|
||||
// rejecting values that are not representable as a non-negative int.
|
||||
func lengthFromUint32(u uint32) (int, error) {
|
||||
if int64(u) > int64(math.MaxInt) {
|
||||
return 0, fmt.Errorf("%w: %d", errDeclaredLengthTooLarge, u)
|
||||
}
|
||||
return int(u), nil // #nosec G115 -- checked above
|
||||
}
|
||||
|
||||
// initialByteCap returns the capacity to reserve for a declared byte length
|
||||
// before its payload has been read.
|
||||
func initialByteCap(n int) int {
|
||||
if n < 1 {
|
||||
return 0
|
||||
}
|
||||
if n < maxPreallocBytes {
|
||||
return n
|
||||
}
|
||||
return maxPreallocBytes
|
||||
}
|
||||
|
||||
// initialSliceCap returns the element capacity to reserve for a declared
|
||||
// slice length, capped both by the declared count and by a byte budget so
|
||||
// large element types never over-commit.
|
||||
func initialSliceCap(l int, elemType reflect.Type) int {
|
||||
if l < 1 {
|
||||
return 0
|
||||
}
|
||||
elemSize := elemType.Size()
|
||||
if elemSize < 1 {
|
||||
elemSize = 1
|
||||
}
|
||||
budget := maxPreallocBytes / int(elemSize)
|
||||
if budget < 1 {
|
||||
budget = 1
|
||||
}
|
||||
if l < budget {
|
||||
return l
|
||||
}
|
||||
return budget
|
||||
}
|
||||
|
||||
// initialMapCap returns the entry hint used to pre-size a map from a
|
||||
// declared pair count.
|
||||
func initialMapCap(l int) int {
|
||||
if l < 1 {
|
||||
return 0
|
||||
}
|
||||
if l < maxPreallocMapSize {
|
||||
return l
|
||||
}
|
||||
return maxPreallocMapSize
|
||||
}
|
||||
|
||||
// initialMapCapForType is initialMapCap for maps created dynamically via
|
||||
// reflection, where the key/value types are only known at decode time and
|
||||
// can be arbitrarily large structs. It additionally bounds the hint by a
|
||||
// byte budget derived from the key/value sizes so a declared pair count
|
||||
// can't force a multi-megabyte allocation before any pair has been decoded.
|
||||
func initialMapCapForType(l int, key, value reflect.Type) int {
|
||||
if l < 1 {
|
||||
return 0
|
||||
}
|
||||
entrySize := key.Size() + value.Size()
|
||||
if entrySize < 1 {
|
||||
entrySize = 1
|
||||
}
|
||||
budget := maxPreallocBytes / int(entrySize)
|
||||
if budget < 1 {
|
||||
budget = 1
|
||||
}
|
||||
if l < budget {
|
||||
return initialMapCap(l)
|
||||
}
|
||||
return initialMapCap(budget)
|
||||
}
|
||||
+7
-3
@@ -15,6 +15,10 @@ func (d *decoder) asInterface(k reflect.Kind) (interface{}, error) {
|
||||
return d.asInterfaceWithCode(code, k)
|
||||
}
|
||||
|
||||
// typeInterfaceValue is the reflect.Type of interface{}; used to size the
|
||||
// element budget when pre-allocating []interface{}.
|
||||
var typeInterfaceValue = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
|
||||
func (d *decoder) asInterfaceWithCode(code byte, k reflect.Kind) (interface{}, error) {
|
||||
switch {
|
||||
case code == def.Nil:
|
||||
@@ -110,13 +114,13 @@ func (d *decoder) asInterfaceWithCode(code byte, k reflect.Kind) (interface{}, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := make([]interface{}, l)
|
||||
v := make([]interface{}, 0, initialSliceCap(l, typeInterfaceValue))
|
||||
for i := 0; i < l; i++ {
|
||||
vv, err := d.asInterface(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v[i] = vv
|
||||
v = append(v, vv)
|
||||
}
|
||||
return v, nil
|
||||
|
||||
@@ -126,7 +130,7 @@ func (d *decoder) asInterfaceWithCode(code byte, k reflect.Kind) (interface{}, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := make(map[interface{}]interface{}, l)
|
||||
v := make(map[interface{}]interface{}, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
keyCode, err := d.readSize1()
|
||||
if err != nil {
|
||||
|
||||
+39
-39
@@ -73,7 +73,7 @@ func (d *decoder) mapLength(code byte, k reflect.Kind) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(bs)), nil
|
||||
return lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
}
|
||||
|
||||
return 0, d.errorTemplate(code, k)
|
||||
@@ -87,7 +87,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
|
||||
switch t {
|
||||
case typeMapStringInt:
|
||||
m := make(map[string]int, l)
|
||||
m := make(map[string]int, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -103,7 +103,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringUint:
|
||||
m := make(map[string]uint, l)
|
||||
m := make(map[string]uint, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -119,7 +119,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringFloat32:
|
||||
m := make(map[string]float32, l)
|
||||
m := make(map[string]float32, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -135,7 +135,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringFloat64:
|
||||
m := make(map[string]float64, l)
|
||||
m := make(map[string]float64, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -151,7 +151,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringBool:
|
||||
m := make(map[string]bool, l)
|
||||
m := make(map[string]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -167,7 +167,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringString:
|
||||
m := make(map[string]string, l)
|
||||
m := make(map[string]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -183,7 +183,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringInt8:
|
||||
m := make(map[string]int8, l)
|
||||
m := make(map[string]int8, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -199,7 +199,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringInt16:
|
||||
m := make(map[string]int16, l)
|
||||
m := make(map[string]int16, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -215,7 +215,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringInt32:
|
||||
m := make(map[string]int32, l)
|
||||
m := make(map[string]int32, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -231,7 +231,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringInt64:
|
||||
m := make(map[string]int64, l)
|
||||
m := make(map[string]int64, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -247,7 +247,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringUint8:
|
||||
m := make(map[string]uint8, l)
|
||||
m := make(map[string]uint8, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -262,7 +262,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return true, nil
|
||||
case typeMapStringUint16:
|
||||
m := make(map[string]uint16, l)
|
||||
m := make(map[string]uint16, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -278,7 +278,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringUint32:
|
||||
m := make(map[string]uint32, l)
|
||||
m := make(map[string]uint32, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -294,7 +294,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapStringUint64:
|
||||
m := make(map[string]uint64, l)
|
||||
m := make(map[string]uint64, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asString(keyKind)
|
||||
if err != nil {
|
||||
@@ -310,7 +310,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapIntString:
|
||||
m := make(map[int]string, l)
|
||||
m := make(map[int]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -326,7 +326,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt8String:
|
||||
m := make(map[int8]string, l)
|
||||
m := make(map[int8]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -342,7 +342,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt16String:
|
||||
m := make(map[int16]string, l)
|
||||
m := make(map[int16]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -358,7 +358,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt32String:
|
||||
m := make(map[int32]string, l)
|
||||
m := make(map[int32]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -374,7 +374,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt64String:
|
||||
m := make(map[int64]string, l)
|
||||
m := make(map[int64]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -390,7 +390,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapIntBool:
|
||||
m := make(map[int]bool, l)
|
||||
m := make(map[int]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -406,7 +406,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt8Bool:
|
||||
m := make(map[int8]bool, l)
|
||||
m := make(map[int8]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -422,7 +422,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt16Bool:
|
||||
m := make(map[int16]bool, l)
|
||||
m := make(map[int16]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -438,7 +438,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt32Bool:
|
||||
m := make(map[int32]bool, l)
|
||||
m := make(map[int32]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -454,7 +454,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapInt64Bool:
|
||||
m := make(map[int64]bool, l)
|
||||
m := make(map[int64]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asInt(keyKind)
|
||||
if err != nil {
|
||||
@@ -470,7 +470,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUintString:
|
||||
m := make(map[uint]string, l)
|
||||
m := make(map[uint]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -486,7 +486,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint8String:
|
||||
m := make(map[uint8]string, l)
|
||||
m := make(map[uint8]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -502,7 +502,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint16String:
|
||||
m := make(map[uint16]string, l)
|
||||
m := make(map[uint16]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -518,7 +518,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint32String:
|
||||
m := make(map[uint32]string, l)
|
||||
m := make(map[uint32]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -534,7 +534,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint64String:
|
||||
m := make(map[uint64]string, l)
|
||||
m := make(map[uint64]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -550,7 +550,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUintBool:
|
||||
m := make(map[uint]bool, l)
|
||||
m := make(map[uint]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -566,7 +566,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint8Bool:
|
||||
m := make(map[uint8]bool, l)
|
||||
m := make(map[uint8]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -582,7 +582,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint16Bool:
|
||||
m := make(map[uint16]bool, l)
|
||||
m := make(map[uint16]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -598,7 +598,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint32Bool:
|
||||
m := make(map[uint32]bool, l)
|
||||
m := make(map[uint32]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -614,7 +614,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapUint64Bool:
|
||||
m := make(map[uint64]bool, l)
|
||||
m := make(map[uint64]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asUint(keyKind)
|
||||
if err != nil {
|
||||
@@ -630,7 +630,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapFloat32String:
|
||||
m := make(map[float32]string, l)
|
||||
m := make(map[float32]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asFloat32(keyKind)
|
||||
if err != nil {
|
||||
@@ -646,7 +646,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapFloat64String:
|
||||
m := make(map[float64]string, l)
|
||||
m := make(map[float64]string, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asFloat64(keyKind)
|
||||
if err != nil {
|
||||
@@ -662,7 +662,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapFloat32Bool:
|
||||
m := make(map[float32]bool, l)
|
||||
m := make(map[float32]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asFloat32(keyKind)
|
||||
if err != nil {
|
||||
@@ -678,7 +678,7 @@ func (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {
|
||||
return true, nil
|
||||
|
||||
case typeMapFloat64Bool:
|
||||
m := make(map[float64]bool, l)
|
||||
m := make(map[float64]bool, initialMapCap(l))
|
||||
for i := 0; i < l; i++ {
|
||||
k, err := d.asFloat64(keyKind)
|
||||
if err != nil {
|
||||
|
||||
+84
-13
@@ -1,50 +1,121 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// readFull fills b completely from d.r. The common case, where the
|
||||
// underlying reader already returns the full amount requested, completes
|
||||
// with a single Read call. Readers that legitimately return fewer bytes than
|
||||
// requested (n > 0, err == nil) fall back to looping over the remainder.
|
||||
// Unlike io.ReadFull, an EOF reached only after some bytes were already
|
||||
// consumed by this call is still reported as io.EOF, not io.ErrUnexpectedEOF,
|
||||
// preserving this package's historical error values.
|
||||
func (d *decoder) readFull(b []byte) error {
|
||||
for len(b) > 0 {
|
||||
n, err := d.r.Read(b)
|
||||
if n < 0 || n > len(b) {
|
||||
return io.ErrNoProgress
|
||||
}
|
||||
b = b[n:]
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
return io.ErrNoProgress
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize1() (byte, error) {
|
||||
if _, err := d.r.Read(d.buf.B1); err != nil {
|
||||
if err := d.readFull(d.buf.B1); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return d.buf.B1[0], nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize2() ([]byte, error) {
|
||||
if _, err := d.r.Read(d.buf.B2); err != nil {
|
||||
if err := d.readFull(d.buf.B2); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return d.buf.B2, nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize4() ([]byte, error) {
|
||||
if _, err := d.r.Read(d.buf.B4); err != nil {
|
||||
if err := d.readFull(d.buf.B4); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return d.buf.B4, nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize8() ([]byte, error) {
|
||||
if _, err := d.r.Read(d.buf.B8); err != nil {
|
||||
if err := d.readFull(d.buf.B8); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return d.buf.B8, nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize16() ([]byte, error) {
|
||||
if _, err := d.r.Read(d.buf.B16); err != nil {
|
||||
if err := d.readFull(d.buf.B16); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return d.buf.B16, nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSizeN(n int) ([]byte, error) {
|
||||
var b []byte
|
||||
if n <= len(d.buf.Data) {
|
||||
b = d.buf.Data[:n]
|
||||
} else {
|
||||
d.buf.Data = append(d.buf.Data, make([]byte, n-len(d.buf.Data))...)
|
||||
b = d.buf.Data
|
||||
if n < 0 {
|
||||
return emptyBytes, fmt.Errorf("invalid declared byte length %d", n)
|
||||
}
|
||||
if _, err := d.r.Read(b); err != nil {
|
||||
return emptyBytes, err
|
||||
if n <= len(d.buf.Data) {
|
||||
b := d.buf.Data[:n]
|
||||
if err := d.readFull(b); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
if n <= maxPreallocBytes {
|
||||
b := make([]byte, n)
|
||||
if err := d.readFull(b); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
return d.readSizeNGrowing(n)
|
||||
}
|
||||
|
||||
// readSizeNGrowing reads a declared byte length that exceeds maxPreallocBytes.
|
||||
// Rather than accumulating fixed-size chunks with append (which pays for a
|
||||
// separate chunk buffer plus a copy into the growing slice on every
|
||||
// iteration), it doubles the output slice's own capacity and reads directly
|
||||
// into the newly available space, halving the bytes copied for large,
|
||||
// legitimate payloads.
|
||||
func (d *decoder) readSizeNGrowing(n int) ([]byte, error) {
|
||||
b := make([]byte, 0, initialByteCap(n))
|
||||
for len(b) < n {
|
||||
if len(b) == cap(b) {
|
||||
newCap := n
|
||||
if remaining := n - cap(b); remaining > cap(b) {
|
||||
newCap = cap(b) * 2
|
||||
}
|
||||
grown := make([]byte, len(b), newCap)
|
||||
copy(grown, b)
|
||||
b = grown
|
||||
}
|
||||
|
||||
start := len(b)
|
||||
end := cap(b)
|
||||
if n < end {
|
||||
end = n
|
||||
}
|
||||
b = b[:end]
|
||||
if err := d.readFull(b[start:end]); err != nil {
|
||||
return emptyBytes, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
+43
-43
@@ -47,7 +47,7 @@ func (d *decoder) sliceLength(code byte, k reflect.Kind) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(bs)), nil
|
||||
return lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
}
|
||||
return 0, d.errorTemplate(code, k)
|
||||
}
|
||||
@@ -58,169 +58,169 @@ func (d *decoder) asFixedSlice(rv reflect.Value, l int) (bool, error) {
|
||||
|
||||
switch t {
|
||||
case typeIntSlice:
|
||||
sli := make([]int, l)
|
||||
for i := range sli {
|
||||
sli := make([]int, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asInt(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = int(v)
|
||||
sli = append(sli, int(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeUintSlice:
|
||||
sli := make([]uint, l)
|
||||
for i := range sli {
|
||||
sli := make([]uint, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asUint(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = uint(v)
|
||||
sli = append(sli, uint(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeStringSlice:
|
||||
sli := make([]string, l)
|
||||
for i := range sli {
|
||||
sli := make([]string, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asString(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeBoolSlice:
|
||||
sli := make([]bool, l)
|
||||
for i := range sli {
|
||||
sli := make([]bool, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asBool(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeFloat32Slice:
|
||||
sli := make([]float32, l)
|
||||
for i := range sli {
|
||||
sli := make([]float32, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asFloat32(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeFloat64Slice:
|
||||
sli := make([]float64, l)
|
||||
for i := range sli {
|
||||
sli := make([]float64, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asFloat64(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeInt8Slice:
|
||||
sli := make([]int8, l)
|
||||
for i := range sli {
|
||||
sli := make([]int8, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asInt(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = int8(v)
|
||||
sli = append(sli, int8(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeInt16Slice:
|
||||
sli := make([]int16, l)
|
||||
for i := range sli {
|
||||
sli := make([]int16, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asInt(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = int16(v)
|
||||
sli = append(sli, int16(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeInt32Slice:
|
||||
sli := make([]int32, l)
|
||||
for i := range sli {
|
||||
sli := make([]int32, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asInt(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = int32(v)
|
||||
sli = append(sli, int32(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeInt64Slice:
|
||||
sli := make([]int64, l)
|
||||
for i := range sli {
|
||||
sli := make([]int64, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asInt(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeUint8Slice:
|
||||
sli := make([]uint8, l)
|
||||
for i := range sli {
|
||||
sli := make([]uint8, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asUint(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = uint8(v)
|
||||
sli = append(sli, uint8(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeUint16Slice:
|
||||
sli := make([]uint16, l)
|
||||
for i := range sli {
|
||||
sli := make([]uint16, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asUint(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = uint16(v)
|
||||
sli = append(sli, uint16(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeUint32Slice:
|
||||
sli := make([]uint32, l)
|
||||
for i := range sli {
|
||||
sli := make([]uint32, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asUint(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = uint32(v)
|
||||
sli = append(sli, uint32(v))
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
case typeUint64Slice:
|
||||
sli := make([]uint64, l)
|
||||
for i := range sli {
|
||||
sli := make([]uint64, 0, initialSliceCap(l, t.Elem()))
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := d.asUint(k)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
sli[i] = v
|
||||
sli = append(sli, v)
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return true, nil
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ func (d *decoder) stringByteLength(code byte, k reflect.Kind) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(b)), nil
|
||||
return lengthFromUint32(binary.BigEndian.Uint32(b))
|
||||
} else if code == def.Nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
+28
-5
@@ -2,6 +2,7 @@ package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
@@ -199,7 +200,11 @@ func (d *decoder) jumpOffset() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = d.readSizeN(int(binary.BigEndian.Uint32(bs)))
|
||||
l, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = d.readSizeN(l)
|
||||
return err
|
||||
|
||||
case d.isFixSlice(code):
|
||||
@@ -225,7 +230,10 @@ func (d *decoder) jumpOffset() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint32(bs))
|
||||
l, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
if err = d.jumpOffset(); err != nil {
|
||||
return err
|
||||
@@ -255,8 +263,16 @@ func (d *decoder) jumpOffset() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint32(bs))
|
||||
for i := 0; i < l*2; i++ {
|
||||
l, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// skip key and value separately: multiplying the pair count would
|
||||
// overflow on 32-bit platforms
|
||||
for i := 0; i < l; i++ {
|
||||
if err = d.jumpOffset(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = d.jumpOffset(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -297,7 +313,14 @@ func (d *decoder) jumpOffset() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = d.readSizeN(def.Byte1 + int(binary.BigEndian.Uint32(bs)))
|
||||
l, err := lengthFromUint32(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if l >= math.MaxInt { // Byte1 + l must not overflow
|
||||
return errDeclaredLengthTooLarge
|
||||
}
|
||||
_, err = d.readSizeN(def.Byte1 + l)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
Vendored
+1
-1
@@ -1961,7 +1961,7 @@ github.com/sethvargo/go-diceware/diceware
|
||||
# github.com/sethvargo/go-password v0.4.0
|
||||
## explicit; go 1.25
|
||||
github.com/sethvargo/go-password/password
|
||||
# github.com/shamaton/msgpack/v2 v2.4.1
|
||||
# github.com/shamaton/msgpack/v2 v2.4.2
|
||||
## explicit; go 1.20
|
||||
github.com/shamaton/msgpack/v2
|
||||
github.com/shamaton/msgpack/v2/def
|
||||
|
||||
Reference in new issue
Block a user