diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal.go index 12cc2f6f2c9..321bec385c5 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal.go @@ -130,7 +130,7 @@ func (s JSON) MarshalJSON() ([]byte, error) { func (s *JSON) UnmarshalJSON(data []byte) error { if len(data) > 0 && !bytes.Equal(data, nullLiteral) { - s.Raw = data + s.Raw = append(s.Raw[0:0], data...) } return nil } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal_test.go index dae08bd5e3b..4ddab379c5d 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/marshal_test.go @@ -148,3 +148,24 @@ func TestJSONSchemaPropsOrArrayMarshalJSON(t *testing.T) { } } } + +func TestJSONUnderlyingArrayReuse(t *testing.T) { + const want = `{"foo":"bar"}` + + b := []byte(want) + + var s JSON + if err := s.UnmarshalJSON(b); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Underlying array is modified. + copy(b[2:5], "bar") + copy(b[8:11], "foo") + + // If UnmarshalJSON copied the bytes of its argument, then it should not have been affected + // by the mutation. + if got := string(s.Raw); got != want { + t.Errorf("unexpected mutation, got %s want %s", got, want) + } +} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal.go index 44941d82eff..43b90387872 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal.go @@ -130,7 +130,7 @@ func (s JSON) MarshalJSON() ([]byte, error) { func (s *JSON) UnmarshalJSON(data []byte) error { if len(data) > 0 && !bytes.Equal(data, nullLiteral) { - s.Raw = data + s.Raw = append(s.Raw[0:0], data...) } return nil } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal_test.go index 99065ff95ad..c45e12f9993 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/marshal_test.go @@ -148,3 +148,24 @@ func TestJSONSchemaPropsOrArrayMarshalJSON(t *testing.T) { } } } + +func TestJSONUnderlyingArrayReuse(t *testing.T) { + const want = `{"foo":"bar"}` + + b := []byte(want) + + var s JSON + if err := s.UnmarshalJSON(b); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Underlying array is modified. + copy(b[2:5], "bar") + copy(b[8:11], "foo") + + // If UnmarshalJSON copied the bytes of its argument, then it should not have been affected + // by the mutation. + if got := string(s.Raw); got != want { + t.Errorf("unexpected mutation, got %s want %s", got, want) + } +}