Repository: getkin/kin-openapi (go)

Issue:
🪲 No further validation in the presence of anyOf. Always true.
The reason for this change: #850 

## Test case (add in `openapi3filter/validate_request_test.go`):

We are waiting for the error `minimum string length is 17`, but there is no error.

```go
func TestValidateRequestInvalidStringLength(t *testing.T) {
	const spec = `
openapi: 3.0.0
info:
  title: 'Validator'
  version: 0.0.1
paths:
  /tech:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                vehicle:
                  $ref: "#/components/schemas/Vehicle"
      responses:
        '200':
          description: Ok

components:
  schemas:
    Vehicle:
      type: object
      properties:
        identifiers:
          type: object
          properties:
            vin:
              type: string
              minLength: 17
              maxLength: 17
            body:
              type: string
              minLength: 7
              maxLength: 15
          anyOf:
            - required: [ vin ]
            - required: [ body ]
`

	body := strings.NewReader(`{"vehicle":{"identifiers":{"vin":"BAD"}}}`)
	req, err := http.NewRequest(http.MethodPost, "/tech", body)
	require.NoError(t, err)

	req.Header.Add("Content-Type", "application/json")

	router := setupTestRouter(t, spec)
	route, pathParams, err := router.FindRoute(req)
	require.NoError(t, err)

	err = ValidateRequest(context.Background(), &RequestValidationInput{
		Request:     req,
		PathParams:  pathParams,
		Route:       route,
		QueryParams: req.URL.Query(),
	})
	require.ErrorContains(t, err, "minimum string length is 17")
}
```

Similar properties are similarly not validated. `minLength` is taken as an example.

Pull request:
openapi3: fix abort logic of validation for schemas with anyOf, allOf, oneOf
## Description

Only abort further validation if xOf validations were successful AND the value is `nil` (this means that the xOf was nullable for a fact). Otherwise, continue validating against the parent schema

## Related Issues

- Closes #890 

Patch:
diff --git a/.github/docs/openapi3.txt b/.github/docs/openapi3.txt
index 5a1ae27..44e641f 100644
--- a/.github/docs/openapi3.txt
+++ b/.github/docs/openapi3.txt
@@ -1355,6 +1355,8 @@ func (schema *Schema) WithProperty(name string, propertySchema *Schema) *Schema
 
 func (schema *Schema) WithPropertyRef(name string, ref *SchemaRef) *Schema
 
+func (schema *Schema) WithRequired(required []string) *Schema
+
 func (schema *Schema) WithUniqueItems(unique bool) *Schema
 
 func (schema *Schema) WithoutAdditionalProperties() *Schema
diff --git a/openapi3/schema.go b/openapi3/schema.go
index 443e628..e8630b3 100644
--- a/openapi3/schema.go
+++ b/openapi3/schema.go
@@ -735,6 +735,11 @@ func (schema *Schema) WithProperties(properties map[string]*Schema) *Schema {
 	return schema
 }
 
+func (schema *Schema) WithRequired(required []string) *Schema {
+	schema.Required = required
+	return schema
+}
+
 func (schema *Schema) WithMinProperties(i int64) *Schema {
 	n := uint64(i)
 	schema.MinProps = n
@@ -1357,7 +1362,7 @@ func (schema *Schema) visitXOFOperations(settings *schemaValidationSettings, val
 		visitedAllOf = true
 	}
 
-	run = !(visitedOneOf || visitedAnyOf || visitedAllOf)
+	run = !((visitedOneOf || visitedAnyOf || visitedAllOf) && value == nil)
 	return
 }
 


Test patch:
diff --git a/openapi3/schema_test.go b/openapi3/schema_test.go
index 1ea8597..fe39139 100644
--- a/openapi3/schema_test.go
+++ b/openapi3/schema_test.go
@@ -230,6 +230,39 @@ var schemaExamples = []schemaExample{
 		},
 	},
 
+	{
+		Title: "ANYOF WITH PARENT CONSTRAINTS",
+		Schema: NewAnyOfSchema(
+			NewObjectSchema().WithRequired([]string{"stringProp"}),
+			NewObjectSchema().WithRequired([]string{"boolProp"}),
+		).WithProperties(map[string]*Schema{
+			"stringProp": NewStringSchema().WithMaxLength(18),
+			"boolProp":   NewBoolSchema(),
+		}),
+		Serialization: map[string]interface{}{
+			"properties": map[string]interface{}{
+				"stringProp": map[string]interface{}{"type": "string", "maxLength": 18},
+				"boolProp":   map[string]interface{}{"type": "boolean"},
+			},
+			"anyOf": []interface{}{
+				map[string]interface{}{"type": "object", "required": []string{"stringProp"}},
+				map[string]interface{}{"type": "object", "required": []string{"boolProp"}},
+			},
+		},
+		AllValid: []interface{}{
+			map[string]interface{}{"stringProp": "valid string value"},
+			map[string]interface{}{"boolProp": true},
+			map[string]interface{}{"stringProp": "valid string value", "boolProp": true},
+		},
+		AllInvalid: []interface{}{
+			1,
+			map[string]interface{}{},
+			map[string]interface{}{"invalidProp": false},
+			map[string]interface{}{"stringProp": "invalid string value"},
+			map[string]interface{}{"stringProp": "invalid string value", "boolProp": true},
+		},
+	},
+
 	{
 		Title:  "BOOLEAN",
 		Schema: NewBoolSchema(),