Skip to content

Commit 8c467d8

Browse files
committed
Fix enum
1 parent 832b9fc commit 8c467d8

File tree

7 files changed

+597
-2
lines changed

7 files changed

+597
-2
lines changed

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

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
package com.networknt.schema;
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
20+
import com.fasterxml.jackson.databind.node.ArrayNode;
2021
import com.fasterxml.jackson.databind.node.DecimalNode;
2122
import com.fasterxml.jackson.databind.node.NullNode;
2223
import org.slf4j.Logger;
2324
import org.slf4j.LoggerFactory;
2425

26+
import java.math.BigDecimal;
2527
import java.util.Collections;
2628
import java.util.HashSet;
2729
import java.util.Set;
@@ -45,7 +47,10 @@ public EnumValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath,
4547
for (JsonNode n : schemaNode) {
4648
if (n.isNumber()) {
4749
// convert to DecimalNode for number comparison
48-
nodes.add(DecimalNode.valueOf(n.decimalValue()));
50+
nodes.add(processNumberNode(n));
51+
} else if (n.isArray()) {
52+
ArrayNode a = processArrayNode((ArrayNode) n);
53+
nodes.add(a);
4954
} else {
5055
nodes.add(n);
5156
}
@@ -78,7 +83,11 @@ public EnumValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath,
7883
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
7984
debug(logger, node, rootNode, instanceLocation);
8085

81-
if (node.isNumber()) node = DecimalNode.valueOf(node.decimalValue());
86+
if (node.isNumber()) {
87+
node = processNumberNode(node);
88+
} else if (node.isArray()) {
89+
node = processArrayNode((ArrayNode) node);
90+
}
8291
if (!nodes.contains(node) && !( this.validationContext.getConfig().isTypeLoose() && isTypeLooseContainsInEnum(node))) {
8392
return Collections.singleton(message().instanceLocation(instanceLocation)
8493
.locale(executionContext.getExecutionConfig().getLocale()).arguments(error).build());
@@ -105,4 +114,50 @@ private boolean isTypeLooseContainsInEnum(JsonNode node) {
105114
return false;
106115
}
107116

117+
/**
118+
* Processes the number and ensures trailing zeros are stripped.
119+
*
120+
* @param n the node
121+
* @return the node
122+
*/
123+
protected JsonNode processNumberNode(JsonNode n) {
124+
return DecimalNode.valueOf(new BigDecimal(n.decimalValue().toPlainString()));
125+
}
126+
127+
/**
128+
* Processes the array and ensures that numbers within have trailing zeroes stripped.
129+
*
130+
* @param node the node
131+
* @return the node
132+
*/
133+
protected ArrayNode processArrayNode(ArrayNode node) {
134+
if (!hasNumber(node)) {
135+
return node;
136+
}
137+
ArrayNode a = (ArrayNode) node.deepCopy();
138+
for (int x = 0; x < a.size(); x++) {
139+
JsonNode v = a.get(x);
140+
if (v.isNumber()) {
141+
v = processNumberNode(v);
142+
a.set(x, v);
143+
}
144+
}
145+
return a;
146+
}
147+
148+
/**
149+
* Determines if the array node contains a number.
150+
*
151+
* @param node the node
152+
* @return the node
153+
*/
154+
protected boolean hasNumber(ArrayNode node) {
155+
for (int x = 0; x < node.size(); x++) {
156+
JsonNode v = node.get(x);
157+
if (v.isNumber()) {
158+
return true;
159+
}
160+
}
161+
return false;
162+
}
108163
}

src/test/suite/tests/draft-next/enum.json

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,30 @@
168168
}
169169
]
170170
},
171+
{
172+
"description": "enum with [false] does not match [0]",
173+
"schema": {
174+
"$schema": "https://json-schema.org/draft/next/schema",
175+
"enum": [[false]]
176+
},
177+
"tests": [
178+
{
179+
"description": "[false] is valid",
180+
"data": [false],
181+
"valid": true
182+
},
183+
{
184+
"description": "[0] is invalid",
185+
"data": [0],
186+
"valid": false
187+
},
188+
{
189+
"description": "[0.0] is invalid",
190+
"data": [0.0],
191+
"valid": false
192+
}
193+
]
194+
},
171195
{
172196
"description": "enum with true does not match 1",
173197
"schema": {
@@ -192,6 +216,30 @@
192216
}
193217
]
194218
},
219+
{
220+
"description": "enum with [true] does not match [1]",
221+
"schema": {
222+
"$schema": "https://json-schema.org/draft/next/schema",
223+
"enum": [[true]]
224+
},
225+
"tests": [
226+
{
227+
"description": "[true] is valid",
228+
"data": [true],
229+
"valid": true
230+
},
231+
{
232+
"description": "[1] is invalid",
233+
"data": [1],
234+
"valid": false
235+
},
236+
{
237+
"description": "[1.0] is invalid",
238+
"data": [1.0],
239+
"valid": false
240+
}
241+
]
242+
},
195243
{
196244
"description": "enum with 0 does not match false",
197245
"schema": {
@@ -216,6 +264,30 @@
216264
}
217265
]
218266
},
267+
{
268+
"description": "enum with [0] does not match [false]",
269+
"schema": {
270+
"$schema": "https://json-schema.org/draft/next/schema",
271+
"enum": [[0]]
272+
},
273+
"tests": [
274+
{
275+
"description": "[false] is invalid",
276+
"data": [false],
277+
"valid": false
278+
},
279+
{
280+
"description": "[0] is valid",
281+
"data": [0],
282+
"valid": true
283+
},
284+
{
285+
"description": "[0.0] is valid",
286+
"data": [0.0],
287+
"valid": true
288+
}
289+
]
290+
},
219291
{
220292
"description": "enum with 1 does not match true",
221293
"schema": {
@@ -240,6 +312,30 @@
240312
}
241313
]
242314
},
315+
{
316+
"description": "enum with [1] does not match [true]",
317+
"schema": {
318+
"$schema": "https://json-schema.org/draft/next/schema",
319+
"enum": [[1]]
320+
},
321+
"tests": [
322+
{
323+
"description": "[true] is invalid",
324+
"data": [true],
325+
"valid": false
326+
},
327+
{
328+
"description": "[1] is valid",
329+
"data": [1],
330+
"valid": true
331+
},
332+
{
333+
"description": "[1.0] is valid",
334+
"data": [1.0],
335+
"valid": true
336+
}
337+
]
338+
},
243339
{
244340
"description": "nul characters in strings",
245341
"schema": {

src/test/suite/tests/draft2019-09/enum.json

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,30 @@
168168
}
169169
]
170170
},
171+
{
172+
"description": "enum with [false] does not match [0]",
173+
"schema": {
174+
"$schema": "https://json-schema.org/draft/2019-09/schema",
175+
"enum": [[false]]
176+
},
177+
"tests": [
178+
{
179+
"description": "[false] is valid",
180+
"data": [false],
181+
"valid": true
182+
},
183+
{
184+
"description": "[0] is invalid",
185+
"data": [0],
186+
"valid": false
187+
},
188+
{
189+
"description": "[0.0] is invalid",
190+
"data": [0.0],
191+
"valid": false
192+
}
193+
]
194+
},
171195
{
172196
"description": "enum with true does not match 1",
173197
"schema": {
@@ -192,6 +216,30 @@
192216
}
193217
]
194218
},
219+
{
220+
"description": "enum with [true] does not match [1]",
221+
"schema": {
222+
"$schema": "https://json-schema.org/draft/2019-09/schema",
223+
"enum": [[true]]
224+
},
225+
"tests": [
226+
{
227+
"description": "[true] is valid",
228+
"data": [true],
229+
"valid": true
230+
},
231+
{
232+
"description": "[1] is invalid",
233+
"data": [1],
234+
"valid": false
235+
},
236+
{
237+
"description": "[1.0] is invalid",
238+
"data": [1.0],
239+
"valid": false
240+
}
241+
]
242+
},
195243
{
196244
"description": "enum with 0 does not match false",
197245
"schema": {
@@ -216,6 +264,30 @@
216264
}
217265
]
218266
},
267+
{
268+
"description": "enum with [0] does not match [false]",
269+
"schema": {
270+
"$schema": "https://json-schema.org/draft/2019-09/schema",
271+
"enum": [[0]]
272+
},
273+
"tests": [
274+
{
275+
"description": "[false] is invalid",
276+
"data": [false],
277+
"valid": false
278+
},
279+
{
280+
"description": "[0] is valid",
281+
"data": [0],
282+
"valid": true
283+
},
284+
{
285+
"description": "[0.0] is valid",
286+
"data": [0.0],
287+
"valid": true
288+
}
289+
]
290+
},
219291
{
220292
"description": "enum with 1 does not match true",
221293
"schema": {
@@ -240,6 +312,30 @@
240312
}
241313
]
242314
},
315+
{
316+
"description": "enum with [1] does not match [true]",
317+
"schema": {
318+
"$schema": "https://json-schema.org/draft/2019-09/schema",
319+
"enum": [[1]]
320+
},
321+
"tests": [
322+
{
323+
"description": "[true] is invalid",
324+
"data": [true],
325+
"valid": false
326+
},
327+
{
328+
"description": "[1] is valid",
329+
"data": [1],
330+
"valid": true
331+
},
332+
{
333+
"description": "[1.0] is valid",
334+
"data": [1.0],
335+
"valid": true
336+
}
337+
]
338+
},
243339
{
244340
"description": "nul characters in strings",
245341
"schema": {

0 commit comments

Comments
 (0)