]>
Commit | Line | Data |
---|---|---|
622749d8 | 1 | m4_define([JSON_CHECK_POSITIVE_C], |
f38b84ea BP |
2 | [AT_SETUP([$1]) |
3 | AT_KEYWORDS([json positive]) | |
4 | AT_CHECK([printf %s "AS_ESCAPE([$2])" > input]) | |
0bdf342a | 5 | AT_CAPTURE_FILE([input]) |
eadd1644 | 6 | AT_CHECK([ovstest test-json $4 input], [0], [stdout], []) |
0bdf342a BP |
7 | AT_CHECK([cat stdout], [0], [$3 |
8 | ]) | |
f38b84ea BP |
9 | AT_CLEANUP]) |
10 | ||
f7255f06 RB |
11 | # JSON_CHECK_POSITIVE_PY(TITLE, INPUT, OUTPUT, TEST-JSON-ARGS, |
12 | # PYTHON-CHCEK, PYTHON-BIN) | |
13 | # | |
622749d8 | 14 | m4_define([JSON_CHECK_POSITIVE_PY], |
99155935 BP |
15 | [AT_SETUP([$1]) |
16 | AT_KEYWORDS([json positive Python]) | |
f7255f06 | 17 | AT_SKIP_IF([test $5 = no]) |
99155935 BP |
18 | AT_CHECK([printf %s "AS_ESCAPE([$2])" > input]) |
19 | AT_CAPTURE_FILE([input]) | |
f7255f06 | 20 | AT_CHECK([$6 $srcdir/test-json.py $4 input], [0], [stdout], []) |
99155935 BP |
21 | AT_CHECK([cat stdout], [0], [$3 |
22 | ]) | |
23 | AT_CLEANUP]) | |
24 | ||
65683353 EJ |
25 | m4_define([JSON_CHECK_POSITIVE_UCS4PY], |
26 | [AT_SETUP([$1]) | |
27 | AT_KEYWORDS([json positive Python]) | |
28 | AT_SKIP_IF([test $HAVE_PYTHON = no]) | |
29 | AT_XFAIL_IF([$PYTHON -c "exit(len(u'\U00010800'))"; test $? -ne 1]) | |
30 | AT_CHECK([printf %s "AS_ESCAPE([$2])" > input]) | |
31 | AT_CAPTURE_FILE([input]) | |
32 | AT_CHECK([$PYTHON $srcdir/test-json.py $4 input], [0], [stdout], []) | |
33 | AT_CHECK([cat stdout], [0], [$3 | |
34 | ]) | |
35 | AT_CLEANUP]) | |
36 | ||
99155935 BP |
37 | m4_define([JSON_CHECK_POSITIVE], |
38 | [JSON_CHECK_POSITIVE_C([$1 - C], [$2], [$3], [$4]) | |
f7255f06 RB |
39 | JSON_CHECK_POSITIVE_PY([$1 - Python2], [$2], [$3], [$4], |
40 | [$HAVE_PYTHON], [$PYTHON]) | |
41 | JSON_CHECK_POSITIVE_PY([$1 - Python3], [$2], [$3], [$4], | |
42 | [$HAVE_PYTHON3], [$PYTHON3])]) | |
99155935 | 43 | |
622749d8 TW |
44 | m4_define([JSON_CHECK_POSITIVE_PY23], |
45 | [JSON_CHECK_POSITIVE_PY([$1 - Python2], [$2], [$3], [$4], | |
46 | [$HAVE_PYTHON], [$PYTHON]) | |
47 | JSON_CHECK_POSITIVE_PY([$1 - Python3], [$2], [$3], [$4], | |
48 | [$HAVE_PYTHON3], [$PYTHON3])]) | |
49 | ||
99155935 | 50 | m4_define([JSON_CHECK_NEGATIVE_C], |
f38b84ea BP |
51 | [AT_SETUP([$1]) |
52 | AT_KEYWORDS([json negative]) | |
53 | AT_CHECK([printf %s "AS_ESCAPE([$2])" > input]) | |
0bdf342a | 54 | AT_CAPTURE_FILE([input]) |
eadd1644 | 55 | AT_CHECK([ovstest test-json $4 input], [1], [stdout], []) |
0bdf342a | 56 | AT_CHECK([[sed 's/^error: [^:]*:/error:/' < stdout]], [0], [$3 |
f38b84ea BP |
57 | ]) |
58 | AT_CLEANUP]) | |
59 | ||
f7255f06 RB |
60 | # JSON_CHECK_NEGATIVE_PY(TITLE, INPUT, OUTPUT, TEST-JSON-ARGS, |
61 | # PYTHON-CHCEK, PYTHON-BIN) | |
62 | # | |
99155935 BP |
63 | m4_define([JSON_CHECK_NEGATIVE_PY], |
64 | [AT_SETUP([$1]) | |
65 | AT_KEYWORDS([json negative Python]) | |
f7255f06 | 66 | AT_SKIP_IF([test $5 = no]) |
99155935 BP |
67 | AT_CHECK([printf %s "AS_ESCAPE([$2])" > input]) |
68 | AT_CAPTURE_FILE([input]) | |
f7255f06 | 69 | AT_CHECK([$6 $srcdir/test-json.py $4 input], [1], [stdout], []) |
99155935 BP |
70 | AT_CHECK([[sed 's/^error: [^:]*:/error:/' < stdout]], [0], [$3 |
71 | ]) | |
72 | AT_CLEANUP]) | |
73 | ||
74 | m4_define([JSON_CHECK_NEGATIVE], | |
75 | [JSON_CHECK_NEGATIVE_C([$1 - C], [$2], [$3], [$4]) | |
f7255f06 RB |
76 | JSON_CHECK_NEGATIVE_PY([$1 - Python2], [$2], [$3], [$4], |
77 | [$HAVE_PYTHON], [$PYTHON]) | |
78 | JSON_CHECK_NEGATIVE_PY([$1 - Python3], [$2], [$3], [$4], | |
79 | [$HAVE_PYTHON3], [$PYTHON3])]) | |
99155935 | 80 | |
f38b84ea BP |
81 | AT_BANNER([JSON -- arrays]) |
82 | ||
83 | JSON_CHECK_POSITIVE([empty array], [[ [ ] ]], [[[]]]) | |
84 | JSON_CHECK_POSITIVE([single-element array], [[ [ 1 ] ]], [[[1]]]) | |
85 | JSON_CHECK_POSITIVE([2-element array], [[ [ 1, 2 ] ]], [[[1,2]]]) | |
86 | JSON_CHECK_POSITIVE([many-element array], | |
87 | [[ [ 1, 2, 3, 4, 5 ] ]], | |
88 | [[[1,2,3,4,5]]]) | |
89 | JSON_CHECK_NEGATIVE([missing comma], [[ [ 1, 2, 3 4, 5 ] ]], | |
90 | [error: syntax error expecting '@:>@' or ',']) | |
91 | JSON_CHECK_NEGATIVE([trailing comma not allowed], | |
92 | [[[1,2,]]], [error: syntax error expecting value]) | |
93 | JSON_CHECK_NEGATIVE([doubled comma not allowed], | |
94 | [[[1,,2]]], [error: syntax error expecting value]) | |
95 | ||
96 | AT_BANNER([JSON -- strings]) | |
97 | ||
98 | JSON_CHECK_POSITIVE([empty string], [[[ "" ]]], [[[""]]]) | |
99 | JSON_CHECK_POSITIVE([1-character strings], | |
100 | [[[ "a", "b", "c" ]]], | |
101 | [[["a","b","c"]]]) | |
102 | JSON_CHECK_POSITIVE([escape sequences], | |
103 | [[[ " \" \\ \/ \b \f \n \r \t" ]]], | |
104 | [[[" \" \\ / \b \f \n \r \t"]]]) | |
105 | JSON_CHECK_POSITIVE([Unicode escape sequences], | |
106 | [[[ " \u0022 \u005c \u002F \u0008 \u000c \u000A \u000d \u0009" ]]], | |
107 | [[[" \" \\ / \b \f \n \r \t"]]]) | |
65683353 EJ |
108 | JSON_CHECK_POSITIVE_C([surrogate pairs - C], |
109 | [[["\ud834\udd1e"]]], | |
110 | [[["𝄞"]]]) | |
111 | JSON_CHECK_POSITIVE_UCS4PY([surrogate pairs - Python], | |
f38b84ea BP |
112 | [[["\ud834\udd1e"]]], |
113 | [[["𝄞"]]]) | |
114 | JSON_CHECK_NEGATIVE([a string by itself is not valid JSON], ["xxx"], | |
115 | [error: syntax error at beginning of input]) | |
116 | JSON_CHECK_NEGATIVE([end of line in quoted string], | |
117 | [[["xxx | |
118 | "]]], | |
119 | [error: U+000A must be escaped in quoted string]) | |
120 | JSON_CHECK_NEGATIVE([formfeed in quoted string], | |
121 | [[["xxx\f"]]], | |
122 | [error: U+000C must be escaped in quoted string]) | |
123 | JSON_CHECK_NEGATIVE([bad escape in quoted string], | |
124 | [[["\x12"]]], | |
125 | [error: bad escape \x]) | |
7d23a63a | 126 | JSON_CHECK_NEGATIVE([\u must be followed by 4 hex digits (1)], |
f38b84ea | 127 | [[["\u1x"]]], |
7d23a63a BP |
128 | [error: quoted string ends within \u escape]) |
129 | JSON_CHECK_NEGATIVE([\u must be followed by 4 hex digits (2)], | |
130 | [[["\u1xyz"]]], | |
f38b84ea BP |
131 | [error: malformed \u escape]) |
132 | JSON_CHECK_NEGATIVE([isolated leading surrogate not allowed], | |
133 | [[["\ud834xxx"]]], | |
134 | [error: malformed escaped surrogate pair]) | |
135 | JSON_CHECK_NEGATIVE([surrogatess must paired properly], | |
136 | [[["\ud834\u1234"]]], | |
137 | [error: second half of escaped surrogate pair is not trailing surrogate]) | |
138 | JSON_CHECK_NEGATIVE([null bytes not allowed], | |
139 | [[["\u0000"]]], | |
140 | [error: null bytes not supported in quoted strings]) | |
7b7c2a46 BP |
141 | dnl Check for regression against a prior bug. |
142 | JSON_CHECK_POSITIVE([properly quoted backslash at end of string], | |
143 | [[["\\"]]], | |
144 | [[["\\"]]]) | |
145 | JSON_CHECK_NEGATIVE([stray backslash at end of string], | |
146 | [[["abcd\"]]], | |
147 | [error: unexpected end of input in quoted string]) | |
f38b84ea | 148 | |
99155935 | 149 | AT_SETUP([end of input in quoted string - C]) |
f38b84ea | 150 | AT_KEYWORDS([json negative]) |
eadd1644 | 151 | AT_CHECK([printf '"xxx' | ovstest test-json -], [1], |
0bdf342a | 152 | [error: line 0, column 4, byte 4: unexpected end of input in quoted string |
f38b84ea BP |
153 | ]) |
154 | AT_CLEANUP | |
155 | ||
99155935 BP |
156 | AT_SETUP([end of input in quoted string - Python]) |
157 | AT_KEYWORDS([json negative Python]) | |
158 | AT_SKIP_IF([test $HAVE_PYTHON = no]) | |
159 | AT_CHECK([printf '"xxx' > input | |
160 | $PYTHON $srcdir/test-json.py input], [1], | |
161 | [error: line 0, column 4, byte 4: unexpected end of input in quoted string | |
162 | ]) | |
163 | AT_CLEANUP | |
164 | ||
f38b84ea BP |
165 | AT_BANNER([JSON -- objects]) |
166 | ||
167 | JSON_CHECK_POSITIVE([empty object], [[{ }]], [[{}]]) | |
168 | JSON_CHECK_POSITIVE([simple object], | |
169 | [[{"b": 2, "a": 1, "c": 3}]], | |
170 | [[{"a":1,"b":2,"c":3}]]) | |
171 | JSON_CHECK_NEGATIVE([bad value], [[{"a": }, "b": 2]], | |
172 | [error: syntax error expecting value]) | |
173 | JSON_CHECK_NEGATIVE([missing colon], [[{"b": 2, "a" 1, "c": 3}]], | |
174 | [error: syntax error parsing object expecting ':']) | |
175 | JSON_CHECK_NEGATIVE([missing comma], [[{"b": 2 "a" 1, "c": 3}]], | |
176 | [error: syntax error expecting '}' or ',']) | |
177 | JSON_CHECK_NEGATIVE([trailing comma not allowed], | |
178 | [[{"b": 2, "a": 1, "c": 3, }]], | |
179 | [[error: syntax error parsing object expecting string]]) | |
180 | JSON_CHECK_NEGATIVE([doubled comma not allowed], | |
181 | [[{"b": 2, "a": 1,, "c": 3}]], | |
182 | [[error: syntax error parsing object expecting string]]) | |
183 | JSON_CHECK_NEGATIVE([names must be strings], | |
184 | [[{1: 2}]], | |
185 | [[error: syntax error parsing object expecting string]]) | |
186 | ||
187 | AT_BANNER([JSON -- literal names]) | |
188 | ||
189 | JSON_CHECK_POSITIVE([null], [[[ null ]]], [[[null]]]) | |
190 | JSON_CHECK_POSITIVE([false], [[[ false ]]], [[[false]]]) | |
191 | JSON_CHECK_POSITIVE([true], [[[ true ]]], [[[true]]]) | |
192 | JSON_CHECK_NEGATIVE([a literal by itself is not valid JSON], [null], | |
193 | [error: syntax error at beginning of input]) | |
194 | JSON_CHECK_NEGATIVE([nullify is invalid], [[[ nullify ]]], | |
195 | [error: invalid keyword 'nullify']) | |
196 | JSON_CHECK_NEGATIVE([nubs is invalid], [[[ nubs ]]], | |
197 | [error: invalid keyword 'nubs']) | |
198 | JSON_CHECK_NEGATIVE([xxx is invalid], [[[ xxx ]]], | |
199 | [error: invalid keyword 'xxx']) | |
200 | ||
201 | AT_BANNER([JSON -- numbers]) | |
202 | ||
203 | JSON_CHECK_POSITIVE( | |
204 | [integers expressed as reals], | |
205 | [[[1.0000000000, | |
206 | 2.00000000000000000000000000000000000, | |
207 | 2e5, | |
208 | 2.1234e4, | |
209 | 2.1230e3, | |
210 | 0e-10000, | |
211 | 0e10000]]], | |
212 | [[[1,2,200000,21234,2123,0,0]]]) | |
213 | JSON_CHECK_POSITIVE( | |
214 | [large integers], | |
215 | [[[9223372036854775807, -9223372036854775808]]], | |
216 | [[[9223372036854775807,-9223372036854775808]]]) | |
217 | JSON_CHECK_POSITIVE( | |
218 | [large integers expressed as reals], | |
219 | [[[9223372036854775807.0, -9223372036854775808.0, | |
220 | 92233720.36854775807e11, -9.223372036854775808e18]]], | |
221 | [[[9223372036854775807,-9223372036854775808,9223372036854775807,-9223372036854775808]]]) | |
222 | # It seems likely that the following test will fail on some system that | |
223 | # rounds slightly differently in arithmetic or in printf, but I'd like | |
224 | # to keep it this way until we run into such a system. | |
622749d8 TW |
225 | JSON_CHECK_POSITIVE_C( |
226 | [C - large integers that overflow to reals], | |
f38b84ea BP |
227 | [[[9223372036854775807000, -92233720368547758080000]]], |
228 | [[[9.22337203685478e+21,-9.22337203685478e+22]]]) | |
622749d8 TW |
229 | JSON_CHECK_POSITIVE_PY23( |
230 | [large integers that overflow to reals], | |
231 | [[[9223372036854775807000, -92233720368547758080000]]], | |
232 | [[[9.223372036854776e+21,-9.223372036854776e+22]]]) | |
f38b84ea BP |
233 | |
234 | JSON_CHECK_POSITIVE( | |
235 | [negative zero], | |
236 | [[[-0, -0.0, 1e-9999, -1e-9999]]], | |
237 | [[[0,0,0,0]]]) | |
238 | ||
239 | JSON_CHECK_POSITIVE( | |
240 | [reals], | |
241 | [[[0.0, 1.0, 2.0, 3.0, 3.5, 81.250]]], | |
242 | [[[0,1,2,3,3.5,81.25]]]) | |
243 | JSON_CHECK_POSITIVE( | |
244 | [scientific notation], | |
245 | [[[1e3, 1E3, 2.5E2, 1e+3, 125e-3, 3.125e-2, 3125e-05, 1.525878906e-5]]], | |
246 | [[[1000,1000,250,1000,0.125,0.03125,0.03125,1.525878906e-05]]]) | |
a105c27b BP |
247 | # It seems likely that the following test will fail on some system that |
248 | # rounds slightly differently in arithmetic or in printf, but I'd like | |
249 | # to keep it this way until we run into such a system. | |
622749d8 TW |
250 | JSON_CHECK_POSITIVE_C( |
251 | [C - +/- DBL_MAX], | |
a105c27b BP |
252 | [[[1.7976931348623157e+308, -1.7976931348623157e+308]]], |
253 | [[[1.79769313486232e+308,-1.79769313486232e+308]]]) | |
622749d8 TW |
254 | JSON_CHECK_POSITIVE_PY23( |
255 | [+/- DBL_MAX], | |
256 | [[[1.7976931348623157e+308, -1.7976931348623157e+308]]], | |
257 | [[[1.7976931348623157e+308,-1.7976931348623157e+308]]]) | |
a105c27b | 258 | |
f38b84ea BP |
259 | JSON_CHECK_POSITIVE( |
260 | [negative reals], | |
261 | [[[-0, -1.0, -2.0, -3.0, -3.5, -8.1250]]], | |
262 | [[[0,-1,-2,-3,-3.5,-8.125]]]) | |
263 | JSON_CHECK_POSITIVE( | |
264 | [negative scientific notation], | |
265 | [[[-1e3, -1E3, -2.5E2, -1e+3, -125e-3, -3.125e-2, -3125e-05, -1.525878906e-5]]], | |
266 | [[[-1000,-1000,-250,-1000,-0.125,-0.03125,-0.03125,-1.525878906e-05]]]) | |
267 | JSON_CHECK_POSITIVE( | |
268 | [1e-9999 underflows to 0], | |
269 | [[[1e-9999]]], | |
270 | [[[0]]]) | |
271 | JSON_CHECK_NEGATIVE([a number by itself is not valid JSON], [1], | |
272 | [error: syntax error at beginning of input]) | |
273 | JSON_CHECK_NEGATIVE( | |
274 | [leading zeros not allowed], | |
275 | [[[0123]]], | |
276 | [error: leading zeros not allowed]) | |
277 | JSON_CHECK_NEGATIVE( | |
278 | [1e9999 is too big], | |
279 | [[[1e9999]]], | |
280 | [error: number outside valid range]) | |
281 | JSON_CHECK_NEGATIVE( | |
282 | [exponent bigger than INT_MAX], | |
283 | [[[1e9999999999999999999]]], | |
284 | [error: exponent outside valid range]) | |
285 | JSON_CHECK_NEGATIVE( | |
286 | [decimal point must be followed by digit], | |
287 | [[[1.]]], | |
288 | [error: decimal point must be followed by digit]) | |
289 | JSON_CHECK_NEGATIVE( | |
290 | [exponent must contain at least one digit (1)], | |
291 | [[[1e]]], | |
292 | [error: exponent must contain at least one digit]) | |
293 | JSON_CHECK_NEGATIVE( | |
294 | [exponent must contain at least one digit (2)], | |
295 | [[[1e+]]], | |
296 | [error: exponent must contain at least one digit]) | |
297 | JSON_CHECK_NEGATIVE( | |
298 | [exponent must contain at least one digit (3)], | |
299 | [[[1e-]]], | |
300 | [error: exponent must contain at least one digit]) | |
301 | ||
302 | AT_BANNER([JSON -- RFC 4627 examples]) | |
303 | ||
304 | JSON_CHECK_POSITIVE([RFC 4267 object example], | |
305 | [[{ | |
306 | "Image": { | |
307 | "Width": 800, | |
308 | "Height": 600, | |
309 | "Title": "View from 15th Floor", | |
310 | "Thumbnail": { | |
311 | "Url": "http://www.example.com/image/481989943", | |
312 | "Height": 125, | |
313 | "Width": "100" | |
314 | }, | |
315 | "IDs": [116, 943, 234, 38793] | |
316 | } | |
317 | }]], | |
318 | [[{"Image":{"Height":600,"IDs":[116,943,234,38793],"Thumbnail":{"Height":125,"Url":"http://www.example.com/image/481989943","Width":"100"},"Title":"View from 15th Floor","Width":800}}]]) | |
319 | ||
320 | JSON_CHECK_POSITIVE([RFC 4267 array example], | |
321 | [[[ | |
322 | { | |
323 | "precision": "zip", | |
324 | "Latitude": 37.7668, | |
325 | "Longitude": -122.3959, | |
326 | "Address": "", | |
327 | "City": "SAN FRANCISCO", | |
328 | "State": "CA", | |
329 | "Zip": "94107", | |
330 | "Country": "US" | |
331 | }, | |
332 | { | |
333 | "precision": "zip", | |
334 | "Latitude": 37.371991, | |
335 | "Longitude": -122.026020, | |
336 | "Address": "", | |
337 | "City": "SUNNYVALE", | |
338 | "State": "CA", | |
339 | "Zip": "94085", | |
340 | "Country": "US" | |
341 | } | |
342 | ]]], | |
343 | [[[{"Address":"","City":"SAN FRANCISCO","Country":"US","Latitude":37.7668,"Longitude":-122.3959,"State":"CA","Zip":"94107","precision":"zip"},{"Address":"","City":"SUNNYVALE","Country":"US","Latitude":37.371991,"Longitude":-122.02602,"State":"CA","Zip":"94085","precision":"zip"}]]]) | |
344 | ||
345 | AT_BANNER([JSON -- pathological cases]) | |
346 | ||
347 | JSON_CHECK_NEGATIVE([trailing garbage], [[[1]null]], | |
348 | [error: trailing garbage at end of input]) | |
349 | JSON_CHECK_NEGATIVE([formfeeds are not valid white space], | |
350 | [[[\f]]], [error: invalid character U+000c]) | |
351 | JSON_CHECK_NEGATIVE([';' is not a valid token], | |
352 | [;], [error: invalid character ';']) | |
353 | JSON_CHECK_NEGATIVE([arrays nesting too deep], | |
354 | [m4_for([i], [0], [1002], [1], [@<:@])dnl | |
355 | m4_for([i], [0], [1002], [1], [@:>@])], | |
356 | [error: input exceeds maximum nesting depth 1000]) | |
357 | JSON_CHECK_NEGATIVE([objects nesting too deep], | |
358 | [m4_for([i], [0], [1002], [1], [{"x":])dnl | |
359 | m4_for([i], [0], [1002], [1], [}])], | |
360 | [error: input exceeds maximum nesting depth 1000]) | |
361 | ||
362 | AT_SETUP([input may not be empty]) | |
363 | AT_KEYWORDS([json negative]) | |
eadd1644 | 364 | AT_CHECK([ovstest test-json /dev/null], [1], [error: line 0, column 0, byte 0: empty input stream |
f38b84ea BP |
365 | ]) |
366 | AT_CLEANUP | |
367 | ||
368 | AT_BANNER([JSON -- multiple inputs]) | |
369 | ||
370 | JSON_CHECK_POSITIVE([multiple adjacent objects], [[{}{}{}]], [[{} | |
371 | {} | |
372 | {}]], | |
373 | [--multiple]) | |
374 | ||
375 | JSON_CHECK_POSITIVE([multiple space-separated objects], [[{} {} {}]], [[{} | |
376 | {} | |
377 | {}]], | |
378 | [--multiple]) | |
379 | ||
380 | JSON_CHECK_POSITIVE([multiple objects on separate lines], [[{} | |
381 | {} | |
382 | {}]], [[{} | |
383 | {} | |
384 | {}]], | |
385 | [--multiple]) | |
386 | ||
387 | JSON_CHECK_POSITIVE([multiple objects and arrays], [[{}[]{}[]]], [[{} | |
388 | [] | |
389 | {} | |
390 | []]], | |
391 | [--multiple]) | |
392 | ||
393 | JSON_CHECK_NEGATIVE([garbage between multiple objects], [[{}x{}]], [[{} | |
394 | error: invalid keyword 'x' | |
395 | {}]], [--multiple]) | |
396 | ||
397 | JSON_CHECK_NEGATIVE([garbage after multiple objects], [[{}{}x]], [[{} | |
398 | {} | |
399 | error: invalid keyword 'x']], [--multiple]) |