Skip to content

Commit 3957163

Browse files
authored
Remove incorrect logic for oneOf, anyOf and properties (#1053)
* Remove incorrect logic for oneOf, anyOf and properties * Refactor * Refactor * Refactor
1 parent 11c0df2 commit 3957163

File tree

11 files changed

+234
-297
lines changed

11 files changed

+234
-297
lines changed

src/main/java/com/networknt/schema/AdditionalPropertiesValidator.java

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,14 @@ public AdditionalPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath
8080
}
8181
}
8282

83-
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
83+
@Override
84+
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
85+
JsonNodePath instanceLocation) {
86+
return validate(executionContext, node, rootNode, instanceLocation, false);
87+
}
88+
89+
protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
90+
JsonNodePath instanceLocation, boolean walk) {
8491
debug(logger, node, rootNode, instanceLocation);
8592
if (!node.isObject()) {
8693
// ignore no object
@@ -110,15 +117,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
110117
if (pname.startsWith("#")) {
111118
continue;
112119
}
113-
boolean handledByPatternProperties = false;
114-
for (RegularExpression pattern : patternProperties) {
115-
if (pattern.matches(pname)) {
116-
handledByPatternProperties = true;
117-
break;
118-
}
119-
}
120-
121-
if (!allowedProperties.contains(pname) && !handledByPatternProperties) {
120+
if (!allowedProperties.contains(pname) && !handledByPatternProperties(pname)) {
122121
if (!allowAdditionalProperties) {
123122
if (errors == null) {
124123
errors = new LinkedHashSet<>();
@@ -129,26 +128,16 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
129128
.failFast(executionContext.isFailFast()).arguments(pname).build());
130129
} else {
131130
if (additionalPropertiesSchema != null) {
132-
ValidatorState state = executionContext.getValidatorState();
133-
if (state != null && state.isWalkEnabled()) {
134-
Set<ValidationMessage> results = additionalPropertiesSchema.walk(executionContext,
135-
entry.getValue(), rootNode, instanceLocation.append(pname),
136-
state.isValidationEnabled());
137-
if (!results.isEmpty()) {
138-
if (errors == null) {
139-
errors = new LinkedHashSet<>();
140-
}
141-
errors.addAll(results);
142-
}
143-
} else {
144-
Set<ValidationMessage> results = additionalPropertiesSchema.validate(executionContext,
145-
entry.getValue(), rootNode, instanceLocation.append(pname));
146-
if (!results.isEmpty()) {
147-
if (errors == null) {
148-
errors = new LinkedHashSet<>();
149-
}
150-
errors.addAll(results);
131+
Set<ValidationMessage> results = !walk
132+
? additionalPropertiesSchema.validate(executionContext, entry.getValue(), rootNode,
133+
instanceLocation.append(pname))
134+
: additionalPropertiesSchema.walk(executionContext, entry.getValue(), rootNode,
135+
instanceLocation.append(pname), true);
136+
if (!results.isEmpty()) {
137+
if (errors == null) {
138+
errors = new LinkedHashSet<>();
151139
}
140+
errors.addAll(results);
152141
}
153142
}
154143
}
@@ -166,7 +155,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
166155
@Override
167156
public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
168157
if (shouldValidateSchema && node != null) {
169-
return validate(executionContext, node, rootNode, instanceLocation);
158+
return validate(executionContext, node, rootNode, instanceLocation, true);
170159
}
171160

172161
if (node == null || !node.isObject()) {
@@ -181,28 +170,27 @@ public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode n
181170
if (pname.startsWith("#")) {
182171
continue;
183172
}
184-
boolean handledByPatternProperties = false;
185-
for (RegularExpression pattern : patternProperties) {
186-
if (pattern.matches(pname)) {
187-
handledByPatternProperties = true;
188-
break;
189-
}
190-
}
191-
192-
if (!allowedProperties.contains(pname) && !handledByPatternProperties) {
173+
if (!allowedProperties.contains(pname) && !handledByPatternProperties(pname)) {
193174
if (allowAdditionalProperties) {
194175
if (additionalPropertiesSchema != null) {
195-
ValidatorState state = executionContext.getValidatorState();
196-
if (state != null && state.isWalkEnabled()) {
197-
additionalPropertiesSchema.walk(executionContext, node.get(pname), rootNode, instanceLocation.append(pname), state.isValidationEnabled());
198-
}
176+
additionalPropertiesSchema.walk(executionContext, node.get(pname), rootNode,
177+
instanceLocation.append(pname), shouldValidateSchema);
199178
}
200179
}
201180
}
202181
}
203182
return Collections.emptySet();
204183
}
205184

185+
private boolean handledByPatternProperties(String pname) {
186+
for (RegularExpression pattern : this.patternProperties) {
187+
if (pattern.matches(pname)) {
188+
return true;
189+
}
190+
}
191+
return false;
192+
}
193+
206194
private boolean collectAnnotations() {
207195
return hasUnevaluatedPropertiesValidator();
208196
}

src/main/java/com/networknt/schema/AllOfValidator.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,18 @@ public AllOfValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
5252

5353
@Override
5454
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
55-
debug(logger, node, rootNode, instanceLocation);
55+
return validate(executionContext, node, rootNode, instanceLocation, false);
56+
}
5657

57-
// get the Validator state object storing validation data
58-
ValidatorState state = executionContext.getValidatorState();
58+
protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean walk) {
59+
debug(logger, node, rootNode, instanceLocation);
5960

6061
SetView<ValidationMessage> childSchemaErrors = null;
6162

6263
for (JsonSchema schema : this.schemas) {
6364
Set<ValidationMessage> localErrors = null;
6465

65-
if (!state.isWalkEnabled()) {
66+
if (!walk) {
6667
localErrors = schema.validate(executionContext, node, rootNode, instanceLocation);
6768
} else {
6869
localErrors = schema.walk(executionContext, node, rootNode, instanceLocation, true);
@@ -111,7 +112,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
111112
@Override
112113
public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
113114
if (shouldValidateSchema) {
114-
return validate(executionContext, node, rootNode, instanceLocation);
115+
return validate(executionContext, node, rootNode, instanceLocation, true);
115116
}
116117
for (JsonSchema schema : this.schemas) {
117118
// Walk through the schema

src/main/java/com/networknt/schema/AnyOfValidator.java

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,18 @@ public AnyOfValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
5353
}
5454

5555
@Override
56-
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
57-
debug(logger, node, rootNode, instanceLocation);
56+
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
57+
JsonNodePath instanceLocation) {
58+
return validate(executionContext, node, rootNode, instanceLocation, false);
59+
}
5860

59-
// get the Validator state object storing validation data
60-
ValidatorState state = executionContext.getValidatorState();
61+
protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
62+
JsonNodePath instanceLocation, boolean walk) {
63+
debug(logger, node, rootNode, instanceLocation);
6164

6265
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
6366
executionContext.enterDiscriminatorContext(new DiscriminatorContext(), instanceLocation);
6467
}
65-
66-
boolean initialHasMatchedNode = state.hasMatchedNode();
67-
6868
SetView<ValidationMessage> allErrors = null;
6969

7070
int numberOfValidSubSchemas = 0;
@@ -75,8 +75,6 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
7575
executionContext.setFailFast(false);
7676
for (JsonSchema schema : this.schemas) {
7777
Set<ValidationMessage> errors = Collections.emptySet();
78-
state.setMatchedNode(initialHasMatchedNode);
79-
8078
TypeValidator typeValidator = schema.getTypeValidator();
8179
if (typeValidator != null) {
8280
// If schema has type validator and node type doesn't match with schemaType then
@@ -90,19 +88,14 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
9088
continue;
9189
}
9290
}
93-
if (!state.isWalkEnabled()) {
91+
if (!walk) {
9492
errors = schema.validate(executionContext, node, rootNode, instanceLocation);
9593
} else {
9694
errors = schema.walk(executionContext, node, rootNode, instanceLocation, true);
9795
}
9896

9997
// check if any validation errors have occurred
10098
if (errors.isEmpty()) {
101-
// check whether there are no errors HOWEVER we have validated the exact
102-
// validator
103-
if (!state.hasMatchedNode()) {
104-
continue;
105-
}
10699
// we found a valid subschema, so increase counter
107100
numberOfValidSubSchemas++;
108101
}
@@ -159,9 +152,6 @@ && canShortCircuit() && canShortCircuit(executionContext)) {
159152
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
160153
executionContext.leaveDiscriminatorContextImmediately(instanceLocation);
161154
}
162-
if (allErrors == null || allErrors.isEmpty()) {
163-
state.setMatchedNode(true);
164-
}
165155
}
166156
if (numberOfValidSubSchemas >= 1) {
167157
return Collections.emptySet();
@@ -172,7 +162,7 @@ && canShortCircuit() && canShortCircuit(executionContext)) {
172162
@Override
173163
public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
174164
if (shouldValidateSchema) {
175-
return validate(executionContext, node, rootNode, instanceLocation);
165+
return validate(executionContext, node, rootNode, instanceLocation, true);
176166
}
177167
for (JsonSchema schema : this.schemas) {
178168
schema.walk(executionContext, node, rootNode, instanceLocation, false);

src/main/java/com/networknt/schema/DependentSchemas.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,23 @@ public DependentSchemas(SchemaLocation schemaLocation, JsonNodePath evaluationPa
4444
}
4545

4646
@Override
47-
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
47+
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
48+
JsonNodePath instanceLocation) {
49+
return validate(executionContext, node, rootNode, instanceLocation, false);
50+
}
51+
52+
protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
53+
JsonNodePath instanceLocation, boolean walk) {
4854
debug(logger, node, rootNode, instanceLocation);
4955

5056
Set<ValidationMessage> errors = null;
5157
for (Iterator<String> it = node.fieldNames(); it.hasNext(); ) {
5258
String pname = it.next();
5359
JsonSchema schema = this.schemaDependencies.get(pname);
5460
if (schema != null) {
55-
Set<ValidationMessage> schemaDependenciesErrors = schema.validate(executionContext, node, rootNode, instanceLocation);
61+
Set<ValidationMessage> schemaDependenciesErrors = !walk
62+
? schema.validate(executionContext, node, rootNode, instanceLocation)
63+
: schema.walk(executionContext, node, rootNode, instanceLocation, true);
5664
if (!schemaDependenciesErrors.isEmpty()) {
5765
if (errors == null) {
5866
errors = new LinkedHashSet<>();
@@ -72,7 +80,7 @@ public void preloadJsonSchema() {
7280
@Override
7381
public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
7482
if (shouldValidateSchema) {
75-
return validate(executionContext, node, rootNode, instanceLocation);
83+
return validate(executionContext, node, rootNode, instanceLocation, true);
7684
}
7785
for (JsonSchema schema : this.schemaDependencies.values()) {
7886
schema.walk(executionContext, node, rootNode, instanceLocation, false);

src/main/java/com/networknt/schema/ExecutionContext.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
public class ExecutionContext {
2828
private ExecutionConfig executionConfig;
2929
private CollectorContext collectorContext = null;
30-
private ValidatorState validatorState = null;
3130
private Stack<DiscriminatorContext> discriminatorContexts = null;
3231
private JsonNodeAnnotations annotations = null;
3332
private JsonNodeResults results = null;
@@ -153,24 +152,6 @@ public void setFailFast(boolean failFast) {
153152
this.failFast = failFast;
154153
}
155154

156-
/**
157-
* Gets the validator state.
158-
*
159-
* @return the validator state
160-
*/
161-
public ValidatorState getValidatorState() {
162-
return validatorState;
163-
}
164-
165-
/**
166-
* Sets the validator state.
167-
*
168-
* @param validatorState the validator state
169-
*/
170-
public void setValidatorState(ValidatorState validatorState) {
171-
this.validatorState = validatorState;
172-
}
173-
174155
public DiscriminatorContext getCurrentDiscriminatorContext() {
175156
if (this.discriminatorContexts == null) {
176157
return null;

src/main/java/com/networknt/schema/JsonSchema.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ public class JsonSchema extends BaseJsonValidator {
5858
private boolean validatorsLoaded = false;
5959
private boolean recursiveAnchor = false;
6060

61-
private JsonValidator requiredValidator = null;
6261
private TypeValidator typeValidator;
6362

6463
private final String id;
@@ -161,7 +160,6 @@ protected JsonSchema(JsonSchema copy) {
161160
this.validators = copy.validators;
162161
this.validatorsLoaded = copy.validatorsLoaded;
163162
this.recursiveAnchor = copy.recursiveAnchor;
164-
this.requiredValidator = copy.requiredValidator;
165163
this.typeValidator = copy.typeValidator;
166164
this.id = copy.id;
167165
}
@@ -189,7 +187,6 @@ public JsonSchema fromRef(JsonSchema refEvaluationParentSchema, JsonNodePath ref
189187
copy.evaluationParentSchema = refEvaluationParentSchema;
190188
// Validator state is reset due to the changes in evaluation path
191189
copy.validatorsLoaded = false;
192-
copy.requiredValidator = null;
193190
copy.typeValidator = null;
194191
copy.validators = null;
195192
return copy;
@@ -204,7 +201,6 @@ public JsonSchema withConfig(SchemaValidatorsConfig config) {
204201
copy.getValidationContext().getSchemaResources(),
205202
copy.getValidationContext().getDynamicAnchors());
206203
copy.validatorsLoaded = false;
207-
copy.requiredValidator = null;
208204
copy.typeValidator = null;
209205
copy.validators = null;
210206
return copy;
@@ -472,8 +468,6 @@ private List<JsonValidator> read(JsonNode schemaNode) {
472468

473469
if ("$ref".equals(pname)) {
474470
refValidator = validator;
475-
} else if ("required".equals(pname)) {
476-
this.requiredValidator = validator;
477471
} else if ("type".equals(pname)) {
478472
if (validator instanceof TypeValidator) {
479473
this.typeValidator = (TypeValidator) validator;
@@ -537,9 +531,6 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
537531
}
538532

539533
SetView<ValidationMessage> errors = null;
540-
// Set the walkEnabled and isValidationEnabled flag in internal validator state.
541-
setValidatorState(executionContext, false, true);
542-
543534
for (JsonValidator v : getValidators()) {
544535
Set<ValidationMessage> results = null;
545536

@@ -894,8 +885,6 @@ public ValidationResult validateAndCollect(ExecutionContext executionContext, Js
894885
* @return ValidationResult
895886
*/
896887
private ValidationResult validateAndCollect(ExecutionContext executionContext, JsonNode jsonNode, JsonNode rootNode, JsonNodePath instanceLocation) {
897-
// Set the walkEnabled and isValidationEnabled flag in internal validator state.
898-
setValidatorState(executionContext, false, true);
899888
// Validate.
900889
Set<ValidationMessage> errors = validate(executionContext, jsonNode, rootNode, instanceLocation);
901890

@@ -990,8 +979,6 @@ public ValidationResult walkAtNode(ExecutionContext executionContext, JsonNode n
990979

991980
private ValidationResult walkAtNodeInternal(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
992981
JsonNodePath instanceLocation, boolean shouldValidateSchema) {
993-
// Set the walkEnabled flag in internal validator state.
994-
setValidatorState(executionContext, true, shouldValidateSchema);
995982
// Walk through the schema.
996983
Set<ValidationMessage> errors = walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
997984

@@ -1041,30 +1028,11 @@ public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode n
10411028
}
10421029

10431030
/************************ END OF WALK METHODS **********************************/
1044-
1045-
private static void setValidatorState(ExecutionContext executionContext, boolean isWalkEnabled,
1046-
boolean shouldValidateSchema) {
1047-
// Get the Validator state object storing validation data
1048-
ValidatorState validatorState = executionContext.getValidatorState();
1049-
if (validatorState == null) {
1050-
// If one has not been created, instantiate one
1051-
executionContext.setValidatorState(new ValidatorState(isWalkEnabled, shouldValidateSchema));
1052-
}
1053-
}
1054-
10551031
@Override
10561032
public String toString() {
10571033
return "\"" + getEvaluationPath() + "\" : " + getSchemaNode().toString();
10581034
}
10591035

1060-
public boolean hasRequiredValidator() {
1061-
return this.requiredValidator != null;
1062-
}
1063-
1064-
public JsonValidator getRequiredValidator() {
1065-
return this.requiredValidator;
1066-
}
1067-
10681036
public boolean hasTypeValidator() {
10691037
return getTypeValidator() != null;
10701038
}

0 commit comments

Comments
 (0)