mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rebase: update kubernetes in api folder
updating the kubernetes to 1.31.0 in the api folder. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
2c0e65b828
commit
63c4c05b35
100
api/vendor/k8s.io/apimachinery/pkg/runtime/extension.go
generated
vendored
100
api/vendor/k8s.io/apimachinery/pkg/runtime/extension.go
generated
vendored
@ -18,16 +18,77 @@ package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
)
|
||||
|
||||
// RawExtension intentionally avoids implementing value.UnstructuredConverter for now because the
|
||||
// signature of ToUnstructured does not allow returning an error value in cases where the conversion
|
||||
// is not possible (content type is unrecognized or bytes don't match content type).
|
||||
func rawToUnstructured(raw []byte, contentType string) (interface{}, error) {
|
||||
switch contentType {
|
||||
case ContentTypeJSON:
|
||||
var u interface{}
|
||||
if err := json.Unmarshal(raw, &u); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse RawExtension bytes as JSON: %w", err)
|
||||
}
|
||||
return u, nil
|
||||
case ContentTypeCBOR:
|
||||
var u interface{}
|
||||
if err := cbor.Unmarshal(raw, &u); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse RawExtension bytes as CBOR: %w", err)
|
||||
}
|
||||
return u, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot convert RawExtension with unrecognized content type to unstructured")
|
||||
}
|
||||
}
|
||||
|
||||
func (re RawExtension) guessContentType() string {
|
||||
switch {
|
||||
case bytes.HasPrefix(re.Raw, cborSelfDescribed):
|
||||
return ContentTypeCBOR
|
||||
case len(re.Raw) > 0:
|
||||
switch re.Raw[0] {
|
||||
case '\t', '\r', '\n', ' ', '{', '[', 'n', 't', 'f', '"', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
// Prefixes for the four whitespace characters, objects, arrays, strings, numbers, true, false, and null.
|
||||
return ContentTypeJSON
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (re *RawExtension) UnmarshalJSON(in []byte) error {
|
||||
if re == nil {
|
||||
return errors.New("runtime.RawExtension: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
if !bytes.Equal(in, []byte("null")) {
|
||||
re.Raw = append(re.Raw[0:0], in...)
|
||||
if bytes.Equal(in, []byte("null")) {
|
||||
return nil
|
||||
}
|
||||
re.Raw = append(re.Raw[0:0], in...)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
cborNull = []byte{0xf6}
|
||||
cborSelfDescribed = []byte{0xd9, 0xd9, 0xf7}
|
||||
)
|
||||
|
||||
func (re *RawExtension) UnmarshalCBOR(in []byte) error {
|
||||
if re == nil {
|
||||
return errors.New("runtime.RawExtension: UnmarshalCBOR on nil pointer")
|
||||
}
|
||||
if !bytes.Equal(in, cborNull) {
|
||||
if !bytes.HasPrefix(in, cborSelfDescribed) {
|
||||
// The self-described CBOR tag doesn't change the interpretation of the data
|
||||
// item it encloses, but it is useful as a magic number. Its encoding is
|
||||
// also what is used to implement the CBOR RecognizingDecoder.
|
||||
re.Raw = append(re.Raw[:0], cborSelfDescribed...)
|
||||
}
|
||||
re.Raw = append(re.Raw, in...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -46,6 +107,35 @@ func (re RawExtension) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
return []byte("null"), nil
|
||||
}
|
||||
// TODO: Check whether ContentType is actually JSON before returning it.
|
||||
return re.Raw, nil
|
||||
|
||||
contentType := re.guessContentType()
|
||||
if contentType == ContentTypeJSON {
|
||||
return re.Raw, nil
|
||||
}
|
||||
|
||||
u, err := rawToUnstructured(re.Raw, contentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(u)
|
||||
}
|
||||
|
||||
func (re RawExtension) MarshalCBOR() ([]byte, error) {
|
||||
if re.Raw == nil {
|
||||
if re.Object != nil {
|
||||
return cbor.Marshal(re.Object)
|
||||
}
|
||||
return cbor.Marshal(nil)
|
||||
}
|
||||
|
||||
contentType := re.guessContentType()
|
||||
if contentType == ContentTypeCBOR {
|
||||
return re.Raw, nil
|
||||
}
|
||||
|
||||
u, err := rawToUnstructured(re.Raw, contentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cbor.Marshal(u)
|
||||
}
|
||||
|
36
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
generated
vendored
Normal file
36
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
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 provides functions for marshaling and unmarshaling between arbitrary Go values and
|
||||
// CBOR data, with behavior that is compatible with that of the CBOR serializer. In particular,
|
||||
// types that implement cbor.Marshaler and cbor.Unmarshaler should use these functions.
|
||||
package direct
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
||||
)
|
||||
|
||||
func Marshal(src interface{}) ([]byte, error) {
|
||||
return modes.Encode.Marshal(src)
|
||||
}
|
||||
|
||||
func Unmarshal(src []byte, dst interface{}) error {
|
||||
return modes.Decode.Unmarshal(src, dst)
|
||||
}
|
||||
|
||||
func Diagnose(src []byte) (string, error) {
|
||||
return modes.Diagnostic.Diagnose(src)
|
||||
}
|
65
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/buffers.go
generated
vendored
Normal file
65
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/buffers.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 modes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var buffers = BufferProvider{p: new(sync.Pool)}
|
||||
|
||||
type buffer struct {
|
||||
bytes.Buffer
|
||||
}
|
||||
|
||||
type pool interface {
|
||||
Get() interface{}
|
||||
Put(interface{})
|
||||
}
|
||||
|
||||
type BufferProvider struct {
|
||||
p pool
|
||||
}
|
||||
|
||||
func (b *BufferProvider) Get() *buffer {
|
||||
if buf, ok := b.p.Get().(*buffer); ok {
|
||||
return buf
|
||||
}
|
||||
return &buffer{}
|
||||
}
|
||||
|
||||
func (b *BufferProvider) Put(buf *buffer) {
|
||||
if buf.Cap() > 3*1024*1024 /* Default MaxRequestBodyBytes */ {
|
||||
// Objects in a sync.Pool are assumed to be fungible. This is not a good assumption
|
||||
// for pools of *bytes.Buffer because a *bytes.Buffer's underlying array grows as
|
||||
// needed to accommodate writes. In Kubernetes, apiservers tend to encode "small"
|
||||
// objects very frequently and much larger objects (especially large lists) only
|
||||
// occasionally. Under steady load, pooled buffers tend to be borrowed frequently
|
||||
// enough to prevent them from being released. Over time, each buffer is used to
|
||||
// encode a large object and its capacity increases accordingly. The result is that
|
||||
// practically all buffers in the pool retain much more capacity than needed to
|
||||
// encode most objects.
|
||||
|
||||
// As a basic mitigation for the worst case, buffers with more capacity than the
|
||||
// default max request body size are never returned to the pool.
|
||||
// TODO: Optimize for higher buffer utilization.
|
||||
return
|
||||
}
|
||||
buf.Reset()
|
||||
b.p.Put(buf)
|
||||
}
|
422
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/custom.go
generated
vendored
Normal file
422
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/custom.go
generated
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
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 modes
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
// Returns a non-nil error if and only if the argument's type (or one of its component types, for
|
||||
// composite types) implements json.Marshaler or encoding.TextMarshaler without also implementing
|
||||
// cbor.Marshaler and likewise for the respective Unmarshaler interfaces.
|
||||
//
|
||||
// This is a temporary, graduation-blocking restriction and will be removed in favor of automatic
|
||||
// transcoding between CBOR and JSON/text for these types. This restriction allows CBOR to be
|
||||
// exercised for in-tree and unstructured types while mitigating the risk of mangling out-of-tree
|
||||
// types in client programs.
|
||||
func RejectCustomMarshalers(v interface{}) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
rv := reflect.ValueOf(v)
|
||||
if err := marshalerCache.getChecker(rv.Type()).check(rv, maxDepth); err != nil {
|
||||
return fmt.Errorf("unable to serialize %T: %w", v, err)
|
||||
}
|
||||
if err := unmarshalerCache.getChecker(rv.Type()).check(rv, maxDepth); err != nil {
|
||||
return fmt.Errorf("unable to serialize %T: %w", v, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Recursion depth is limited as a basic mitigation against cyclic objects. Objects created by the
|
||||
// decoder shouldn't be able to contain cycles, but practically any object can be passed to the
|
||||
// encoder.
|
||||
var errMaxDepthExceeded = errors.New("object depth exceeds limit (possible cycle?)")
|
||||
|
||||
// The JSON encoder begins detecting cycles after depth 1000. Use a generous limit here, knowing
|
||||
// that it can might deeply nested acyclic objects. The limit will be removed along with the rest of
|
||||
// this mechanism.
|
||||
const maxDepth = 2048
|
||||
|
||||
var marshalerCache = checkers{
|
||||
cborInterface: reflect.TypeFor[cbor.Marshaler](),
|
||||
nonCBORInterfaces: []reflect.Type{
|
||||
reflect.TypeFor[json.Marshaler](),
|
||||
reflect.TypeFor[encoding.TextMarshaler](),
|
||||
},
|
||||
}
|
||||
|
||||
var unmarshalerCache = checkers{
|
||||
cborInterface: reflect.TypeFor[cbor.Unmarshaler](),
|
||||
nonCBORInterfaces: []reflect.Type{
|
||||
reflect.TypeFor[json.Unmarshaler](),
|
||||
reflect.TypeFor[encoding.TextUnmarshaler](),
|
||||
},
|
||||
assumeAddressableValues: true,
|
||||
}
|
||||
|
||||
// checker wraps a function for dynamically checking a value of a specific type for custom JSON
|
||||
// behaviors not matched by a custom CBOR behavior.
|
||||
type checker struct {
|
||||
// check returns a non-nil error if the given value might be marshalled to or from CBOR
|
||||
// using the default behavior for its kind, but marshalled to or from JSON using custom
|
||||
// behavior.
|
||||
check func(rv reflect.Value, depth int) error
|
||||
|
||||
// safe returns true if all values of this type are safe from mismatched custom marshalers.
|
||||
safe func() bool
|
||||
}
|
||||
|
||||
// TODO: stale
|
||||
// Having a single addressable checker for comparisons lets us prune and collapse parts of the
|
||||
// object traversal that are statically known to be safe. Depending on the type, it may be
|
||||
// unnecessary to inspect each value of that type. For example, no value of the built-in type bool
|
||||
// can implement json.Marshaler (a named type whose underlying type is bool could, but it is a
|
||||
// distinct type from bool).
|
||||
var noop = checker{
|
||||
safe: func() bool {
|
||||
return true
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
type checkers struct {
|
||||
m sync.Map // reflect.Type => *checker
|
||||
|
||||
cborInterface reflect.Type
|
||||
nonCBORInterfaces []reflect.Type
|
||||
|
||||
assumeAddressableValues bool
|
||||
}
|
||||
|
||||
func (cache *checkers) getChecker(rt reflect.Type) checker {
|
||||
if ptr, ok := cache.m.Load(rt); ok {
|
||||
return *ptr.(*checker)
|
||||
}
|
||||
|
||||
return cache.getCheckerInternal(rt, nil)
|
||||
}
|
||||
|
||||
// linked list node representing the path from a composite type to an element type
|
||||
type path struct {
|
||||
Type reflect.Type
|
||||
Parent *path
|
||||
}
|
||||
|
||||
func (p path) cyclic(rt reflect.Type) bool {
|
||||
for ancestor := &p; ancestor != nil; ancestor = ancestor.Parent {
|
||||
if ancestor.Type == rt {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (cache *checkers) getCheckerInternal(rt reflect.Type, parent *path) (c checker) {
|
||||
// Store a placeholder cache entry first to handle cyclic types.
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
defer wg.Done()
|
||||
c = checker{
|
||||
safe: func() bool {
|
||||
wg.Wait()
|
||||
return c.safe()
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
wg.Wait()
|
||||
return c.check(rv, depth)
|
||||
},
|
||||
}
|
||||
if actual, loaded := cache.m.LoadOrStore(rt, &c); loaded {
|
||||
// Someone else stored an entry for this type, use it.
|
||||
return *actual.(*checker)
|
||||
}
|
||||
|
||||
// Take a nonreflective path for the unstructured container types. They're common and
|
||||
// usually nested inside one another.
|
||||
switch rt {
|
||||
case reflect.TypeFor[map[string]interface{}](), reflect.TypeFor[[]interface{}]():
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
return checkUnstructuredValue(cache, rv.Interface(), depth)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// It's possible that one of the relevant interfaces is implemented on a type with a pointer
|
||||
// receiver, but that a particular value of that type is not addressable. For example:
|
||||
//
|
||||
// func (Foo) MarshalText() ([]byte, error) { ... }
|
||||
// func (*Foo) MarshalCBOR() ([]byte, error) { ... }
|
||||
//
|
||||
// Both methods are in the method set of *Foo, but the method set of Foo contains only
|
||||
// MarshalText.
|
||||
//
|
||||
// Both the unmarshaler and marshaler checks assume that methods implementing a JSON or text
|
||||
// interface with a pointer receiver are always accessible. Only the unmarshaler check
|
||||
// assumes that CBOR methods with pointer receivers are accessible.
|
||||
|
||||
if rt.Implements(cache.cborInterface) {
|
||||
return noop
|
||||
}
|
||||
for _, unsafe := range cache.nonCBORInterfaces {
|
||||
if rt.Implements(unsafe) {
|
||||
err := fmt.Errorf("%v implements %v without corresponding cbor interface", rt, unsafe)
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(reflect.Value, int) error {
|
||||
return err
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cache.assumeAddressableValues && reflect.PointerTo(rt).Implements(cache.cborInterface) {
|
||||
return noop
|
||||
}
|
||||
for _, unsafe := range cache.nonCBORInterfaces {
|
||||
if reflect.PointerTo(rt).Implements(unsafe) {
|
||||
err := fmt.Errorf("%v implements %v without corresponding cbor interface", reflect.PointerTo(rt), unsafe)
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(reflect.Value, int) error {
|
||||
return err
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self := &path{Type: rt, Parent: parent}
|
||||
|
||||
switch rt.Kind() {
|
||||
case reflect.Array:
|
||||
ce := cache.getCheckerInternal(rt.Elem(), self)
|
||||
rtlen := rt.Len()
|
||||
if rtlen == 0 || (!self.cyclic(rt.Elem()) && ce.safe()) {
|
||||
return noop
|
||||
}
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
for i := 0; i < rtlen; i++ {
|
||||
if err := ce.check(rv.Index(i), depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
// All interface values have to be checked because their dynamic type might
|
||||
// implement one of the interesting interfaces or be composed of another type that
|
||||
// does.
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if rv.IsNil() {
|
||||
return nil
|
||||
}
|
||||
// Unpacking interfaces must count against recursion depth,
|
||||
// consider this cycle:
|
||||
// > var i interface{}
|
||||
// > var p *interface{} = &i
|
||||
// > i = p
|
||||
// > rv := reflect.ValueOf(i)
|
||||
// > for {
|
||||
// > rv = rv.Elem()
|
||||
// > }
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
rv = rv.Elem()
|
||||
return cache.getChecker(rv.Type()).check(rv, depth-1)
|
||||
},
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
rtk := rt.Key()
|
||||
ck := cache.getCheckerInternal(rtk, self)
|
||||
rte := rt.Elem()
|
||||
ce := cache.getCheckerInternal(rte, self)
|
||||
if !self.cyclic(rtk) && !self.cyclic(rte) && ck.safe() && ce.safe() {
|
||||
return noop
|
||||
}
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
iter := rv.MapRange()
|
||||
rvk := reflect.New(rtk).Elem()
|
||||
rve := reflect.New(rte).Elem()
|
||||
for iter.Next() {
|
||||
rvk.SetIterKey(iter)
|
||||
if err := ck.check(rvk, depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
rve.SetIterValue(iter)
|
||||
if err := ce.check(rve, depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
case reflect.Pointer:
|
||||
ce := cache.getCheckerInternal(rt.Elem(), self)
|
||||
if !self.cyclic(rt.Elem()) && ce.safe() {
|
||||
return noop
|
||||
}
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if rv.IsNil() {
|
||||
return nil
|
||||
}
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
return ce.check(rv.Elem(), depth-1)
|
||||
},
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
ce := cache.getCheckerInternal(rt.Elem(), self)
|
||||
if !self.cyclic(rt.Elem()) && ce.safe() {
|
||||
return noop
|
||||
}
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if err := ce.check(rv.Index(i), depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
type field struct {
|
||||
Index int
|
||||
Checker checker
|
||||
}
|
||||
var fields []field
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
f := rt.Field(i)
|
||||
cf := cache.getCheckerInternal(f.Type, self)
|
||||
if !self.cyclic(f.Type) && cf.safe() {
|
||||
continue
|
||||
}
|
||||
fields = append(fields, field{Index: i, Checker: cf})
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return noop
|
||||
}
|
||||
return checker{
|
||||
safe: func() bool {
|
||||
return false
|
||||
},
|
||||
check: func(rv reflect.Value, depth int) error {
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
for _, fi := range fields {
|
||||
if err := fi.Checker.check(rv.Field(fi.Index), depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
default:
|
||||
// Not a serializable composite type (funcs and channels are composite types but are
|
||||
// rejected by JSON and CBOR serialization).
|
||||
return noop
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func checkUnstructuredValue(cache *checkers, v interface{}, depth int) error {
|
||||
switch v := v.(type) {
|
||||
case nil, bool, int64, float64, string:
|
||||
return nil
|
||||
case []interface{}:
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
for _, element := range v {
|
||||
if err := checkUnstructuredValue(cache, element, depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case map[string]interface{}:
|
||||
if depth <= 0 {
|
||||
return errMaxDepthExceeded
|
||||
}
|
||||
for _, element := range v {
|
||||
if err := checkUnstructuredValue(cache, element, depth-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
// Unmarshaling an unstructured doesn't use other dynamic types, but nothing
|
||||
// prevents inserting values with arbitrary dynamic types into unstructured content,
|
||||
// as long as they can be marshalled.
|
||||
rv := reflect.ValueOf(v)
|
||||
return cache.getChecker(rv.Type()).check(rv, depth)
|
||||
}
|
||||
}
|
158
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/decode.go
generated
vendored
Normal file
158
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/decode.go
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
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 modes
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
var simpleValues *cbor.SimpleValueRegistry = func() *cbor.SimpleValueRegistry {
|
||||
var opts []func(*cbor.SimpleValueRegistry) error
|
||||
for sv := 0; sv <= 255; sv++ {
|
||||
// Reject simple values 0-19, 23, and 32-255. The simple values 24-31 are reserved
|
||||
// and considered ill-formed by the CBOR specification. We only accept false (20),
|
||||
// true (21), and null (22).
|
||||
switch sv {
|
||||
case 20: // false
|
||||
case 21: // true
|
||||
case 22: // null
|
||||
case 24, 25, 26, 27, 28, 29, 30, 31: // reserved
|
||||
default:
|
||||
opts = append(opts, cbor.WithRejectedSimpleValue(cbor.SimpleValue(sv)))
|
||||
}
|
||||
}
|
||||
simpleValues, err := cbor.NewSimpleValueRegistryFromDefaults(opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return simpleValues
|
||||
}()
|
||||
|
||||
var Decode cbor.DecMode = func() cbor.DecMode {
|
||||
decode, err := cbor.DecOptions{
|
||||
// Maps with duplicate keys are well-formed but invalid according to the CBOR spec
|
||||
// and never acceptable. Unlike the JSON serializer, inputs containing duplicate map
|
||||
// keys are rejected outright and not surfaced as a strict decoding error.
|
||||
DupMapKey: cbor.DupMapKeyEnforcedAPF,
|
||||
|
||||
// For JSON parity, decoding an RFC3339 string into time.Time needs to be accepted
|
||||
// with or without tagging. If a tag number is present, it must be valid.
|
||||
TimeTag: cbor.DecTagOptional,
|
||||
|
||||
// Observed depth up to 16 in fuzzed batch/v1 CronJobList. JSON implementation limit
|
||||
// is 10000.
|
||||
MaxNestedLevels: 64,
|
||||
|
||||
MaxArrayElements: 1024,
|
||||
MaxMapPairs: 1024,
|
||||
|
||||
// Indefinite-length sequences aren't produced by this serializer, but other
|
||||
// implementations can.
|
||||
IndefLength: cbor.IndefLengthAllowed,
|
||||
|
||||
// Accept inputs that contain CBOR tags.
|
||||
TagsMd: cbor.TagsAllowed,
|
||||
|
||||
// Decode type 0 (unsigned integer) as int64.
|
||||
// TODO: IntDecConvertSignedOrFail errors on overflow, JSON will try to fall back to float64.
|
||||
IntDec: cbor.IntDecConvertSignedOrFail,
|
||||
|
||||
// Disable producing map[cbor.ByteString]interface{}, which is not acceptable for
|
||||
// decodes into interface{}.
|
||||
MapKeyByteString: cbor.MapKeyByteStringForbidden,
|
||||
|
||||
// Error on map keys that don't map to a field in the destination struct.
|
||||
ExtraReturnErrors: cbor.ExtraDecErrorUnknownField,
|
||||
|
||||
// Decode maps into concrete type map[string]interface{} when the destination is an
|
||||
// interface{}.
|
||||
DefaultMapType: reflect.TypeOf(map[string]interface{}(nil)),
|
||||
|
||||
// A CBOR text string whose content is not a valid UTF-8 sequence is well-formed but
|
||||
// invalid according to the CBOR spec. Reject invalid inputs. Encoders are
|
||||
// responsible for ensuring that all text strings they produce contain valid UTF-8
|
||||
// sequences and may use the byte string major type to encode strings that have not
|
||||
// been validated.
|
||||
UTF8: cbor.UTF8RejectInvalid,
|
||||
|
||||
// Never make a case-insensitive match between a map key and a struct field.
|
||||
FieldNameMatching: cbor.FieldNameMatchingCaseSensitive,
|
||||
|
||||
// Produce string concrete values when decoding a CBOR byte string into interface{}.
|
||||
DefaultByteStringType: reflect.TypeOf(""),
|
||||
|
||||
// Allow CBOR byte strings to be decoded into string destination values. If a byte
|
||||
// string is enclosed in an "expected later encoding" tag
|
||||
// (https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.5.2), then the text
|
||||
// encoding indicated by that tag (e.g. base64) will be applied to the contents of
|
||||
// the byte string.
|
||||
ByteStringToString: cbor.ByteStringToStringAllowedWithExpectedLaterEncoding,
|
||||
|
||||
// Allow CBOR byte strings to match struct fields when appearing as a map key.
|
||||
FieldNameByteString: cbor.FieldNameByteStringAllowed,
|
||||
|
||||
// When decoding an unrecognized tag to interface{}, return the decoded tag content
|
||||
// instead of the default, a cbor.Tag representing a (number, content) pair.
|
||||
UnrecognizedTagToAny: cbor.UnrecognizedTagContentToAny,
|
||||
|
||||
// Decode time tags to interface{} as strings containing RFC 3339 timestamps.
|
||||
TimeTagToAny: cbor.TimeTagToRFC3339Nano,
|
||||
|
||||
// For parity with JSON, strings can be decoded into time.Time if they are RFC 3339
|
||||
// timestamps.
|
||||
ByteStringToTime: cbor.ByteStringToTimeAllowed,
|
||||
|
||||
// Reject NaN and infinite floating-point values since they don't have a JSON
|
||||
// representation (RFC 8259 Section 6).
|
||||
NaN: cbor.NaNDecodeForbidden,
|
||||
Inf: cbor.InfDecodeForbidden,
|
||||
|
||||
// When unmarshaling a byte string into a []byte, assume that the byte string
|
||||
// contains base64-encoded bytes, unless explicitly counterindicated by an "expected
|
||||
// later encoding" tag. This is consistent with the because of unmarshaling a JSON
|
||||
// text into a []byte.
|
||||
ByteStringExpectedFormat: cbor.ByteStringExpectedBase64,
|
||||
|
||||
// Reject the arbitrary-precision integer tags because they can't be faithfully
|
||||
// roundtripped through the allowable Unstructured types.
|
||||
BignumTag: cbor.BignumTagForbidden,
|
||||
|
||||
// Reject anything other than the simple values true, false, and null.
|
||||
SimpleValues: simpleValues,
|
||||
|
||||
// Disable default recognition of types implementing encoding.BinaryUnmarshaler,
|
||||
// which is not recognized for JSON decoding.
|
||||
BinaryUnmarshaler: cbor.BinaryUnmarshalerNone,
|
||||
}.DecMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return decode
|
||||
}()
|
||||
|
||||
// DecodeLax is derived from Decode, but does not complain about unknown fields in the input.
|
||||
var DecodeLax cbor.DecMode = func() cbor.DecMode {
|
||||
opts := Decode.DecOptions()
|
||||
opts.ExtraReturnErrors &^= cbor.ExtraDecErrorUnknownField // clear bit
|
||||
dm, err := opts.DecMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dm
|
||||
}()
|
36
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/diagnostic.go
generated
vendored
Normal file
36
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/diagnostic.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
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 modes
|
||||
|
||||
import (
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
var Diagnostic cbor.DiagMode = func() cbor.DiagMode {
|
||||
opts := Decode.DecOptions()
|
||||
diagnostic, err := cbor.DiagOptions{
|
||||
ByteStringText: true,
|
||||
|
||||
MaxNestedLevels: opts.MaxNestedLevels,
|
||||
MaxArrayElements: opts.MaxArrayElements,
|
||||
MaxMapPairs: opts.MaxMapPairs,
|
||||
}.DiagMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return diagnostic
|
||||
}()
|
155
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
generated
vendored
Normal file
155
api/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
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 modes
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
var Encode = EncMode{
|
||||
delegate: func() cbor.UserBufferEncMode {
|
||||
encode, err := cbor.EncOptions{
|
||||
// Map keys need to be sorted to have deterministic output, and this is the order
|
||||
// defined in RFC 8949 4.2.1 "Core Deterministic Encoding Requirements".
|
||||
Sort: cbor.SortBytewiseLexical,
|
||||
|
||||
// CBOR supports distinct types for IEEE-754 float16, float32, and float64. Store
|
||||
// floats in the smallest width that preserves value so that equivalent float32 and
|
||||
// float64 values encode to identical bytes, as they do in a JSON
|
||||
// encoding. Satisfies one of the "Core Deterministic Encoding Requirements".
|
||||
ShortestFloat: cbor.ShortestFloat16,
|
||||
|
||||
// Error on attempt to encode NaN and infinite values. This is what the JSON
|
||||
// serializer does.
|
||||
NaNConvert: cbor.NaNConvertReject,
|
||||
InfConvert: cbor.InfConvertReject,
|
||||
|
||||
// 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,
|
||||
|
||||
// The decoder must be able to accept RFC3339 strings with or without tag 0 (e.g. by
|
||||
// the end of time.Time -> JSON -> Unstructured -> CBOR, the CBOR encoder has no
|
||||
// reliable way of knowing that a particular string originated from serializing a
|
||||
// time.Time), so producing tag 0 has little use.
|
||||
TimeTag: cbor.EncTagNone,
|
||||
|
||||
// Indefinite-length items have multiple encodings and aren't being used anyway, so
|
||||
// disable to avoid an opportunity for nondeterminism.
|
||||
IndefLength: cbor.IndefLengthForbidden,
|
||||
|
||||
// Preserve distinction between nil and empty for slices and maps.
|
||||
NilContainers: cbor.NilContainerAsNull,
|
||||
|
||||
// OK to produce tags.
|
||||
TagsMd: cbor.TagsAllowed,
|
||||
|
||||
// Use the same definition of "empty" as encoding/json.
|
||||
OmitEmpty: cbor.OmitEmptyGoValue,
|
||||
|
||||
// The CBOR types text string and byte string are structurally equivalent, with the
|
||||
// semantic difference that a text string whose content is an invalid UTF-8 sequence
|
||||
// is itself invalid. We reject all invalid text strings at decode time and do not
|
||||
// validate or sanitize all Go strings at encode time. Encoding Go strings to the
|
||||
// byte string type is comparable to the existing Protobuf behavior and cheaply
|
||||
// ensures that the output is valid CBOR.
|
||||
String: cbor.StringToByteString,
|
||||
|
||||
// Encode struct field names to the byte string type rather than the text string
|
||||
// type.
|
||||
FieldName: cbor.FieldNameToByteString,
|
||||
|
||||
// Marshal Go byte arrays to CBOR arrays of integers (as in JSON) instead of byte
|
||||
// strings.
|
||||
ByteArray: cbor.ByteArrayToArray,
|
||||
|
||||
// Marshal []byte to CBOR byte string enclosed in tag 22 (expected later base64
|
||||
// encoding, https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.5.2), to
|
||||
// interoperate with the existing JSON behavior. This indicates to the decoder that,
|
||||
// when decoding into a string (or unstructured), the resulting value should be the
|
||||
// base64 encoding of the original bytes. No base64 encoding or decoding needs to be
|
||||
// performed for []byte-to-CBOR-to-[]byte roundtrips.
|
||||
ByteSliceLaterFormat: cbor.ByteSliceLaterFormatBase64,
|
||||
|
||||
// Disable default recognition of types implementing encoding.BinaryMarshaler, which
|
||||
// is not recognized for JSON encoding.
|
||||
BinaryMarshaler: cbor.BinaryMarshalerNone,
|
||||
}.UserBufferEncMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return encode
|
||||
}(),
|
||||
}
|
||||
|
||||
var EncodeNondeterministic = EncMode{
|
||||
delegate: func() cbor.UserBufferEncMode {
|
||||
opts := Encode.options()
|
||||
opts.Sort = cbor.SortNone // TODO: Use cbor.SortFastShuffle after bump to v2.7.0.
|
||||
em, err := opts.UserBufferEncMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return em
|
||||
}(),
|
||||
}
|
||||
|
||||
type EncMode struct {
|
||||
delegate cbor.UserBufferEncMode
|
||||
}
|
||||
|
||||
func (em EncMode) options() cbor.EncOptions {
|
||||
return em.delegate.EncOptions()
|
||||
}
|
||||
|
||||
func (em EncMode) MarshalTo(v interface{}, w io.Writer) error {
|
||||
if buf, ok := w.(*buffer); ok {
|
||||
return em.delegate.MarshalToBuffer(v, &buf.Buffer)
|
||||
}
|
||||
|
||||
buf := buffers.Get()
|
||||
defer buffers.Put(buf)
|
||||
if err := em.delegate.MarshalToBuffer(v, &buf.Buffer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(w, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (em EncMode) Marshal(v interface{}) ([]byte, error) {
|
||||
buf := buffers.Get()
|
||||
defer buffers.Put(buf)
|
||||
|
||||
if err := em.MarshalTo(v, &buf.Buffer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clone := make([]byte, buf.Len())
|
||||
copy(clone, buf.Bytes())
|
||||
|
||||
return clone, nil
|
||||
}
|
1
api/vendor/k8s.io/apimachinery/pkg/runtime/types.go
generated
vendored
1
api/vendor/k8s.io/apimachinery/pkg/runtime/types.go
generated
vendored
@ -46,6 +46,7 @@ const (
|
||||
ContentTypeJSON string = "application/json"
|
||||
ContentTypeYAML string = "application/yaml"
|
||||
ContentTypeProtobuf string = "application/vnd.kubernetes.protobuf"
|
||||
ContentTypeCBOR string = "application/cbor"
|
||||
)
|
||||
|
||||
// RawExtension is used to hold extensions in external versions.
|
||||
|
Reference in New Issue
Block a user