Skip to content

Commit 601aa70

Browse files
authored
Add exhaustive ABNF-driven tests with RFC 2673 compliance for ipv4 format (#840)
* feat: Add exhaustive ABNF-driven tests with RFC 2673 compliance for ipv4 format * fix: Replace forbidden 'specification' field with 'comment' for CI compliance * fix: Update ABNF citations to RFC 3986 Sec 3.2.2 and remove redundant test * fix: align ipv4 tests strictly to RFC 2673 and move strict CVE checks to URI format * feat: enforce strict anti-octal ipv4 tests in v1 spec * feat: document URI reg-name fallback and backport ipv4 tests to older drafts * fix: revert v1 ipv4 leading zero tests to valid * fix: remove all speculative comments regarding v1 spec changes * style: removed trailing space from RFC 2673 comments * style: combines RFC 2673 ABNF rules comments into test group level comment * fix: remove leading zero tests as requested by @jdesrosiers * fix: remove legacy duplicate test and backport uri tests to all drafts
1 parent 583d7c6 commit 601aa70

File tree

17 files changed

+696
-54
lines changed

17 files changed

+696
-54
lines changed

tests/draft2019-09/optional/format/ipv4.json

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[
22
{
33
"description": "validation of IP addresses",
4+
"comment": "RFC 2673, Section 3.2: dotted-quad = decbyte \".\" decbyte \".\" decbyte \".\" decbyte. A 'decbyte' (1*3DIGIT) restricts semantic values to 0-255, allows leading zeros, and strictly forbids symbols, alpha/hex, whitespace, and non-ASCII characters.",
45
"schema": {
56
"$schema": "https://json-schema.org/draft/2019-09/schema",
67
"format": "ipv4"
@@ -67,24 +68,108 @@
6768
"valid": false
6869
},
6970
{
70-
"description": "invalid leading zeroes, as they are treated as octals",
71-
"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/",
72-
"data": "087.10.0.1",
71+
"description": "invalid non-ASCII '২' (a Bengali 2)",
72+
"data": "1২7.0.0.1",
73+
"valid": false
74+
},
75+
{
76+
"description": "netmask is not a part of ipv4 address",
77+
"data": "192.168.1.0/24",
78+
"valid": false
79+
},
80+
{
81+
"description": "leading whitespace is invalid",
82+
"data": " 192.168.0.1",
83+
"valid": false
84+
},
85+
{
86+
"description": "trailing whitespace is invalid",
87+
"data": "192.168.0.1 ",
88+
"valid": false
89+
},
90+
{
91+
"description": "trailing newline is invalid",
92+
"data": "192.168.0.1\n",
93+
"valid": false
94+
},
95+
{
96+
"description": "hexadecimal notation is invalid",
97+
"data": "0x7f.0.0.1",
7398
"valid": false
7499
},
75100
{
76-
"description": "value without leading zero is valid",
77-
"data": "87.10.0.1",
101+
"description": "octal notation explicit is invalid",
102+
"data": "0o10.0.0.1",
103+
"valid": false
104+
},
105+
{
106+
"description": "empty part (double dot) is invalid",
107+
"data": "192.168..1",
108+
"valid": false
109+
},
110+
{
111+
"description": "leading dot is invalid",
112+
"data": ".192.168.0.1",
113+
"valid": false
114+
},
115+
{
116+
"description": "trailing dot is invalid",
117+
"data": "192.168.0.1.",
118+
"valid": false
119+
},
120+
{
121+
"description": "minimum valid IPv4 address",
122+
"data": "0.0.0.0",
78123
"valid": true
79124
},
80125
{
81-
"description": "invalid non-ASCII '২' (a Bengali 2)",
82-
"data": "1২7.0.0.1",
126+
"description": "maximum valid IPv4 address",
127+
"data": "255.255.255.255",
128+
"valid": true
129+
},
130+
{
131+
"description": "empty string is invalid",
132+
"data": "",
83133
"valid": false
84134
},
85135
{
86-
"description": "netmask is not a part of ipv4 address",
87-
"data": "192.168.1.0/24",
136+
"description": "plus sign is invalid",
137+
"data": "+1.2.3.4",
138+
"valid": false
139+
},
140+
{
141+
"description": "negative sign is invalid",
142+
"data": "-1.2.3.4",
143+
"valid": false
144+
},
145+
{
146+
"description": "exponential notation is invalid",
147+
"data": "1e2.0.0.1",
148+
"valid": false
149+
},
150+
{
151+
"description": "alpha characters are invalid",
152+
"data": "192.168.a.1",
153+
"valid": false
154+
},
155+
{
156+
"description": "internal whitespace is invalid",
157+
"data": "192. 168.0.1",
158+
"valid": false
159+
},
160+
{
161+
"description": "tab character is invalid",
162+
"data": "192.168.0.1\t",
163+
"valid": false
164+
},
165+
{
166+
"description": "with port number is invalid",
167+
"data": "192.168.0.1:80",
168+
"valid": false
169+
},
170+
{
171+
"description": "single octet out of range in last position",
172+
"data": "192.168.0.256",
88173
"valid": false
89174
}
90175
]

tests/draft2019-09/optional/format/uri-reference.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@
8080
"description": "invalid backslash character",
8181
"data": "https://example.org/foobar\\.txt",
8282
"valid": false
83+
},
84+
{
85+
"description": "URI with leading-zero IPv4 is structurally valid as a reg-name",
86+
"comment": "RFC 3986, Section 3.2.2: If an IP literal fails strict IPv4address parsing, it falls back to reg-name. A string of digits and dots is valid under unreserved characters. JSON Schema format asserts syntax, not scheme-specific DNS semantics.",
87+
"data": "http://087.10.0.1/",
88+
"valid": true
89+
},
90+
{
91+
"description": "URI with out-of-bounds IPv4 is structurally valid as a reg-name",
92+
"comment": "RFC 3986, Section 3.2.2: Fallback to reg-name allows digits and dots.",
93+
"data": "http://999.999.999.999/",
94+
"valid": true
8395
}
8496
]
8597
}

tests/draft2019-09/optional/format/uri.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@
185185
"description": "invalid | character",
186186
"data": "https://example.org/foobar|.txt",
187187
"valid": false
188+
},
189+
{
190+
"description": "URI with leading-zero IPv4 is structurally valid as a reg-name",
191+
"comment": "RFC 3986, Section 3.2.2: If an IP literal fails strict IPv4address parsing, it falls back to reg-name. A string of digits and dots is valid under unreserved characters. JSON Schema format asserts syntax, not scheme-specific DNS semantics.",
192+
"data": "http://087.10.0.1/",
193+
"valid": true
194+
},
195+
{
196+
"description": "URI with out-of-bounds IPv4 is structurally valid as a reg-name",
197+
"comment": "RFC 3986, Section 3.2.2: Fallback to reg-name allows digits and dots.",
198+
"data": "http://999.999.999.999/",
199+
"valid": true
188200
}
189201
]
190202
}

tests/draft2020-12/optional/format/ipv4.json

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[
22
{
33
"description": "validation of IP addresses",
4+
"comment": "RFC 2673, Section 3.2: dotted-quad = decbyte \".\" decbyte \".\" decbyte \".\" decbyte. A 'decbyte' (1*3DIGIT) restricts semantic values to 0-255, allows leading zeros, and strictly forbids symbols, alpha/hex, whitespace, and non-ASCII characters.",
45
"schema": {
56
"$schema": "https://json-schema.org/draft/2020-12/schema",
67
"format": "ipv4"
@@ -67,24 +68,108 @@
6768
"valid": false
6869
},
6970
{
70-
"description": "invalid leading zeroes, as they are treated as octals",
71-
"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/",
72-
"data": "087.10.0.1",
71+
"description": "invalid non-ASCII '২' (a Bengali 2)",
72+
"data": "1২7.0.0.1",
73+
"valid": false
74+
},
75+
{
76+
"description": "netmask is not a part of ipv4 address",
77+
"data": "192.168.1.0/24",
78+
"valid": false
79+
},
80+
{
81+
"description": "leading whitespace is invalid",
82+
"data": " 192.168.0.1",
83+
"valid": false
84+
},
85+
{
86+
"description": "trailing whitespace is invalid",
87+
"data": "192.168.0.1 ",
88+
"valid": false
89+
},
90+
{
91+
"description": "trailing newline is invalid",
92+
"data": "192.168.0.1\n",
93+
"valid": false
94+
},
95+
{
96+
"description": "hexadecimal notation is invalid",
97+
"data": "0x7f.0.0.1",
7398
"valid": false
7499
},
75100
{
76-
"description": "value without leading zero is valid",
77-
"data": "87.10.0.1",
101+
"description": "octal notation explicit is invalid",
102+
"data": "0o10.0.0.1",
103+
"valid": false
104+
},
105+
{
106+
"description": "empty part (double dot) is invalid",
107+
"data": "192.168..1",
108+
"valid": false
109+
},
110+
{
111+
"description": "leading dot is invalid",
112+
"data": ".192.168.0.1",
113+
"valid": false
114+
},
115+
{
116+
"description": "trailing dot is invalid",
117+
"data": "192.168.0.1.",
118+
"valid": false
119+
},
120+
{
121+
"description": "minimum valid IPv4 address",
122+
"data": "0.0.0.0",
78123
"valid": true
79124
},
80125
{
81-
"description": "invalid non-ASCII '২' (a Bengali 2)",
82-
"data": "1২7.0.0.1",
126+
"description": "maximum valid IPv4 address",
127+
"data": "255.255.255.255",
128+
"valid": true
129+
},
130+
{
131+
"description": "empty string is invalid",
132+
"data": "",
83133
"valid": false
84134
},
85135
{
86-
"description": "netmask is not a part of ipv4 address",
87-
"data": "192.168.1.0/24",
136+
"description": "plus sign is invalid",
137+
"data": "+1.2.3.4",
138+
"valid": false
139+
},
140+
{
141+
"description": "negative sign is invalid",
142+
"data": "-1.2.3.4",
143+
"valid": false
144+
},
145+
{
146+
"description": "exponential notation is invalid",
147+
"data": "1e2.0.0.1",
148+
"valid": false
149+
},
150+
{
151+
"description": "alpha characters are invalid",
152+
"data": "192.168.a.1",
153+
"valid": false
154+
},
155+
{
156+
"description": "internal whitespace is invalid",
157+
"data": "192. 168.0.1",
158+
"valid": false
159+
},
160+
{
161+
"description": "tab character is invalid",
162+
"data": "192.168.0.1\t",
163+
"valid": false
164+
},
165+
{
166+
"description": "with port number is invalid",
167+
"data": "192.168.0.1:80",
168+
"valid": false
169+
},
170+
{
171+
"description": "single octet out of range in last position",
172+
"data": "192.168.0.256",
88173
"valid": false
89174
}
90175
]

tests/draft2020-12/optional/format/uri-reference.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@
8080
"description": "invalid backslash character",
8181
"data": "https://example.org/foobar\\.txt",
8282
"valid": false
83+
},
84+
{
85+
"description": "URI with leading-zero IPv4 is structurally valid as a reg-name",
86+
"comment": "RFC 3986, Section 3.2.2: If an IP literal fails strict IPv4address parsing, it falls back to reg-name. A string of digits and dots is valid under unreserved characters. JSON Schema format asserts syntax, not scheme-specific DNS semantics.",
87+
"data": "http://087.10.0.1/",
88+
"valid": true
89+
},
90+
{
91+
"description": "URI with out-of-bounds IPv4 is structurally valid as a reg-name",
92+
"comment": "RFC 3986, Section 3.2.2: Fallback to reg-name allows digits and dots.",
93+
"data": "http://999.999.999.999/",
94+
"valid": true
8395
}
8496
]
8597
}

tests/draft2020-12/optional/format/uri.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@
185185
"description": "invalid | character",
186186
"data": "https://example.org/foobar|.txt",
187187
"valid": false
188+
},
189+
{
190+
"description": "URI with leading-zero IPv4 is structurally valid as a reg-name",
191+
"comment": "RFC 3986, Section 3.2.2: If an IP literal fails strict IPv4address parsing, it falls back to reg-name. A string of digits and dots is valid under unreserved characters. JSON Schema format asserts syntax, not scheme-specific DNS semantics.",
192+
"data": "http://087.10.0.1/",
193+
"valid": true
194+
},
195+
{
196+
"description": "URI with out-of-bounds IPv4 is structurally valid as a reg-name",
197+
"comment": "RFC 3986, Section 3.2.2: Fallback to reg-name allows digits and dots.",
198+
"data": "http://999.999.999.999/",
199+
"valid": true
188200
}
189201
]
190202
}

0 commit comments

Comments
 (0)