...

Source file src/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go

Documentation: k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes

     1  /*
     2  Copyright 2024 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package modes
    18  
    19  import (
    20  	"github.com/fxamacker/cbor/v2"
    21  )
    22  
    23  var Encode cbor.EncMode = func() cbor.EncMode {
    24  	encode, err := cbor.EncOptions{
    25  		// Map keys need to be sorted to have deterministic output, and this is the order
    26  		// defined in RFC 8949 4.2.1 "Core Deterministic Encoding Requirements".
    27  		Sort: cbor.SortBytewiseLexical,
    28  
    29  		// CBOR supports distinct types for IEEE-754 float16, float32, and float64. Store
    30  		// floats in the smallest width that preserves value so that equivalent float32 and
    31  		// float64 values encode to identical bytes, as they do in a JSON
    32  		// encoding. Satisfies one of the "Core Deterministic Encoding Requirements".
    33  		ShortestFloat: cbor.ShortestFloat16,
    34  
    35  		// ShortestFloat doesn't apply to NaN or Inf values. Inf values are losslessly
    36  		// encoded to float16. RFC 8949 recommends choosing a single representation of NaN
    37  		// in applications that do not smuggle additional information inside NaN values, we
    38  		// use 0x7e00.
    39  		NaNConvert: cbor.NaNConvert7e00,
    40  		InfConvert: cbor.InfConvertFloat16,
    41  
    42  		// Prefer encoding math/big.Int to one of the 64-bit integer types if it fits. When
    43  		// later decoded into Unstructured, the set of allowable concrete numeric types is
    44  		// limited to int64 and float64, so the distinction between big integer and integer
    45  		// can't be preserved.
    46  		BigIntConvert: cbor.BigIntConvertShortest,
    47  
    48  		// MarshalJSON for time.Time writes RFC3339 with nanos.
    49  		Time: cbor.TimeRFC3339Nano,
    50  
    51  		// The decoder must be able to accept RFC3339 strings with or without tag 0 (e.g. by
    52  		// the end of time.Time -> JSON -> Unstructured -> CBOR, the CBOR encoder has no
    53  		// reliable way of knowing that a particular string originated from serializing a
    54  		// time.Time), so producing tag 0 has little use.
    55  		TimeTag: cbor.EncTagNone,
    56  
    57  		// Indefinite-length items have multiple encodings and aren't being used anyway, so
    58  		// disable to avoid an opportunity for nondeterminism.
    59  		IndefLength: cbor.IndefLengthForbidden,
    60  
    61  		// Preserve distinction between nil and empty for slices and maps.
    62  		NilContainers: cbor.NilContainerAsNull,
    63  
    64  		// OK to produce tags.
    65  		TagsMd: cbor.TagsAllowed,
    66  
    67  		// Use the same definition of "empty" as encoding/json.
    68  		OmitEmpty: cbor.OmitEmptyGoValue,
    69  
    70  		// The CBOR types text string and byte string are structurally equivalent, with the
    71  		// semantic difference that a text string whose content is an invalid UTF-8 sequence
    72  		// is itself invalid. We reject all invalid text strings at decode time and do not
    73  		// validate or sanitize all Go strings at encode time. Encoding Go strings to the
    74  		// byte string type is comparable to the existing Protobuf behavior and cheaply
    75  		// ensures that the output is valid CBOR.
    76  		String: cbor.StringToByteString,
    77  
    78  		// Encode struct field names to the byte string type rather than the text string
    79  		// type.
    80  		FieldName: cbor.FieldNameToByteString,
    81  	}.EncMode()
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  	return encode
    86  }()
    87  
    88  var EncodeNondeterministic cbor.EncMode = func() cbor.EncMode {
    89  	opts := Encode.EncOptions()
    90  	opts.Sort = cbor.SortNone
    91  	em, err := opts.EncMode()
    92  	if err != nil {
    93  		panic(err)
    94  	}
    95  	return em
    96  }()
    97  

View as plain text