| | varnish-cache/lib/libvarnish/vjsn.c |
0 |
|
/*- |
1 |
|
* Copyright (c) 2017 Varnish Software AS |
2 |
|
* All rights reserved. |
3 |
|
* |
4 |
|
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk> |
5 |
|
* |
6 |
|
* SPDX-License-Identifier: BSD-2-Clause |
7 |
|
* |
8 |
|
* Redistribution and use in source and binary forms, with or without |
9 |
|
* modification, are permitted provided that the following conditions |
10 |
|
* are met: |
11 |
|
* 1. Redistributions of source code must retain the above copyright |
12 |
|
* notice, this list of conditions and the following disclaimer. |
13 |
|
* 2. Redistributions in binary form must reproduce the above copyright |
14 |
|
* notice, this list of conditions and the following disclaimer in the |
15 |
|
* documentation and/or other materials provided with the distribution. |
16 |
|
* |
17 |
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
18 |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 |
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE |
21 |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 |
|
* SUCH DAMAGE. |
28 |
|
*/ |
29 |
|
|
30 |
|
#include "config.h" |
31 |
|
|
32 |
|
#include <fcntl.h> |
33 |
|
#include <stdio.h> |
34 |
|
#include <string.h> |
35 |
|
#include <stdlib.h> |
36 |
|
#include <unistd.h> |
37 |
|
|
38 |
|
#include "vdef.h" |
39 |
|
|
40 |
|
#include "vas.h" |
41 |
|
#include "miniobj.h" |
42 |
|
#include "vqueue.h" |
43 |
|
#include "vjsn.h" |
44 |
|
|
45 |
|
#define VJSN_TYPE_MACRO(UPPER, lower) \ |
46 |
|
static const char VJSN_##UPPER[] = #lower; |
47 |
|
VJSN_TYPES |
48 |
|
#undef VJSN_TYPE_MACRO |
49 |
|
|
50 |
|
#define VJSN_EXPECT(js, xxx, ret) \ |
51 |
|
do { \ |
52 |
|
AZ(js->err); \ |
53 |
|
if (*((js)->ptr) != xxx) { \ |
54 |
|
js->err = "Expected " #xxx " not found."; \ |
55 |
|
return (ret); \ |
56 |
|
} else { \ |
57 |
|
*js->ptr++ = '\0'; \ |
58 |
|
} \ |
59 |
|
} while (0) |
60 |
|
|
61 |
|
static struct vjsn_val *vjsn_value(struct vjsn *); |
62 |
|
|
63 |
|
static struct vjsn_val * |
64 |
34792021 |
vjsn_val_new(const char *type) |
65 |
|
{ |
66 |
|
struct vjsn_val *jsv; |
67 |
|
|
68 |
34792021 |
ALLOC_OBJ(jsv, VJSN_VAL_MAGIC); |
69 |
34792021 |
AN(jsv); |
70 |
34792021 |
VTAILQ_INIT(&jsv->children); |
71 |
34792021 |
jsv->type = type; |
72 |
34792021 |
return (jsv); |
73 |
|
} |
74 |
|
|
75 |
|
static void |
76 |
15588541 |
vjsn_val_delete(struct vjsn_val *jsv) |
77 |
|
{ |
78 |
|
struct vjsn_val *jsve; |
79 |
|
|
80 |
15588541 |
CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC); |
81 |
15588541 |
do { |
82 |
31086694 |
jsve = VTAILQ_FIRST(&jsv->children); |
83 |
31086694 |
if (jsve != NULL) { |
84 |
15498153 |
VTAILQ_REMOVE(&jsv->children, jsve, list); |
85 |
15498153 |
vjsn_val_delete(jsve); |
86 |
15498153 |
} |
87 |
31086694 |
} while (jsve != NULL); |
88 |
15588541 |
FREE_OBJ(jsv); |
89 |
15588541 |
} |
90 |
|
|
91 |
|
void |
92 |
88748 |
vjsn_delete(struct vjsn **jp) |
93 |
|
{ |
94 |
|
struct vjsn *js; |
95 |
|
|
96 |
88748 |
TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC); |
97 |
88748 |
if (js->value != NULL) |
98 |
88228 |
vjsn_val_delete(js->value); |
99 |
88748 |
free(js->raw); |
100 |
88748 |
FREE_OBJ(js); |
101 |
88748 |
} |
102 |
|
|
103 |
|
static void |
104 |
134262900 |
vjsn_skip_ws(struct vjsn *js) |
105 |
|
{ |
106 |
|
char c; |
107 |
|
|
108 |
134262900 |
while (1) { |
109 |
289905140 |
c = js->ptr[0]; |
110 |
289905140 |
if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) { |
111 |
155642240 |
*js->ptr++ = '\0'; |
112 |
155642240 |
continue; |
113 |
|
} |
114 |
|
#ifdef VJSN_COMMENTS |
115 |
|
if (c == '/' && js->ptr[1] == '*') { |
116 |
|
js->ptr += 2; |
117 |
|
while (js->ptr[0] != '*' || js->ptr[1] != '/') |
118 |
|
js->ptr++; |
119 |
|
js->ptr += 2; |
120 |
|
continue; |
121 |
|
} |
122 |
|
#endif |
123 |
134262900 |
return; |
124 |
|
} |
125 |
|
} |
126 |
|
|
127 |
|
static unsigned |
128 |
2760 |
vjsn_unumber(struct vjsn *js) |
129 |
|
{ |
130 |
2760 |
unsigned u = 0; |
131 |
|
char c; |
132 |
|
int i; |
133 |
|
|
134 |
2760 |
VJSN_EXPECT(js, '\\', 0); |
135 |
2760 |
VJSN_EXPECT(js, 'u', 0); |
136 |
12760 |
for (i = 0; i < 4; i++) { |
137 |
10320 |
u <<= 4; |
138 |
10320 |
c = *js->ptr; |
139 |
10320 |
if (c >= '0' && c <= '9') |
140 |
6560 |
u |= c - '0'; /*lint !e737 */ |
141 |
3760 |
else if (c >= 'A' && c <= 'F') |
142 |
2360 |
u |= c - '7'; /*lint !e737 */ |
143 |
1400 |
else if (c >= 'a' && c <= 'f') |
144 |
1120 |
u |= c - 'W'; /*lint !e737 */ |
145 |
|
else { |
146 |
280 |
js->err = "Illegal \\uXXXX sequence"; |
147 |
280 |
return (0); |
148 |
|
} |
149 |
10040 |
js->ptr++; |
150 |
10040 |
} |
151 |
2440 |
return (u); |
152 |
2760 |
} |
153 |
|
|
154 |
|
static void |
155 |
2240 |
vjsn_unicode(struct vjsn *js, char **d) |
156 |
|
{ |
157 |
|
unsigned u1, u2; |
158 |
|
|
159 |
2240 |
u1 = vjsn_unumber(js); |
160 |
2240 |
if (js->err) |
161 |
120 |
return; |
162 |
|
|
163 |
2120 |
if (u1 >= 0xdc00 && u1 <= 0xdfff) { |
164 |
40 |
js->err = "Lone second UTF-16 Surrogate"; |
165 |
40 |
return; |
166 |
|
} |
167 |
2080 |
if (u1 >= 0xd800 && u1 <= 0xdc00) { |
168 |
520 |
u2 = vjsn_unumber(js); |
169 |
520 |
if (u2 < 0xdc00 || u2 > 0xdfff) { |
170 |
240 |
js->err = "Bad UTF-16 Surrogate pair"; |
171 |
240 |
return; |
172 |
|
} |
173 |
280 |
u1 -= 0xd800; |
174 |
280 |
u2 -= 0xdc00; |
175 |
280 |
u1 <<= 10; |
176 |
280 |
u1 |= u2; |
177 |
280 |
u1 |= 0x10000; |
178 |
280 |
} |
179 |
1840 |
assert(u1 < 0x110000); |
180 |
|
/*lint -save -e734 -e713 */ |
181 |
1840 |
if (u1 < 0x80) |
182 |
360 |
*(*d)++ = u1; |
183 |
1480 |
else if (u1 < 0x800) { |
184 |
760 |
*(*d)++ = 0xc0 + u1 / 64; |
185 |
760 |
*(*d)++ = 0x80 + u1 % 64; |
186 |
1480 |
} else if (u1 < 0x10000) { |
187 |
440 |
*(*d)++ = 0xe0 + u1 / 4096; |
188 |
440 |
*(*d)++ = 0x80 + u1 / 64 % 64; |
189 |
440 |
*(*d)++ = 0x80 + u1 % 64; |
190 |
440 |
} else { |
191 |
280 |
*(*d)++ = 0xf0 + u1 / 262144; |
192 |
280 |
*(*d)++ = 0x80 + u1 / 4096 % 64; |
193 |
280 |
*(*d)++ = 0x80 + u1 / 64 % 64; |
194 |
280 |
*(*d)++ = 0x80 + u1 % 64; |
195 |
|
} |
196 |
|
/*lint -restore */ |
197 |
2240 |
} |
198 |
|
|
199 |
|
static char * |
200 |
41788396 |
vjsn_string(struct vjsn *js, char **e) |
201 |
|
{ |
202 |
|
char *p, *b; |
203 |
|
|
204 |
41788396 |
AN(e); |
205 |
41788396 |
vjsn_skip_ws(js); |
206 |
41788396 |
VJSN_EXPECT(js, '"', NULL); |
207 |
41787596 |
b = p = js->ptr; |
208 |
585574387 |
while (*js->ptr != '"') { |
209 |
543787911 |
if (*js->ptr == '\0') { |
210 |
280 |
js->err = "Unterminated string"; |
211 |
280 |
return (NULL); |
212 |
|
} |
213 |
543787631 |
if ((unsigned char)(*js->ptr) <= 0x1f) { |
214 |
120 |
js->err = "Unescaped control char in string"; |
215 |
120 |
return (NULL); |
216 |
|
} |
217 |
543787511 |
if (*js->ptr != '\\') { |
218 |
534728438 |
*p++ = *js->ptr++; |
219 |
534728438 |
continue; |
220 |
|
} |
221 |
9059073 |
switch (js->ptr[1]) { |
222 |
|
case '\\': |
223 |
|
case '/': |
224 |
111960 |
case '"': *p++ = js->ptr[1]; js->ptr += 2; break; |
225 |
40 |
case 'b': *p++ = 0x08; js->ptr += 2; break; |
226 |
40 |
case 'f': *p++ = 0x0c; js->ptr += 2; break; |
227 |
8023969 |
case 't': *p++ = 0x09; js->ptr += 2; break; |
228 |
920464 |
case 'n': *p++ = 0x0a; js->ptr += 2; break; |
229 |
40 |
case 'r': *p++ = 0x0d; js->ptr += 2; break; |
230 |
|
case 'u': |
231 |
2240 |
vjsn_unicode(js, &p); |
232 |
2240 |
if (js->err != NULL) |
233 |
400 |
return (NULL); |
234 |
1840 |
break; |
235 |
|
default: |
236 |
320 |
js->err = "Bad string escape"; |
237 |
320 |
return (NULL); |
238 |
|
} |
239 |
|
} |
240 |
41786476 |
VJSN_EXPECT(js, '"', NULL); |
241 |
41786476 |
*p = '\0'; |
242 |
41786476 |
*e = p; |
243 |
41786476 |
return (b); |
244 |
41788396 |
} |
245 |
|
|
246 |
|
static struct vjsn_val * |
247 |
1880989 |
vjsn_object(struct vjsn *js) |
248 |
|
{ |
249 |
|
struct vjsn_val *jsv, *jsve; |
250 |
|
char *s, *e; |
251 |
|
|
252 |
1880989 |
VJSN_EXPECT(js, '{', NULL); |
253 |
|
|
254 |
1880989 |
jsv = vjsn_val_new(VJSN_OBJECT); |
255 |
1880989 |
AN(jsv); |
256 |
|
|
257 |
1880989 |
vjsn_skip_ws(js); |
258 |
1880989 |
if (*js->ptr != '}') { |
259 |
16382033 |
while (1) { |
260 |
16382033 |
s = vjsn_string(js, &e); |
261 |
16382033 |
if (js->err != NULL) |
262 |
840 |
return (jsv); |
263 |
16381193 |
vjsn_skip_ws(js); |
264 |
16381193 |
VJSN_EXPECT(js, ':', jsv); |
265 |
16380993 |
jsve = vjsn_value(js); |
266 |
16380993 |
if (js->err != NULL) { |
267 |
200 |
if (jsve != NULL) |
268 |
40 |
vjsn_val_delete(jsve); |
269 |
200 |
return (jsv); |
270 |
|
} |
271 |
16380793 |
CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC); |
272 |
16380793 |
jsve->name = s; |
273 |
16380793 |
jsve->name_e = e; |
274 |
16380793 |
VTAILQ_INSERT_TAIL(&jsv->children, jsve, list); |
275 |
16380793 |
vjsn_skip_ws(js); |
276 |
16380793 |
if (*js->ptr == '}') |
277 |
1879389 |
break; |
278 |
14501404 |
VJSN_EXPECT(js, ',', jsv); |
279 |
|
} |
280 |
1879389 |
} |
281 |
1879669 |
VJSN_EXPECT(js, '}', jsv); |
282 |
1879669 |
return (jsv); |
283 |
1880989 |
} |
284 |
|
|
285 |
|
static struct vjsn_val * |
286 |
4634200 |
vjsn_array(struct vjsn *js) |
287 |
|
{ |
288 |
|
struct vjsn_val *jsv, *jsve; |
289 |
|
|
290 |
4634200 |
VJSN_EXPECT(js, '[', NULL); |
291 |
|
|
292 |
4634200 |
jsv = vjsn_val_new(VJSN_ARRAY); |
293 |
4634200 |
AN(jsv); |
294 |
|
|
295 |
4634200 |
vjsn_skip_ws(js); |
296 |
4634200 |
if (*js->ptr != ']') { |
297 |
18297560 |
while (1) { |
298 |
18297560 |
jsve = vjsn_value(js); |
299 |
18297560 |
if (js->err != NULL) { |
300 |
3880 |
if (jsve != NULL) |
301 |
2120 |
vjsn_val_delete(jsve); |
302 |
3880 |
return (jsv); |
303 |
|
} |
304 |
18293680 |
CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC); |
305 |
18293680 |
VTAILQ_INSERT_TAIL(&jsv->children, jsve, list); |
306 |
18293680 |
vjsn_skip_ws(js); |
307 |
18293680 |
if (*js->ptr == ']') |
308 |
4626360 |
break; |
309 |
13667320 |
VJSN_EXPECT(js, ',', jsv); |
310 |
|
} |
311 |
4626360 |
} |
312 |
4629400 |
VJSN_EXPECT(js, ']', jsv); |
313 |
4629400 |
return (jsv); |
314 |
4634200 |
} |
315 |
|
|
316 |
|
static struct vjsn_val * |
317 |
1818629 |
vjsn_number(struct vjsn *js) |
318 |
|
{ |
319 |
|
struct vjsn_val *jsv; |
320 |
|
|
321 |
1818629 |
jsv = vjsn_val_new(VJSN_NUMBER); |
322 |
1818629 |
AN(jsv); |
323 |
|
|
324 |
1818629 |
jsv->value = js->ptr; |
325 |
|
|
326 |
1818629 |
if (*js->ptr == '-') |
327 |
1320 |
js->ptr++; |
328 |
1818629 |
if (*js->ptr < '0' || *js->ptr > '9') { |
329 |
240 |
js->err = "Bad number"; |
330 |
240 |
return (jsv); |
331 |
|
} |
332 |
1818389 |
if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') { |
333 |
120 |
js->err = "Bad number"; |
334 |
120 |
return (jsv); |
335 |
|
} |
336 |
6984115 |
while (*js->ptr >= '0' && *js->ptr <= '9') |
337 |
5165846 |
js->ptr++; |
338 |
1818269 |
if (*js->ptr == '.') { |
339 |
7160 |
js->ptr++; |
340 |
7160 |
if (*js->ptr < '0' || *js->ptr > '9') { |
341 |
280 |
js->err = "Bad number"; |
342 |
280 |
return (jsv); |
343 |
|
} |
344 |
34400 |
while (*js->ptr >= '0' && *js->ptr <= '9') |
345 |
27520 |
js->ptr++; |
346 |
6880 |
} |
347 |
1817989 |
if (*js->ptr == 'e' || *js->ptr == 'E') { |
348 |
1080 |
js->ptr++; |
349 |
1080 |
if (*js->ptr == '-' || *js->ptr == '+') |
350 |
520 |
js->ptr++; |
351 |
1080 |
if (*js->ptr < '0' || *js->ptr > '9') { |
352 |
520 |
js->err = "Bad number"; |
353 |
520 |
return (jsv); |
354 |
|
} |
355 |
1360 |
while (*js->ptr >= '0' && *js->ptr <= '9') |
356 |
800 |
js->ptr++; |
357 |
560 |
} |
358 |
|
/* |
359 |
|
* The terminating NUL is supplied by the caller, once they |
360 |
|
* have decided if they like what occupies that spot. |
361 |
|
*/ |
362 |
1817469 |
return (jsv); |
363 |
1818629 |
} |
364 |
|
|
365 |
|
static struct vjsn_val * |
366 |
34794461 |
vjsn_value(struct vjsn *js) |
367 |
|
{ |
368 |
|
struct vjsn_val *jsv; |
369 |
|
|
370 |
34794461 |
AZ(js->err); |
371 |
34794461 |
vjsn_skip_ws(js); |
372 |
34794461 |
if (*js->ptr == '{') |
373 |
1880989 |
return (vjsn_object(js)); |
374 |
32913472 |
if (*js->ptr== '[') |
375 |
4634200 |
return (vjsn_array(js)); |
376 |
28279272 |
if (*js->ptr== '"') { |
377 |
25406363 |
jsv = vjsn_val_new(VJSN_STRING); |
378 |
25406363 |
jsv->value = vjsn_string(js, &jsv->value_e); |
379 |
25406363 |
if (js->err != NULL) |
380 |
1080 |
return (jsv); |
381 |
25405283 |
AN(jsv->value); |
382 |
25405283 |
return (jsv); |
383 |
|
} |
384 |
2872909 |
if (!strncmp(js->ptr, "true", 4)) { |
385 |
313800 |
js->ptr += 4; |
386 |
313800 |
return (vjsn_val_new(VJSN_TRUE)); |
387 |
|
} |
388 |
2559109 |
if (!strncmp(js->ptr, "false", 5)) { |
389 |
82160 |
js->ptr += 5; |
390 |
82160 |
return (vjsn_val_new(VJSN_FALSE)); |
391 |
|
} |
392 |
2476949 |
if (!strncmp(js->ptr, "null", 4)) { |
393 |
655880 |
js->ptr += 4; |
394 |
655880 |
return (vjsn_val_new(VJSN_NULL)); |
395 |
|
} |
396 |
1821069 |
if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9')) |
397 |
1818629 |
return (vjsn_number(js)); |
398 |
2440 |
js->err = "Unrecognized value"; |
399 |
2440 |
return (NULL); |
400 |
34794461 |
} |
401 |
|
|
402 |
|
struct vjsn * |
403 |
115908 |
vjsn_parse_end(const char *from, const char *to, const char **err) |
404 |
|
{ |
405 |
|
struct vjsn *js; |
406 |
|
char *p, *e; |
407 |
|
size_t sz; |
408 |
|
|
409 |
115908 |
AN(from); |
410 |
|
|
411 |
115908 |
AN(err); |
412 |
115908 |
*err = NULL; |
413 |
|
|
414 |
115908 |
if (to == NULL) |
415 |
115908 |
to = strchr(from, '\0'); |
416 |
115908 |
AN(to); |
417 |
|
|
418 |
115908 |
sz = to - from; |
419 |
|
|
420 |
115908 |
p = malloc(sz + 1L); |
421 |
115908 |
AN(p); |
422 |
115908 |
memcpy(p, from, sz); |
423 |
115908 |
p[sz] = '\0'; |
424 |
115908 |
e = p + sz; |
425 |
|
|
426 |
115908 |
ALLOC_OBJ(js, VJSN_MAGIC); |
427 |
115908 |
AN(js); |
428 |
115908 |
js->raw = p; |
429 |
115908 |
js->ptr = p; |
430 |
|
|
431 |
115908 |
js->value = vjsn_value(js); |
432 |
115908 |
if (js->err != NULL) { |
433 |
6720 |
*err = js->err; |
434 |
6720 |
vjsn_delete(&js); |
435 |
6720 |
return (NULL); |
436 |
|
} |
437 |
|
|
438 |
109188 |
vjsn_skip_ws(js); |
439 |
109188 |
if (js->ptr != e) { |
440 |
640 |
*err = "Garbage after value"; |
441 |
640 |
vjsn_delete(&js); |
442 |
640 |
return (NULL); |
443 |
|
} |
444 |
108548 |
return (js); |
445 |
115908 |
} |
446 |
|
|
447 |
|
struct vjsn * |
448 |
115908 |
vjsn_parse(const char *src, const char **err) |
449 |
|
{ |
450 |
|
|
451 |
115908 |
return (vjsn_parse_end(src, NULL, err)); |
452 |
|
} |
453 |
|
|
454 |
|
struct vjsn_val * |
455 |
16495746 |
vjsn_child(const struct vjsn_val *vv, const char *key) |
456 |
|
{ |
457 |
|
struct vjsn_val *vc; |
458 |
|
|
459 |
16495746 |
CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC); |
460 |
16495746 |
AN(key); |
461 |
77818241 |
VTAILQ_FOREACH(vc, &vv->children, list) { |
462 |
77770121 |
if (vc->name != NULL && !strcmp(vc->name, key)) |
463 |
16447626 |
return (vc); |
464 |
61322495 |
} |
465 |
48120 |
return (NULL); |
466 |
16495746 |
} |
467 |
|
|
468 |
|
static void |
469 |
7720 |
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent) |
470 |
|
{ |
471 |
|
struct vjsn_val *jsve; |
472 |
|
|
473 |
7720 |
CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC); |
474 |
7720 |
printf("%*s", indent, ""); |
475 |
7720 |
if (jsv->name != NULL) |
476 |
680 |
printf("[\"%s\"]: ", jsv->name); |
477 |
7720 |
printf("{%s}", jsv->type); |
478 |
7720 |
if (jsv->value != NULL) { |
479 |
3640 |
if (strlen(jsv->value) < 20) |
480 |
3480 |
printf(" <%s", jsv->value); |
481 |
|
else |
482 |
160 |
printf(" <%.10s[...#%zu]", |
483 |
160 |
jsv->value, strlen(jsv->value + 10)); |
484 |
3640 |
printf(">"); |
485 |
3640 |
} |
486 |
7720 |
printf("\n"); |
487 |
11640 |
VTAILQ_FOREACH(jsve, &jsv->children, list) |
488 |
3920 |
vjsn_dump_i(jsve, fo, indent + 2); |
489 |
7720 |
} |
490 |
|
|
491 |
|
void |
492 |
0 |
vjsn_dump_val(const struct vjsn_val *jsv, FILE *fo) |
493 |
|
{ |
494 |
0 |
CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC); |
495 |
0 |
vjsn_dump_i(jsv, fo, 0); |
496 |
0 |
} |
497 |
|
|
498 |
|
void |
499 |
3800 |
vjsn_dump(const struct vjsn *js, FILE *fo) |
500 |
|
{ |
501 |
|
|
502 |
3800 |
CHECK_OBJ_NOTNULL(js, VJSN_MAGIC); |
503 |
3800 |
AN(fo); |
504 |
3800 |
vjsn_dump_i(js->value, fo, 0); |
505 |
3800 |
} |
506 |
|
|
507 |
|
#define VJSN_TYPE_MACRO(UPPER, lower) \ |
508 |
|
int \ |
509 |
|
vjsn_is_##lower(const struct vjsn_val *jsv) \ |
510 |
|
{ \ |
511 |
|
CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC); \ |
512 |
|
return (jsv->type == VJSN_##UPPER); \ |
513 |
|
} |
514 |
31969691 |
VJSN_TYPES |
515 |
|
#undef VJSN_TYPE_MACRO |
516 |
|
|
517 |
|
|
518 |
|
#ifdef VJSN_TEST |
519 |
|
|
520 |
|
/* |
521 |
|
* Test-cases by Nicolas Seriot |
522 |
|
* |
523 |
|
* See: http://seriot.ch/parsing_json.php |
524 |
|
* |
525 |
|
* MIT License |
526 |
|
* |
527 |
|
* Copyright (c) 2016 Nicolas Seriot |
528 |
|
* |
529 |
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
530 |
|
* of this software and associated documentation files (the "Software"), to deal |
531 |
|
* in the Software without restriction, including without limitation the rights |
532 |
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
533 |
|
* copies of the Software, and to permit persons to whom the Software is |
534 |
|
* furnished to do so, subject to the following conditions: |
535 |
|
* |
536 |
|
* The above copyright notice and this permission notice shall be included in |
537 |
|
* all copies or substantial portions of the Software. |
538 |
|
* |
539 |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
540 |
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
541 |
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
542 |
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
543 |
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
544 |
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
545 |
|
* SOFTWARE. |
546 |
|
* |
547 |
|
* We skip tests containing NUL, because we're lazy (The code will actually |
548 |
|
* pass these tests if you provide for a way to pass the true length of the |
549 |
|
* input to it, and we skip really huge tests, because we are only limited |
550 |
|
* by available memory. |
551 |
|
* |
552 |
|
* To produce the C-data-structures: |
553 |
|
* |
554 |
|
* Clone https://github.com/nst/JSONTestSuite.git |
555 |
|
* |
556 |
|
* And run this python in test_parsing: |
557 |
|
|
558 |
|
import glob |
559 |
|
|
560 |
|
skip = {} |
561 |
|
|
562 |
|
def emit(fin): |
563 |
|
if fin in skip: |
564 |
|
return |
565 |
|
x = bytearray(open(fin).read()) |
566 |
|
if 0 in x: |
567 |
|
return |
568 |
|
if len(x) > 1000: |
569 |
|
return |
570 |
|
t = '\t"' |
571 |
|
for i in x: |
572 |
|
t += "\\x%02x" % i |
573 |
|
if len(t) > 64: |
574 |
|
print(t + '"') |
575 |
|
t = '\t"' |
576 |
|
print(t + '",') |
577 |
|
|
578 |
|
print("const char *good[] = {") |
579 |
|
l = list(glob.glob("y_*")) |
580 |
|
l.sort() |
581 |
|
for f in l: |
582 |
|
emit(f) |
583 |
|
print("\tNULL") |
584 |
|
print("};") |
585 |
|
|
586 |
|
print("const char *bad[] = {") |
587 |
|
l = list(glob.glob("n_*")) |
588 |
|
l.sort() |
589 |
|
for f in l: |
590 |
|
emit(f) |
591 |
|
print("\tNULL") |
592 |
|
print("};") |
593 |
|
*/ |
594 |
|
|
595 |
|
static const char *good[] = { |
596 |
|
"\x5b\x5b\x5d\x20\x20\x20\x5d", |
597 |
|
"\x5b\x22\x22\x5d", |
598 |
|
"\x5b\x5d", |
599 |
|
"\x5b\x22\x61\x22\x5d", |
600 |
|
"\x5b\x66\x61\x6c\x73\x65\x5d", |
601 |
|
"\x5b\x6e\x75\x6c\x6c\x2c\x20\x31\x2c\x20\x22\x31\x22\x2c\x20\x7b" |
602 |
|
"\x7d\x5d", |
603 |
|
"\x5b\x6e\x75\x6c\x6c\x5d", |
604 |
|
"\x5b\x31\x0a\x5d", |
605 |
|
"\x20\x5b\x31\x5d", |
606 |
|
"\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c" |
607 |
|
"\x6c\x2c\x32\x5d", |
608 |
|
"\x5b\x32\x5d\x20", |
609 |
|
"\x5b\x31\x32\x33\x65\x36\x35\x5d", |
610 |
|
"\x5b\x30\x65\x2b\x31\x5d", |
611 |
|
"\x5b\x30\x65\x31\x5d", |
612 |
|
"\x5b\x20\x34\x5d", |
613 |
|
"\x5b\x2d\x30\x2e\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" |
614 |
|
"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" |
615 |
|
"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" |
616 |
|
"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" |
617 |
|
"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30" |
618 |
|
"\x30\x31\x5d\x0a", |
619 |
|
"\x5b\x32\x30\x65\x31\x5d", |
620 |
|
"\x5b\x2d\x30\x5d", |
621 |
|
"\x5b\x2d\x31\x32\x33\x5d", |
622 |
|
"\x5b\x2d\x31\x5d", |
623 |
|
"\x5b\x2d\x30\x5d", |
624 |
|
"\x5b\x31\x45\x32\x32\x5d", |
625 |
|
"\x5b\x31\x45\x2d\x32\x5d", |
626 |
|
"\x5b\x31\x45\x2b\x32\x5d", |
627 |
|
"\x5b\x31\x32\x33\x65\x34\x35\x5d", |
628 |
|
"\x5b\x31\x32\x33\x2e\x34\x35\x36\x65\x37\x38\x5d", |
629 |
|
"\x5b\x31\x65\x2d\x32\x5d", |
630 |
|
"\x5b\x31\x65\x2b\x32\x5d", |
631 |
|
"\x5b\x31\x32\x33\x5d", |
632 |
|
"\x5b\x31\x32\x33\x2e\x34\x35\x36\x37\x38\x39\x5d", |
633 |
|
"\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x2c\x20\x22\x64" |
634 |
|
"\x66\x67\x22\x3a\x22\x66\x67\x68\x22\x7d", |
635 |
|
"\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x7d", |
636 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x63\x22" |
637 |
|
"\x7d", |
638 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x62\x22" |
639 |
|
"\x7d", |
640 |
|
"\x7b\x7d", |
641 |
|
"\x7b\x22\x22\x3a\x30\x7d", |
642 |
|
"\x7b\x22\x66\x6f\x6f\x5c\x75\x30\x30\x30\x30\x62\x61\x72\x22\x3a" |
643 |
|
"\x20\x34\x32\x7d", |
644 |
|
"\x7b\x20\x22\x6d\x69\x6e\x22\x3a\x20\x2d\x31\x2e\x30\x65\x2b\x32" |
645 |
|
"\x38\x2c\x20\x22\x6d\x61\x78\x22\x3a\x20\x31\x2e\x30\x65\x2b\x32" |
646 |
|
"\x38\x20\x7d", |
647 |
|
"\x7b\x22\x78\x22\x3a\x5b\x7b\x22\x69\x64\x22\x3a\x20\x22\x78\x78" |
648 |
|
"\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78" |
649 |
|
"\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78" |
650 |
|
"\x78\x78\x78\x78\x78\x78\x22\x7d\x5d\x2c\x20\x22\x69\x64\x22\x3a" |
651 |
|
"\x20\x22\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78" |
652 |
|
"\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78" |
653 |
|
"\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x22\x7d", |
654 |
|
"\x7b\x22\x61\x22\x3a\x5b\x5d\x7d", |
655 |
|
"\x7b\x22\x74\x69\x74\x6c\x65\x22\x3a\x22\x5c\x75\x30\x34\x31\x66" |
656 |
|
"\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x33\x62\x5c\x75\x30\x34" |
657 |
|
"\x34\x32\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x34\x30\x5c\x75" |
658 |
|
"\x30\x34\x33\x30\x20\x5c\x75\x30\x34\x31\x37\x5c\x75\x30\x34\x33" |
659 |
|
"\x35\x5c\x75\x30\x34\x33\x63\x5c\x75\x30\x34\x33\x62\x5c\x75\x30" |
660 |
|
"\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c" |
661 |
|
"\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d", |
662 |
|
"\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d", |
663 |
|
"\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75" |
664 |
|
"\x31\x32\x41\x42\x22\x5d", |
665 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d" |
666 |
|
"", |
667 |
|
"\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75" |
668 |
|
"\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d", |
669 |
|
"\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72" |
670 |
|
"\x5c\x74\x22\x5d", |
671 |
|
"\x5b\x22\x5c\x5c\x75\x30\x30\x30\x30\x22\x5d", |
672 |
|
"\x5b\x22\x5c\x22\x22\x5d", |
673 |
|
"\x5b\x22\x61\x2f\x2a\x62\x2a\x2f\x63\x2f\x2a\x64\x2f\x2f\x65\x22" |
674 |
|
"\x5d", |
675 |
|
"\x5b\x22\x5c\x5c\x61\x22\x5d", |
676 |
|
"\x5b\x22\x5c\x5c\x6e\x22\x5d", |
677 |
|
"\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d", |
678 |
|
"\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d", |
679 |
|
"\x5b\x22\x61\x73\x64\x22\x5d", |
680 |
|
"\x5b\x20\x22\x61\x73\x64\x22\x5d", |
681 |
|
"\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d" |
682 |
|
"", |
683 |
|
"\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22" |
684 |
|
"\x5d", |
685 |
|
"\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d", |
686 |
|
"\x5b\x22\xef\xbf\xbf\x22\x5d", |
687 |
|
"\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d", |
688 |
|
"\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d", |
689 |
|
"\x5b\x22\xcf\x80\x22\x5d", |
690 |
|
"\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d", |
691 |
|
"\x5b\x22\x61\x73\x64\x20\x22\x5d", |
692 |
|
"\x22\x20\x22", |
693 |
|
"\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d" |
694 |
|
"", |
695 |
|
"\x5b\x22\x5c\x75\x30\x38\x32\x31\x22\x5d", |
696 |
|
"\x5b\x22\x5c\x75\x30\x31\x32\x33\x22\x5d", |
697 |
|
"\x5b\x22\xe2\x80\xa8\x22\x5d", |
698 |
|
"\x5b\x22\xe2\x80\xa9\x22\x5d", |
699 |
|
"\x5b\x22\x5c\x75\x30\x30\x36\x31\x5c\x75\x33\x30\x61\x66\x5c\x75" |
700 |
|
"\x33\x30\x45\x41\x5c\x75\x33\x30\x62\x39\x22\x5d", |
701 |
|
"\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x30\x41\x6c\x69\x6e\x65\x22" |
702 |
|
"\x5d", |
703 |
|
"\x5b\x22\x7f\x22\x5d", |
704 |
|
"\x5b\x22\x5c\x75\x41\x36\x36\x44\x22\x5d", |
705 |
|
"\x5b\x22\x5c\x75\x30\x30\x35\x43\x22\x5d", |
706 |
|
"\x5b\x22\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82\x22\x5d", |
707 |
|
"\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x45\x22\x5d" |
708 |
|
"", |
709 |
|
"\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d" |
710 |
|
"", |
711 |
|
"\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d", |
712 |
|
"\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d", |
713 |
|
"\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d", |
714 |
|
"\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d", |
715 |
|
"\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d", |
716 |
|
"\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d", |
717 |
|
"\x5b\x22\x61\x7f\x61\x22\x5d", |
718 |
|
"\x66\x61\x6c\x73\x65", |
719 |
|
"\x34\x32", |
720 |
|
"\x2d\x30\x2e\x31", |
721 |
|
"\x6e\x75\x6c\x6c", |
722 |
|
"\x22\x61\x73\x64\x22", |
723 |
|
"\x74\x72\x75\x65", |
724 |
|
"\x22\x22", |
725 |
|
"\x5b\x22\x61\x22\x5d\x0a", |
726 |
|
"\x5b\x74\x72\x75\x65\x5d", |
727 |
|
"\x20\x5b\x5d\x20", |
728 |
|
NULL |
729 |
|
}; |
730 |
|
static const char *bad[] = { |
731 |
|
"\x5b\x31\x20\x74\x72\x75\x65\x5d", |
732 |
|
"\x5b\x61\xe5\x5d", |
733 |
|
"\x5b\x22\x22\x3a\x20\x31\x5d", |
734 |
|
"\x5b\x22\x22\x5d\x2c", |
735 |
|
"\x5b\x2c\x31\x5d", |
736 |
|
"\x5b\x31\x2c\x2c\x32\x5d", |
737 |
|
"\x5b\x22\x78\x22\x2c\x2c\x5d", |
738 |
|
"\x5b\x22\x78\x22\x5d\x5d", |
739 |
|
"\x5b\x22\x22\x2c\x5d", |
740 |
|
"\x5b\x22\x78\x22", |
741 |
|
"\x5b\x78", |
742 |
|
"\x5b\x33\x5b\x34\x5d\x5d", |
743 |
|
"\x5b\xff\x5d", |
744 |
|
"\x5b\x31\x3a\x32\x5d", |
745 |
|
"\x5b\x2c\x5d", |
746 |
|
"\x5b\x2d\x5d", |
747 |
|
"\x5b\x20\x20\x20\x2c\x20\x22\x22\x5d", |
748 |
|
"\x5b\x22\x61\x22\x2c\x0a\x34\x0a\x2c\x31\x2c", |
749 |
|
"\x5b\x31\x2c\x5d", |
750 |
|
"\x5b\x31\x2c\x2c\x5d", |
751 |
|
"\x5b\x22\x0b\x61\x22\x5c\x66\x5d", |
752 |
|
"\x5b\x2a\x5d", |
753 |
|
"\x5b\x22\x22", |
754 |
|
"\x5b\x31\x2c", |
755 |
|
"\x5b\x31\x2c\x0a\x31\x0a\x2c\x31", |
756 |
|
"\x5b\x7b\x7d", |
757 |
|
"\x5b\x66\x61\x6c\x73\x5d", |
758 |
|
"\x5b\x6e\x75\x6c\x5d", |
759 |
|
"\x5b\x74\x72\x75\x5d", |
760 |
|
"\x5b\x2b\x2b\x31\x32\x33\x34\x5d", |
761 |
|
"\x5b\x2b\x31\x5d", |
762 |
|
"\x5b\x2b\x49\x6e\x66\x5d", |
763 |
|
"\x5b\x2d\x30\x31\x5d", |
764 |
|
"\x5b\x2d\x31\x2e\x30\x2e\x5d", |
765 |
|
"\x5b\x2d\x32\x2e\x5d", |
766 |
|
"\x5b\x2d\x4e\x61\x4e\x5d", |
767 |
|
"\x5b\x2e\x2d\x31\x5d", |
768 |
|
"\x5b\x2e\x32\x65\x2d\x33\x5d", |
769 |
|
"\x5b\x30\x2e\x31\x2e\x32\x5d", |
770 |
|
"\x5b\x30\x2e\x33\x65\x2b\x5d", |
771 |
|
"\x5b\x30\x2e\x33\x65\x5d", |
772 |
|
"\x5b\x30\x2e\x65\x31\x5d", |
773 |
|
"\x5b\x30\x45\x2b\x5d", |
774 |
|
"\x5b\x30\x45\x5d", |
775 |
|
"\x5b\x30\x65\x2b\x5d", |
776 |
|
"\x5b\x30\x65\x5d", |
777 |
|
"\x5b\x31\x2e\x30\x65\x2b\x5d", |
778 |
|
"\x5b\x31\x2e\x30\x65\x2d\x5d", |
779 |
|
"\x5b\x31\x2e\x30\x65\x5d", |
780 |
|
"\x5b\x31\x20\x30\x30\x30\x2e\x30\x5d", |
781 |
|
"\x5b\x31\x65\x45\x32\x5d", |
782 |
|
"\x5b\x32\x2e\x65\x2b\x33\x5d", |
783 |
|
"\x5b\x32\x2e\x65\x2d\x33\x5d", |
784 |
|
"\x5b\x32\x2e\x65\x33\x5d", |
785 |
|
"\x5b\x39\x2e\x65\x2b\x5d", |
786 |
|
"\x5b\x49\x6e\x66\x5d", |
787 |
|
"\x5b\x4e\x61\x4e\x5d", |
788 |
|
"\x5b\xef\xbc\x91\x5d", |
789 |
|
"\x5b\x31\x2b\x32\x5d", |
790 |
|
"\x5b\x30\x78\x31\x5d", |
791 |
|
"\x5b\x30\x78\x34\x32\x5d", |
792 |
|
"\x5b\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d", |
793 |
|
"\x5b\x30\x65\x2b\x2d\x31\x5d", |
794 |
|
"\x5b\x2d\x31\x32\x33\x2e\x31\x32\x33\x66\x6f\x6f\x5d", |
795 |
|
"\x5b\x31\x32\x33\xe5\x5d", |
796 |
|
"\x5b\x31\x65\x31\xe5\x5d", |
797 |
|
"\x5b\x30\xe5\x5d\x0a", |
798 |
|
"\x5b\x2d\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d", |
799 |
|
"\x5b\x2d\x66\x6f\x6f\x5d", |
800 |
|
"\x5b\x2d\x20\x31\x5d", |
801 |
|
"\x5b\x2d\x30\x31\x32\x5d", |
802 |
|
"\x5b\x2d\x2e\x31\x32\x33\x5d", |
803 |
|
"\x5b\x2d\x31\x78\x5d", |
804 |
|
"\x5b\x31\x65\x61\x5d", |
805 |
|
"\x5b\x31\x65\xe5\x5d", |
806 |
|
"\x5b\x31\x2e\x5d", |
807 |
|
"\x5b\x2e\x31\x32\x33\x5d", |
808 |
|
"\x5b\x31\x2e\x32\x61\x2d\x33\x5d", |
809 |
|
"\x5b\x31\x2e\x38\x30\x31\x31\x36\x37\x30\x30\x33\x33\x33\x37\x36" |
810 |
|
"\x35\x31\x34\x48\x2d\x33\x30\x38\x5d", |
811 |
|
"\x5b\x30\x31\x32\x5d", |
812 |
|
"\x5b\x22\x78\x22\x2c\x20\x74\x72\x75\x74\x68\x5d", |
813 |
|
"\x7b\x5b\x3a\x20\x22\x78\x22\x7d\x0a", |
814 |
|
"\x7b\x22\x78\x22\x2c\x20\x6e\x75\x6c\x6c\x7d", |
815 |
|
"\x7b\x22\x78\x22\x3a\x3a\x22\x62\x22\x7d", |
816 |
|
"\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d", |
817 |
|
"\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d", |
818 |
|
"\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d", |
819 |
|
"\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d", |
820 |
|
"\x7b\x22\x61\x22\x20\x62\x7d", |
821 |
|
"\x7b\x3a\x22\x62\x22\x7d", |
822 |
|
"\x7b\x22\x61\x22\x20\x22\x62\x22\x7d", |
823 |
|
"\x7b\x22\x61\x22\x3a", |
824 |
|
"\x7b\x22\x61\x22", |
825 |
|
"\x7b\x31\x3a\x31\x7d", |
826 |
|
"\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d", |
827 |
|
"\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a" |
828 |
|
"\x6e\x75\x6c\x6c\x7d", |
829 |
|
"\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d", |
830 |
|
"\x7b\x27\x61\x27\x3a\x30\x7d", |
831 |
|
"\x7b\x22\x69\x64\x22\x3a\x30\x2c\x7d", |
832 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f", |
833 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f\x2f", |
834 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2f", |
835 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f", |
836 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x2c\x22\x63\x22\x3a\x22\x64" |
837 |
|
"\x22\x7d", |
838 |
|
"\x7b\x61\x3a\x20\x22\x62\x22\x7d", |
839 |
|
"\x7b\x22\x61\x22\x3a\x22\x61", |
840 |
|
"\x7b\x20\x22\x66\x6f\x6f\x22\x20\x3a\x20\x22\x62\x61\x72\x22\x2c" |
841 |
|
"\x20\x22\x61\x22\x20\x7d", |
842 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23", |
843 |
|
"\x20", |
844 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x22\x5d", |
845 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x22\x5d", |
846 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d", |
847 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d", |
848 |
|
"\x5b\xc3\xa9\x5d", |
849 |
|
"\x5b\x22\x5c\x78\x30\x30\x22\x5d", |
850 |
|
"\x5b\x22\x5c\x5c\x5c\x22\x5d", |
851 |
|
"\x5b\x22\x5c\x09\x22\x5d", |
852 |
|
"\x5b\x22\x5c\xf0\x9f\x8c\x80\x22\x5d", |
853 |
|
"\x5b\x22\x5c\x22\x5d", |
854 |
|
"\x5b\x22\x5c\x75\x30\x30\x41\x22\x5d", |
855 |
|
"\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x22\x5d", |
856 |
|
"\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x44\x38\x30\x30\x5c\x78" |
857 |
|
"\x22\x5d", |
858 |
|
"\x5b\x22\x5c\x75\xe5\x22\x5d", |
859 |
|
"\x5b\x22\x5c\x61\x22\x5d", |
860 |
|
"\x5b\x22\x5c\x75\x71\x71\x71\x71\x22\x5d", |
861 |
|
"\x5b\x22\x5c\xe5\x22\x5d", |
862 |
|
"\x5b\x5c\x75\x30\x30\x32\x30\x22\x61\x73\x64\x22\x5d", |
863 |
|
"\x5b\x5c\x6e\x5d", |
864 |
|
"\x22", |
865 |
|
"\x5b\x27\x73\x69\x6e\x67\x6c\x65\x20\x71\x75\x6f\x74\x65\x27\x5d" |
866 |
|
"", |
867 |
|
"\x61\x62\x63", |
868 |
|
"\x5b\x22\x5c", |
869 |
|
"\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d", |
870 |
|
"\x5b\x22\x09\x22\x5d", |
871 |
|
"\x22\x5c\x55\x41\x36\x36\x44\x22", |
872 |
|
"\x22\x22\x78", |
873 |
|
"\x5b\xe2\x81\xa0\x5d", |
874 |
|
"\xef\xbb\xbf", |
875 |
|
"\x3c\x2e\x3e", |
876 |
|
"\x5b\x3c\x6e\x75\x6c\x6c\x3e\x5d", |
877 |
|
"\x5b\x31\x5d\x78", |
878 |
|
"\x5b\x31\x5d\x5d", |
879 |
|
"\x5b\x22\x61\x73\x64\x5d", |
880 |
|
"\x61\xc3\xa5", |
881 |
|
"\x5b\x54\x72\x75\x65\x5d", |
882 |
|
"\x31\x5d", |
883 |
|
"\x7b\x22\x78\x22\x3a\x20\x74\x72\x75\x65\x2c", |
884 |
|
"\x5b\x5d\x5b\x5d", |
885 |
|
"\x5d", |
886 |
|
"\xef\xbb\x7b\x7d", |
887 |
|
"\xe5", |
888 |
|
"\x5b", |
889 |
|
"", |
890 |
|
"\x32\x40", |
891 |
|
"\x7b\x7d\x7d", |
892 |
|
"\x7b\x22\x22\x3a", |
893 |
|
"\x7b\x22\x61\x22\x3a\x2f\x2a\x63\x6f\x6d\x6d\x65\x6e\x74\x2a\x2f" |
894 |
|
"\x22\x62\x22\x7d", |
895 |
|
"\x7b\x22\x61\x22\x3a\x20\x74\x72\x75\x65\x7d\x20\x22\x78\x22", |
896 |
|
"\x5b\x27", |
897 |
|
"\x5b\x2c", |
898 |
|
"\x5b\x7b", |
899 |
|
"\x5b\x22\x61", |
900 |
|
"\x5b\x22\x61\x22", |
901 |
|
"\x7b", |
902 |
|
"\x7b\x5d", |
903 |
|
"\x7b\x2c", |
904 |
|
"\x7b\x5b", |
905 |
|
"\x7b\x22\x61", |
906 |
|
"\x7b\x27\x61\x27", |
907 |
|
"\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b" |
908 |
|
"", |
909 |
|
"\xe9", |
910 |
|
"\x2a", |
911 |
|
"\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23\x7b\x7d", |
912 |
|
"\x5b\x5c\x75\x30\x30\x30\x41\x22\x22\x5d", |
913 |
|
"\x5b\x31", |
914 |
|
"\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x6e\x75\x6c", |
915 |
|
"\x5b\x20\x74\x72\x75\x65\x2c\x20\x66\x61\x6c\x73", |
916 |
|
"\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x74\x72\x75", |
917 |
|
"\x7b\x22\x61\x73\x64\x22\x3a\x22\x61\x73\x64\x22", |
918 |
|
"\xc3\xa5", |
919 |
|
"\x5b\xe2\x81\xa0\x5d", |
920 |
|
"\x5b\x0c\x5d", |
921 |
|
NULL |
922 |
|
}; |
923 |
|
|
924 |
|
static void |
925 |
3800 |
test_good(const char *j) |
926 |
|
{ |
927 |
|
struct vjsn *js; |
928 |
|
const char *err; |
929 |
|
|
930 |
3800 |
js = vjsn_parse(j, &err); |
931 |
3800 |
if (js == NULL || err != NULL) { |
932 |
0 |
fprintf(stderr, "Parse error: %s\n%s\n", err, j); |
933 |
0 |
exit(1); |
934 |
|
} |
935 |
3800 |
printf("GOOD: %s\n", j); |
936 |
3800 |
vjsn_dump(js, stdout); |
937 |
3800 |
vjsn_delete(&js); |
938 |
3800 |
} |
939 |
|
|
940 |
|
static void |
941 |
7320 |
test_bad(const char *j) |
942 |
|
{ |
943 |
|
struct vjsn *js; |
944 |
|
const char *err; |
945 |
|
|
946 |
7320 |
js = vjsn_parse(j, &err); |
947 |
7320 |
if (js != NULL || err == NULL) { |
948 |
0 |
fprintf(stderr, "Parse succeeded %s\n", j); |
949 |
0 |
exit(1); |
950 |
|
} |
951 |
7320 |
printf("BAD: %s %s\n", err, j); |
952 |
7320 |
} |
953 |
|
|
954 |
|
int |
955 |
40 |
main(int argc, char **argv) |
956 |
|
{ |
957 |
|
const char **s; |
958 |
|
|
959 |
40 |
(void)argc; |
960 |
40 |
(void)argv; |
961 |
3840 |
for (s = good; *s != NULL; s++) |
962 |
3800 |
test_good(*s); |
963 |
7320 |
for (s = bad; *s != NULL; s++) |
964 |
7280 |
test_bad(*s); |
965 |
|
|
966 |
|
/* |
967 |
|
* This is part of Nicolas i(ndeterminate) test set, for reasons I |
968 |
|
* do not fully grasp, but we want it to test bad. |
969 |
|
*/ |
970 |
40 |
test_bad("\"\\uDFAA\""); |
971 |
40 |
printf("Tests done\n"); |
972 |
40 |
return (0); |
973 |
|
} |
974 |
|
|
975 |
|
#endif |