Unverified Commit 0918155d authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #62981 from atlassian/uint64-remove

Automatic merge from submit-queue (batch tested with PRs 61154, 62981). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Remove incomplete uint64 support from JSON unmarshaling **What this PR does / why we need it**: Removes `uint64` support from JSON unmarshaling because: - [unsigned types should not be used](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#primitive-types); - big numbers (53+ bits) cannot be properly round tripped via JSON in most languages. **Which issue(s) this PR fixes** Fixes #62769. **Special notes for your reviewer**: This is an alternative approach to https://github.com/kubernetes/kubernetes/pull/62775. **Release note**: ```release-note NONE ``` /kind bug /sig api-machinery /cc @sttts
parents 89542d9e bbef0f6f
...@@ -16,6 +16,8 @@ limitations under the License. ...@@ -16,6 +16,8 @@ limitations under the License.
package apiextensions package apiextensions
import "k8s.io/apimachinery/pkg/runtime"
// TODO: Update this after a tag is created for interface fields in DeepCopy // TODO: Update this after a tag is created for interface fields in DeepCopy
func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
if in == nil { if in == nil {
...@@ -26,14 +28,14 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { ...@@ -26,14 +28,14 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
*out = *in *out = *in
if in.Default != nil { if in.Default != nil {
defaultJSON := JSON(deepCopyJSON(*(in.Default))) defaultJSON := JSON(runtime.DeepCopyJSONValue(*(in.Default)))
out.Default = &(defaultJSON) out.Default = &(defaultJSON)
} else { } else {
out.Default = nil out.Default = nil
} }
if in.Example != nil { if in.Example != nil {
exampleJSON := JSON(deepCopyJSON(*(in.Example))) exampleJSON := JSON(runtime.DeepCopyJSONValue(*(in.Example)))
out.Example = &(exampleJSON) out.Example = &(exampleJSON)
} else { } else {
out.Example = nil out.Example = nil
...@@ -121,7 +123,7 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { ...@@ -121,7 +123,7 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
if in.Enum != nil { if in.Enum != nil {
out.Enum = make([]JSON, len(in.Enum)) out.Enum = make([]JSON, len(in.Enum))
for i := range in.Enum { for i := range in.Enum {
out.Enum[i] = deepCopyJSON(in.Enum[i]) out.Enum[i] = runtime.DeepCopyJSONValue(in.Enum[i])
} }
} }
...@@ -258,22 +260,3 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { ...@@ -258,22 +260,3 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
return out return out
} }
func deepCopyJSON(x interface{}) interface{} {
switch x := x.(type) {
case map[string]interface{}:
clone := make(map[string]interface{}, len(x))
for k, v := range x {
clone[k] = deepCopyJSON(v)
}
return clone
case []interface{}:
clone := make([]interface{}, len(x))
for i := range x {
clone[i] = deepCopyJSON(x[i])
}
return clone
default:
return x
}
}
...@@ -236,22 +236,3 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps { ...@@ -236,22 +236,3 @@ func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
return out return out
} }
func deepCopyJSON(x interface{}) interface{} {
switch x := x.(type) {
case map[string]interface{}:
clone := make(map[string]interface{}, len(x))
for k, v := range x {
clone[k] = deepCopyJSON(v)
}
return clone
case []interface{}:
clone := make([]interface{}, len(x))
for i := range x {
clone[i] = deepCopyJSON(x[i])
}
return clone
default:
return x
}
}
...@@ -268,7 +268,7 @@ func v1alpha1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { ...@@ -268,7 +268,7 @@ func v1alpha1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
case 0: case 0:
r.Cells[i] = c.RandString() r.Cells[i] = c.RandString()
case 1: case 1:
r.Cells[i] = c.Uint64() r.Cells[i] = c.Int63()
case 2: case 2:
r.Cells[i] = c.RandBool() r.Cells[i] = c.RandBool()
case 3: case 3:
...@@ -280,7 +280,7 @@ func v1alpha1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { ...@@ -280,7 +280,7 @@ func v1alpha1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} {
case 4: case 4:
x := make([]interface{}, c.Intn(10)) x := make([]interface{}, c.Intn(10))
for i := range x { for i := range x {
x[i] = c.Uint64() x[i] = c.Int63()
} }
r.Cells[i] = x r.Cells[i] = x
default: default:
......
...@@ -16,6 +16,8 @@ limitations under the License. ...@@ -16,6 +16,8 @@ limitations under the License.
package v1beta1 package v1beta1
import "k8s.io/apimachinery/pkg/runtime"
func (in *TableRow) DeepCopy() *TableRow { func (in *TableRow) DeepCopy() *TableRow {
if in == nil { if in == nil {
return nil return nil
...@@ -26,7 +28,7 @@ func (in *TableRow) DeepCopy() *TableRow { ...@@ -26,7 +28,7 @@ func (in *TableRow) DeepCopy() *TableRow {
if in.Cells != nil { if in.Cells != nil {
out.Cells = make([]interface{}, len(in.Cells)) out.Cells = make([]interface{}, len(in.Cells))
for i := range in.Cells { for i := range in.Cells {
out.Cells[i] = deepCopyJSON(in.Cells[i]) out.Cells[i] = runtime.DeepCopyJSONValue(in.Cells[i])
} }
} }
...@@ -40,22 +42,3 @@ func (in *TableRow) DeepCopy() *TableRow { ...@@ -40,22 +42,3 @@ func (in *TableRow) DeepCopy() *TableRow {
in.Object.DeepCopyInto(&out.Object) in.Object.DeepCopyInto(&out.Object)
return out return out
} }
func deepCopyJSON(x interface{}) interface{} {
switch x := x.(type) {
case map[string]interface{}:
clone := make(map[string]interface{}, len(x))
for k, v := range x {
clone[k] = deepCopyJSON(v)
}
return clone
case []interface{}:
clone := make([]interface{}, len(x))
for i := range x {
clone[i] = deepCopyJSON(x[i])
}
return clone
default:
return x
}
}
...@@ -73,7 +73,6 @@ var ( ...@@ -73,7 +73,6 @@ var (
mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{}) mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
stringType = reflect.TypeOf(string("")) stringType = reflect.TypeOf(string(""))
int64Type = reflect.TypeOf(int64(0)) int64Type = reflect.TypeOf(int64(0))
uint64Type = reflect.TypeOf(uint64(0))
float64Type = reflect.TypeOf(float64(0)) float64Type = reflect.TypeOf(float64(0))
boolType = reflect.TypeOf(bool(false)) boolType = reflect.TypeOf(bool(false))
fieldCache = newFieldsCache() fieldCache = newFieldsCache()
...@@ -438,13 +437,15 @@ func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]inte ...@@ -438,13 +437,15 @@ func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]inte
} }
// DeepCopyJSON deep copies the passed value, assuming it is a valid JSON representation i.e. only contains // DeepCopyJSON deep copies the passed value, assuming it is a valid JSON representation i.e. only contains
// types produced by json.Unmarshal(). // types produced by json.Unmarshal() and also int64.
// bool, int64, float64, string, []interface{}, map[string]interface{}, json.Number and nil
func DeepCopyJSON(x map[string]interface{}) map[string]interface{} { func DeepCopyJSON(x map[string]interface{}) map[string]interface{} {
return DeepCopyJSONValue(x).(map[string]interface{}) return DeepCopyJSONValue(x).(map[string]interface{})
} }
// DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains // DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains
// types produced by json.Unmarshal(). // types produced by json.Unmarshal() and also int64.
// bool, int64, float64, string, []interface{}, map[string]interface{}, json.Number and nil
func DeepCopyJSONValue(x interface{}) interface{} { func DeepCopyJSONValue(x interface{}) interface{} {
switch x := x.(type) { switch x := x.(type) {
case map[string]interface{}: case map[string]interface{}:
...@@ -591,10 +592,14 @@ func toUnstructured(sv, dv reflect.Value) error { ...@@ -591,10 +592,14 @@ func toUnstructured(sv, dv reflect.Value) error {
dv.Set(reflect.ValueOf(sv.Int())) dv.Set(reflect.ValueOf(sv.Int()))
return nil return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
uVal := sv.Uint()
if uVal > math.MaxInt64 {
return fmt.Errorf("unsigned value %d does not fit into int64 (overflow)", uVal)
}
if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
dv.Set(reflect.New(uint64Type)) dv.Set(reflect.New(int64Type))
} }
dv.Set(reflect.ValueOf(sv.Uint())) dv.Set(reflect.ValueOf(int64(uVal)))
return nil return nil
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
......
...@@ -75,11 +75,6 @@ func init() { ...@@ -75,11 +75,6 @@ func init() {
case jsoniter.NumberValue: case jsoniter.NumberValue:
var number json.Number var number json.Number
iter.ReadVal(&number) iter.ReadVal(&number)
u64, err := strconv.ParseUint(string(number), 10, 64)
if err == nil {
*(*interface{})(ptr) = u64
return
}
i64, err := strconv.ParseInt(string(number), 10, 64) i64, err := strconv.ParseInt(string(number), 10, 64)
if err == nil { if err == nil {
*(*interface{})(ptr) = i64 *(*interface{})(ptr) = i64
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment