mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Merge pull request #128462 from benluddy/cbor-direct-custom-marshalers
KEP-4222: Reject custom marshalers from direct CBOR Marshal and Unmarshal.
This commit is contained in:
commit
f0ff870871
@ -23,14 +23,39 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Marshal serializes a value to CBOR. If there is more than one way to encode the value, it will
|
||||||
|
// make the same choice as the CBOR implementation of runtime.Serializer.
|
||||||
|
//
|
||||||
|
// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
|
||||||
|
// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
|
||||||
|
// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
|
||||||
|
// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
|
||||||
|
// removed in favor of automatic transcoding to CBOR.
|
||||||
func Marshal(src interface{}) ([]byte, error) {
|
func Marshal(src interface{}) ([]byte, error) {
|
||||||
|
if err := modes.RejectCustomMarshalers(src); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return modes.Encode.Marshal(src)
|
return modes.Encode.Marshal(src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal deserializes from CBOR into an addressable value. If there is more than one way to
|
||||||
|
// unmarshal a value, it will make the same choice as the CBOR implementation of runtime.Serializer.
|
||||||
|
//
|
||||||
|
// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
|
||||||
|
// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
|
||||||
|
// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
|
||||||
|
// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
|
||||||
|
// removed in favor of automatic transcoding to CBOR.
|
||||||
func Unmarshal(src []byte, dst interface{}) error {
|
func Unmarshal(src []byte, dst interface{}) error {
|
||||||
|
if err := modes.RejectCustomMarshalers(dst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return modes.Decode.Unmarshal(src, dst)
|
return modes.Decode.Unmarshal(src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Diagnose accepts well-formed CBOR bytes and returns a string representing the same data item in
|
||||||
|
// human-readable diagnostic notation (RFC 8949 Section 8). The diagnostic notation is not meant to
|
||||||
|
// be parsed.
|
||||||
func Diagnose(src []byte) (string, error) {
|
func Diagnose(src []byte) (string, error) {
|
||||||
return modes.Diagnostic.Diagnose(src)
|
return modes.Diagnostic.Diagnose(src)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2024 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package direct_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ json.Marshaler = CustomJSONMarshaler{}
|
||||||
|
|
||||||
|
type CustomJSONMarshaler struct{}
|
||||||
|
|
||||||
|
func (CustomJSONMarshaler) MarshalJSON() ([]byte, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ json.Unmarshaler = CustomJSONUnmarshaler{}
|
||||||
|
|
||||||
|
type CustomJSONUnmarshaler struct{}
|
||||||
|
|
||||||
|
func (CustomJSONUnmarshaler) UnmarshalJSON([]byte) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.TextMarshaler = CustomTextMarshaler{}
|
||||||
|
|
||||||
|
type CustomTextMarshaler struct{}
|
||||||
|
|
||||||
|
func (CustomTextMarshaler) MarshalText() ([]byte, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.TextUnmarshaler = CustomTextUnmarshaler{}
|
||||||
|
|
||||||
|
type CustomTextUnmarshaler struct{}
|
||||||
|
|
||||||
|
func (CustomTextUnmarshaler) UnmarshalText([]byte) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRejectsCustom(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
value interface{}
|
||||||
|
iface reflect.Type
|
||||||
|
}{
|
||||||
|
{value: CustomJSONMarshaler{}, iface: reflect.TypeFor[json.Marshaler]()},
|
||||||
|
{value: CustomJSONUnmarshaler{}, iface: reflect.TypeFor[json.Unmarshaler]()},
|
||||||
|
{value: CustomTextMarshaler{}, iface: reflect.TypeFor[encoding.TextMarshaler]()},
|
||||||
|
{value: CustomTextUnmarshaler{}, iface: reflect.TypeFor[encoding.TextUnmarshaler]()},
|
||||||
|
} {
|
||||||
|
t.Run(fmt.Sprintf("%T", tc.value), func(t *testing.T) {
|
||||||
|
want := fmt.Sprintf("unable to serialize %T: %T implements %s without corresponding cbor interface", tc.value, tc.value, tc.iface.String())
|
||||||
|
if _, err := direct.Marshal(tc.value); err == nil || err.Error() != want {
|
||||||
|
t.Errorf("want error: %q, got: %v", want, err)
|
||||||
|
}
|
||||||
|
if err := direct.Unmarshal(nil, tc.value); err == nil || err.Error() != want {
|
||||||
|
t.Errorf("want error: %q, got: %v", want, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user