Fix IntOrString cost estimation when schema has a MaxLength constraint
Kubernetes-commit: 8dc20a0f62d44af1d584efbbc6bf918b93c4e3d8
This commit is contained in:
parent
953f6a8aff
commit
76004fdd79
|
@ -55,8 +55,15 @@ func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType {
|
|||
// `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5
|
||||
//
|
||||
dyn := apiservercel.NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) // smallest value for a serialized x-kubernetes-int-or-string is 0
|
||||
// handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string
|
||||
dyn.MaxElements = maxRequestSizeBytes - 2
|
||||
|
||||
// If the schema has a maxlength constraint, bound the max elements based on the max length.
|
||||
// Otherwise, fallback to the max request size.
|
||||
if s.MaxLength() != nil {
|
||||
dyn.MaxElements = estimateMaxElementsFromMaxLength(s)
|
||||
} else {
|
||||
dyn.MaxElements = estimateMaxStringLengthPerRequest(s)
|
||||
}
|
||||
|
||||
return dyn
|
||||
}
|
||||
|
||||
|
@ -159,11 +166,7 @@ func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType {
|
|||
|
||||
strWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), apiservercel.MinStringSize)
|
||||
if s.MaxLength() != nil {
|
||||
// multiply the user-provided max length by 4 in the case of an otherwise-untyped string
|
||||
// we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points,
|
||||
// but we need to reason about length for things like request size, so we use bytes in this code (and an individual
|
||||
// unicode code point can be up to 4 bytes long)
|
||||
strWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) * 4
|
||||
strWithMaxLength.MaxElements = estimateMaxElementsFromMaxLength(s)
|
||||
} else {
|
||||
if len(s.Enum()) > 0 {
|
||||
strWithMaxLength.MaxElements = estimateMaxStringEnumLength(s)
|
||||
|
@ -228,6 +231,7 @@ func WithTypeAndObjectMeta(s *spec.Schema) *spec.Schema {
|
|||
// must only be called on schemas of type "string" or x-kubernetes-int-or-string: true
|
||||
func estimateMaxStringLengthPerRequest(s Schema) int64 {
|
||||
if s.IsXIntOrString() {
|
||||
// handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string
|
||||
return maxRequestSizeBytes - 2
|
||||
}
|
||||
switch s.Format() {
|
||||
|
@ -272,3 +276,13 @@ func estimateMaxAdditionalPropertiesFromMinSize(minSize int64) int64 {
|
|||
// subtract 2 to account for { and }
|
||||
return (maxRequestSizeBytes - 2) / keyValuePairSize
|
||||
}
|
||||
|
||||
// estimateMaxElementsFromMaxLength estimates the maximum number of elements for a string schema
|
||||
// that is bound with a maxLength constraint.
|
||||
func estimateMaxElementsFromMaxLength(s Schema) int64 {
|
||||
// multiply the user-provided max length by 4 in the case of an otherwise-untyped string
|
||||
// we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points,
|
||||
// but we need to reason about length for things like request size, so we use bytes in this code (and an individual
|
||||
// unicode code point can be up to 4 bytes long)
|
||||
return zeroIfNegative(*s.MaxLength()) * 4
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue