Skip to content

Commit c485170

Browse files
benluddyk8s-publishing-bot
authored andcommitted
Error on custom (un)marshalers without a CBOR implementation.
When CBOR marshaling or unmarshaling a type that implements any of TextMarshaler, TextUnmarshaler, json.Marshaler, or json.Unmarshaler, without also implementing the corresponding CBOR interface, the proposed behavior is to automatically use the available interface method by transcoding between CBOR and JSON or text. As a safety measure, values of these types will be rejected by the CBOR serializer until that is implemented. Kubernetes-commit: 40c283908358c7af82f14ba3ea77960d5caf42d9
1 parent 4524748 commit c485170

File tree

4 files changed

+664
-4
lines changed

4 files changed

+664
-4
lines changed

pkg/runtime/serializer/cbor/cbor.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,19 @@ func (s *serializer) Encode(obj runtime.Object, w io.Writer) error {
118118
}
119119

120120
func (s *serializer) encode(mode modes.EncMode, obj runtime.Object, w io.Writer) error {
121-
if _, err := w.Write(selfDescribedCBOR); err != nil {
122-
return err
123-
}
124-
125121
var v interface{} = obj
126122
if u, ok := obj.(runtime.Unstructured); ok {
127123
v = u.UnstructuredContent()
128124
}
129125

126+
if err := modes.RejectCustomMarshalers(v); err != nil {
127+
return err
128+
}
129+
130+
if _, err := w.Write(selfDescribedCBOR); err != nil {
131+
return err
132+
}
133+
130134
return mode.MarshalTo(v, w)
131135
}
132136

@@ -237,6 +241,8 @@ func (s *serializer) unmarshal(data []byte, into interface{}) (strict, lax error
237241
}
238242
}()
239243
into = &content
244+
} else if err := modes.RejectCustomMarshalers(into); err != nil {
245+
return nil, err
240246
}
241247

242248
if !s.options.strict {

pkg/runtime/serializer/cbor/cbor_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,42 @@ func TestEncode(t *testing.T) {
207207
}
208208
},
209209
},
210+
{
211+
name: "unsupported marshaler",
212+
in: &textMarshalerObject{},
213+
assertOnWriter: func() (io.Writer, func(*testing.T)) {
214+
var b bytes.Buffer
215+
return &b, func(t *testing.T) {
216+
if b.Len() != 0 {
217+
t.Errorf("expected no bytes to be written, got %d", b.Len())
218+
}
219+
}
220+
},
221+
assertOnError: func(t *testing.T, err error) {
222+
if want := "unable to serialize *cbor.textMarshalerObject: *cbor.textMarshalerObject implements encoding.TextMarshaler without corresponding cbor interface"; err == nil || err.Error() != want {
223+
t.Errorf("expected error %q, got: %v", want, err)
224+
}
225+
},
226+
},
227+
{
228+
name: "unsupported marshaler within unstructured content",
229+
in: &unstructured.Unstructured{
230+
Object: map[string]interface{}{"": textMarshalerObject{}},
231+
},
232+
assertOnWriter: func() (io.Writer, func(*testing.T)) {
233+
var b bytes.Buffer
234+
return &b, func(t *testing.T) {
235+
if b.Len() != 0 {
236+
t.Errorf("expected no bytes to be written, got %d", b.Len())
237+
}
238+
}
239+
},
240+
assertOnError: func(t *testing.T, err error) {
241+
if want := "unable to serialize map[string]interface {}: cbor.textMarshalerObject implements encoding.TextMarshaler without corresponding cbor interface"; err == nil || err.Error() != want {
242+
t.Errorf("expected error %q, got: %v", want, err)
243+
}
244+
},
245+
},
210246
} {
211247
t.Run(tc.name, func(t *testing.T) {
212248
s := NewSerializer(nil, nil)
@@ -625,6 +661,19 @@ func TestDecode(t *testing.T) {
625661
}
626662
},
627663
},
664+
{
665+
name: "into unsupported marshaler",
666+
data: []byte("\xa0"),
667+
into: &textMarshalerObject{},
668+
metaFactory: stubMetaFactory{gvk: &schema.GroupVersionKind{}},
669+
typer: stubTyper{gvks: []schema.GroupVersionKind{{Version: "v", Kind: "k"}}},
670+
expectedGVK: &schema.GroupVersionKind{Version: "v", Kind: "k"},
671+
assertOnError: func(t *testing.T, err error) {
672+
if want := "unable to serialize *cbor.textMarshalerObject: *cbor.textMarshalerObject implements encoding.TextMarshaler without corresponding cbor interface"; err == nil || err.Error() != want {
673+
t.Errorf("expected error %q, got: %v", want, err)
674+
}
675+
},
676+
},
628677
} {
629678
t.Run(tc.name, func(t *testing.T) {
630679
s := newSerializer(tc.metaFactory, tc.creater, tc.typer, tc.options...)
@@ -643,6 +692,20 @@ func TestDecode(t *testing.T) {
643692
}
644693
}
645694

695+
type textMarshalerObject struct{}
696+
697+
func (p textMarshalerObject) GetObjectKind() schema.ObjectKind {
698+
return schema.EmptyObjectKind
699+
}
700+
701+
func (textMarshalerObject) DeepCopyObject() runtime.Object {
702+
panic("unimplemented")
703+
}
704+
705+
func (textMarshalerObject) MarshalText() ([]byte, error) {
706+
return nil, nil
707+
}
708+
646709
func TestMetaFactoryInterpret(t *testing.T) {
647710
mf := &defaultMetaFactory{}
648711
_, err := mf.Interpret(nil)

0 commit comments

Comments
 (0)