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