mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 13:45:06 +00:00
Merge pull request #125420 from benluddy/cbor-bignum-bigint
KEP-4222: Reject math/big.Int on encode and bignum tags on decode for CBOR.
This commit is contained in:
@@ -121,7 +121,6 @@ func TestAppendixA(t *testing.T) {
|
||||
{
|
||||
example: hex("c249010000000000000000"),
|
||||
reject: "decoding tagged positive bigint value to interface{} can't reproduce this value without losing distinction between float and integer",
|
||||
fixme: "decoding bigint to interface{} must not produce math/big.Int",
|
||||
},
|
||||
{
|
||||
example: hex("3bffffffffffffffff"),
|
||||
@@ -130,7 +129,6 @@ func TestAppendixA(t *testing.T) {
|
||||
{
|
||||
example: hex("c349010000000000000000"),
|
||||
reject: "-18446744073709551617 overflows int64 and falling back to float64 (as with JSON) loses distinction between float and integer",
|
||||
fixme: "decoding negative bigint to interface{} must not produce math/big.Int",
|
||||
},
|
||||
{
|
||||
example: hex("20"),
|
||||
|
@@ -96,6 +96,10 @@ var Decode cbor.DecMode = func() cbor.DecMode {
|
||||
// representation (RFC 8259 Section 6).
|
||||
NaN: cbor.NaNDecodeForbidden,
|
||||
Inf: cbor.InfDecodeForbidden,
|
||||
|
||||
// Reject the arbitrary-precision integer tags because they can't be faithfully
|
||||
// roundtripped through the allowable Unstructured types.
|
||||
BignumTag: cbor.BignumTagForbidden,
|
||||
}.DecMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@@ -741,13 +741,11 @@ func TestDecode(t *testing.T) {
|
||||
{
|
||||
name: "rejected",
|
||||
in: hex("c249010000000000000000"), // 2(18446744073709551616)
|
||||
fixme: "decoding cbor data tagged with 2 produces big.Int instead of rejecting",
|
||||
assertOnError: func(t *testing.T, e error) {
|
||||
// TODO: Once this can pass, make the assertion stronger.
|
||||
if e == nil {
|
||||
t.Error("expected non-nil error")
|
||||
assertOnError: assertOnConcreteError(func(t *testing.T, e *cbor.UnacceptableDataItemError) {
|
||||
if diff := cmp.Diff(&cbor.UnacceptableDataItemError{CBORType: "tag", Message: "bignum"}, e); diff != "" {
|
||||
t.Errorf("unexpected error diff:\n%s", diff)
|
||||
}
|
||||
},
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -755,13 +753,11 @@ func TestDecode(t *testing.T) {
|
||||
{
|
||||
name: "rejected",
|
||||
in: hex("c349010000000000000000"), // 3(-18446744073709551617)
|
||||
fixme: "decoding cbor data tagged with 3 produces big.Int instead of rejecting",
|
||||
assertOnError: func(t *testing.T, e error) {
|
||||
// TODO: Once this can pass, make the assertion stronger.
|
||||
if e == nil {
|
||||
t.Error("expected non-nil error")
|
||||
assertOnError: assertOnConcreteError(func(t *testing.T, e *cbor.UnacceptableDataItemError) {
|
||||
if diff := cmp.Diff(&cbor.UnacceptableDataItemError{CBORType: "tag", Message: "bignum"}, e); diff != "" {
|
||||
t.Errorf("unexpected error diff:\n%s", diff)
|
||||
}
|
||||
},
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
|
@@ -37,11 +37,10 @@ var Encode cbor.EncMode = func() cbor.EncMode {
|
||||
NaNConvert: cbor.NaNConvertReject,
|
||||
InfConvert: cbor.InfConvertReject,
|
||||
|
||||
// Prefer encoding math/big.Int to one of the 64-bit integer types if it fits. When
|
||||
// later decoded into Unstructured, the set of allowable concrete numeric types is
|
||||
// limited to int64 and float64, so the distinction between big integer and integer
|
||||
// can't be preserved.
|
||||
BigIntConvert: cbor.BigIntConvertShortest,
|
||||
// Error on attempt to encode math/big.Int values, which can't be faithfully
|
||||
// roundtripped through Unstructured in general (the dynamic numeric types allowed
|
||||
// in Unstructured are limited to float64 and int64).
|
||||
BigIntConvert: cbor.BigIntConvertReject,
|
||||
|
||||
// MarshalJSON for time.Time writes RFC3339 with nanos.
|
||||
Time: cbor.TimeRFC3339Nano,
|
||||
|
@@ -18,6 +18,8 @@ package modes_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
@@ -53,6 +55,15 @@ func TestEncode(t *testing.T) {
|
||||
want: []byte{0xa1, 0x41, 0x41, 0x02}, // {"A": 2}
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "math/big.Int values are rejected",
|
||||
in: big.NewInt(1),
|
||||
assertOnError: assertOnConcreteError(func(t *testing.T, got *cbor.UnsupportedTypeError) {
|
||||
if want := (&cbor.UnsupportedTypeError{Type: reflect.TypeFor[big.Int]()}); *want != *got {
|
||||
t.Errorf("unexpected error, got %#v (%q), want %#v (%q)", got, got.Error(), want, want.Error())
|
||||
}
|
||||
}),
|
||||
},
|
||||
} {
|
||||
encModes := tc.modes
|
||||
if len(encModes) == 0 {
|
||||
@@ -68,7 +79,7 @@ func TestEncode(t *testing.T) {
|
||||
t.Run(fmt.Sprintf("mode=%s/%s", modeName, tc.name), func(t *testing.T) {
|
||||
out, err := encMode.Marshal(tc.in)
|
||||
tc.assertOnError(t, err)
|
||||
if diff := cmp.Diff(tc.want, out); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, out, cmp.Comparer(func(a, b reflect.Type) bool { return a == b })); diff != "" {
|
||||
t.Errorf("unexpected output:\n%s", diff)
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user