@@ -646,35 +646,65 @@ func (st SchemaTypeCheck) validateDependentRequired(schema *v3.Schema, context *
646646 return results
647647}
648648
649- // checkPolymorphicProperty checks if a property is defined in anyOf, oneOf, or allOf schemas
649+ // checkPolymorphicProperty checks if a property is defined in anyOf, oneOf, or allOf schemas,
650+ // including nested compositions and referenced schemas.
650651func (st SchemaTypeCheck ) checkPolymorphicProperty (schema * v3.Schema , propertyName string ) bool {
651- // check in AnyOf schemas
652- if schema .Value .AnyOf != nil {
653- for _ , anyOfSchema := range schema .Value .AnyOf {
654- if anyOfSchema .Schema () != nil && anyOfSchema .Schema ().Properties != nil &&
655- anyOfSchema .Schema ().Properties .GetOrZero (propertyName ) != nil {
656- return true
657- }
658- }
652+ if schema == nil || schema .Value == nil {
653+ return false
659654 }
660655
661- // check in OneOf schemas
662- if schema .Value .OneOf != nil {
663- for _ , oneOfSchema := range schema .Value .OneOf {
664- if oneOfSchema .Schema () != nil && oneOfSchema .Schema ().Properties != nil &&
665- oneOfSchema .Schema ().Properties .GetOrZero (propertyName ) != nil {
666- return true
667- }
656+ visited := make (map [* lowBase.Schema ]struct {})
657+ return st .checkSchemaPropertyRecursive (schema .Value , propertyName , visited )
658+ }
659+
660+ // checkSchemaPropertyRecursive recursively traverses down the schema looking for the existance
661+ // of a specific property. It ensures that all references are properly resolved.
662+ func (st SchemaTypeCheck ) checkSchemaPropertyRecursive (schema * highBase.Schema , propertyName string , visited map [* lowBase.Schema ]struct {}) bool {
663+ if schema == nil {
664+ return false
665+ }
666+
667+ if low := schema .GoLow (); low != nil {
668+ if _ , seen := visited [low ]; seen {
669+ return false
668670 }
671+ visited [low ] = struct {}{}
669672 }
670673
671- // check in AllOf schemas
672- if schema .Value .AllOf != nil {
673- for _ , allOfSchema := range schema .Value .AllOf {
674- if allOfSchema .Schema () != nil && allOfSchema .Schema ().Properties != nil &&
675- allOfSchema .Schema ().Properties .GetOrZero (propertyName ) != nil {
676- return true
677- }
674+ if schema .Properties != nil && schema .Properties .GetOrZero (propertyName ) != nil {
675+ return true
676+ }
677+
678+ if st .checkSchemaProxiesForProperty (schema .AnyOf , propertyName , visited ) {
679+ return true
680+ }
681+ if st .checkSchemaProxiesForProperty (schema .OneOf , propertyName , visited ) {
682+ return true
683+ }
684+ if st .checkSchemaProxiesForProperty (schema .AllOf , propertyName , visited ) {
685+ return true
686+ }
687+
688+ return false
689+ }
690+
691+ func (st SchemaTypeCheck ) checkSchemaProxiesForProperty (
692+ proxies []* highBase.SchemaProxy ,
693+ propertyName string ,
694+ visited map [* lowBase.Schema ]struct {},
695+ ) bool {
696+ for _ , proxy := range proxies {
697+ if proxy == nil {
698+ continue
699+ }
700+
701+ subSchema := proxy .Schema ()
702+ if subSchema == nil {
703+ continue
704+ }
705+
706+ if st .checkSchemaPropertyRecursive (subSchema , propertyName , visited ) {
707+ return true
678708 }
679709 }
680710
0 commit comments