Skip to content

Commit c399621

Browse files
committed
apiextensions: disallow additionalProperties at the root
1 parent 9581919 commit c399621

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/validation.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const (
5555
// - ... zero or more
5656
//
5757
// * every specified field or array in s is also specified outside of value validation.
58+
// * additionalProperties at the root is not allowed.
5859
func ValidateStructural(s *Structural, fldPath *field.Path) field.ErrorList {
5960
allErrs := field.ErrorList{}
6061

@@ -76,7 +77,7 @@ func validateStructuralInvariants(s *Structural, lvl level, fldPath *field.Path)
7677
for k, v := range s.Properties {
7778
allErrs = append(allErrs, validateStructuralInvariants(&v, fieldLevel, fldPath.Child("properties").Key(k))...)
7879
}
79-
allErrs = append(allErrs, validateGeneric(&s.Generic, fldPath)...)
80+
allErrs = append(allErrs, validateGeneric(&s.Generic, lvl, fldPath)...)
8081
allErrs = append(allErrs, validateExtensions(&s.Extensions, fldPath)...)
8182

8283
// detect the two IntOrString exceptions:
@@ -129,14 +130,17 @@ func validateStructuralInvariants(s *Structural, lvl level, fldPath *field.Path)
129130
}
130131

131132
// validateGeneric checks the generic fields of a structural schema.
132-
func validateGeneric(g *Generic, fldPath *field.Path) field.ErrorList {
133+
func validateGeneric(g *Generic, lvl level, fldPath *field.Path) field.ErrorList {
133134
if g == nil {
134135
return nil
135136
}
136137

137138
allErrs := field.ErrorList{}
138139

139140
if g.AdditionalProperties != nil {
141+
if lvl == rootLevel {
142+
allErrs = append(allErrs, field.Forbidden(fldPath.Child("additionalProperties"), "must not be used at the root"))
143+
}
140144
if g.AdditionalProperties.Structural != nil {
141145
allErrs = append(allErrs, validateStructuralInvariants(g.AdditionalProperties.Structural, fieldLevel, fldPath.Child("additionalProperties"))...)
142146
}

staging/src/k8s.io/apiextensions-apiserver/test/integration/validation_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,16 @@ properties:
10481048
"spec.validation.openAPIV3Schema.properties[c]",
10491049
},
10501050
},
1051+
{
1052+
desc: "forbidden additionalProperties at the root",
1053+
globalSchema: `
1054+
type: object
1055+
additionalProperties: false
1056+
`,
1057+
expectedViolations: []string{
1058+
"spec.validation.openAPIV3Schema.additionalProperties: Forbidden: must not be used at the root",
1059+
},
1060+
},
10511061
{
10521062
desc: "structural incomplete",
10531063
globalSchema: `

0 commit comments

Comments
 (0)