fixes #523 synched ipv4 and ipv6 and fix some gaps for the IP format validation
diff --git a/src/main/java/com/networknt/schema/FormatValidator.java b/src/main/java/com/networknt/schema/FormatValidator.java
index 7e7962d..8fec8e4 100644
--- a/src/main/java/com/networknt/schema/FormatValidator.java
+++ b/src/main/java/com/networknt/schema/FormatValidator.java
@@ -49,6 +49,15 @@
}
if (format != null) {
+ if(format.getName().equals("ipv6")) {
+ if(!node.textValue().trim().equals(node.textValue())) {
+ // leading and trailing spaces
+ errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));
+ } else if(node.textValue().contains("%")) {
+ // zone id is not part of the ipv6
+ errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));
+ }
+ }
try {
if (!format.matches(node.textValue())) {
errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));
diff --git a/src/main/java/com/networknt/schema/JsonMetaSchema.java b/src/main/java/com/networknt/schema/JsonMetaSchema.java
index cfd038d..c490388 100644
--- a/src/main/java/com/networknt/schema/JsonMetaSchema.java
+++ b/src/main/java/com/networknt/schema/JsonMetaSchema.java
@@ -43,8 +43,7 @@
COMMON_BUILTIN_FORMATS.add(pattern("time", "^\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?$"));
COMMON_BUILTIN_FORMATS.add(pattern("ip-address",
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"));
- COMMON_BUILTIN_FORMATS.add(pattern("ipv4",
- "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"));
+ COMMON_BUILTIN_FORMATS.add(pattern("ipv4", "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"));
COMMON_BUILTIN_FORMATS.add(pattern("ipv6",
"^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"));
diff --git a/src/test/java/com/networknt/schema/V4JsonSchemaTest.java b/src/test/java/com/networknt/schema/V4JsonSchemaTest.java
index 2bea9cd..f0d37d3 100644
--- a/src/test/java/com/networknt/schema/V4JsonSchemaTest.java
+++ b/src/test/java/com/networknt/schema/V4JsonSchemaTest.java
@@ -58,13 +58,11 @@
}
@Test
- @Disabled
public void testFormatIpv4Validator() throws Exception {
runTestFile("draft4/optional/format/ipv4.json");
}
@Test
- @Disabled
public void testFormatIpv6Validator() throws Exception {
runTestFile("draft4/optional/format/ipv6.json");
}
diff --git a/src/test/java/com/networknt/schema/V6JsonSchemaTest.java b/src/test/java/com/networknt/schema/V6JsonSchemaTest.java
index 65dcca3..7f3ad8a 100644
--- a/src/test/java/com/networknt/schema/V6JsonSchemaTest.java
+++ b/src/test/java/com/networknt/schema/V6JsonSchemaTest.java
@@ -24,6 +24,11 @@
}
@Test
+ public void testFormatIpv4Validator() throws Exception {
+ runTestFile("draft4/optional/format/ipv4.json");
+ }
+
+ @Test
public void testOptionalBignumValidator() throws Exception {
runTestFile("draft6/optional/bignum.json");
}
diff --git a/src/test/resources/draft6/optional/ipv4.json b/src/test/resources/draft6/optional/ipv4.json
new file mode 100644
index 0000000..6b166c7
--- /dev/null
+++ b/src/test/resources/draft6/optional/ipv4.json
@@ -0,0 +1,84 @@
+[
+ {
+ "description": "validation of IP addresses",
+ "schema": { "format": "ipv4" },
+ "tests": [
+ {
+ "description": "all string formats ignore integers",
+ "data": 12,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore floats",
+ "data": 13.7,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore objects",
+ "data": {},
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore arrays",
+ "data": [],
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore booleans",
+ "data": false,
+ "valid": true
+ },
+ {
+ "description": "all string formats ignore nulls",
+ "data": null,
+ "valid": true
+ },
+ {
+ "description": "a valid IP address",
+ "data": "192.168.0.1",
+ "valid": true
+ },
+ {
+ "description": "an IP address with too many components",
+ "data": "127.0.0.0.1",
+ "valid": false
+ },
+ {
+ "description": "an IP address with out-of-range values",
+ "data": "256.256.256.256",
+ "valid": false
+ },
+ {
+ "description": "an IP address without 4 components",
+ "data": "127.0",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer",
+ "data": "0x7f000001",
+ "valid": false
+ },
+ {
+ "description": "an IP address as an integer (decimal)",
+ "data": "2130706433",
+ "valid": false
+ },
+ {
+ "description": "leading zeroes should be rejected, as they are treated as octals",
+ "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/",
+ "data": "087.10.0.1",
+ "valid": false
+ },
+ {
+ "description": "value without leading zero is valid",
+ "data": "87.10.0.1",
+ "valid": true
+ },
+ {
+ "description": "non-ascii digits should be rejected",
+ "data": "1২7.0.0.1",
+ "valid": false
+ }
+ ]
+ }
+]