vinyl-cache/lib/libvinyl/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 4168204
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 4168204
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 4168204
        AN(jsv);
70 4168204
        VTAILQ_INIT(&jsv->children);
71 4168204
        jsv->type = type;
72 4168204
        return (jsv);
73
}
74
75
static void
76 1863276
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 1863276
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 1863276
        do {
82 3716624
                jsve = VTAILQ_FIRST(&jsv->children);
83 3716624
                if (jsve != NULL) {
84 1853348
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 1853348
                        vjsn_val_delete(jsve);
86 1853348
                }
87 3716624
        } while (jsve != NULL);
88 1863276
        FREE_OBJ(jsv);
89 1863276
}
90
91
void
92 9764
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 9764
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 9764
        if (js->value != NULL)
98 9712
                vjsn_val_delete(js->value);
99 9764
        free(js->raw);
100 9764
        FREE_OBJ(js);
101 9764
}
102
103
static void
104 16028316
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 16028316
        while (1) {
109 34856732
                c = js->ptr[0];
110 34856732
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 18828416
                        *js->ptr++ = '\0';
112 18828416
                        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 16028316
                return;
124
        }
125
}
126
127
static unsigned
128 276
vjsn_unumber(struct vjsn *js)
129
{
130 276
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 276
        VJSN_EXPECT(js, '\\', 0);
135 276
        VJSN_EXPECT(js, 'u', 0);
136 1276
        for (i = 0; i < 4; i++) {
137 1032
                u <<= 4;
138 1032
                c = *js->ptr;
139 1032
                if (c >= '0' && c <= '9')
140 656
                        u |= c - '0';                   /*lint !e737 */
141 376
                else if (c >= 'A' && c <= 'F')
142 236
                        u |= c - '7';                   /*lint !e737 */
143 140
                else if (c >= 'a' && c <= 'f')
144 112
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 28
                        js->err = "Illegal \\uXXXX sequence";
147 28
                        return (0);
148
                }
149 1004
                js->ptr++;
150 1004
        }
151 244
        return (u);
152 276
}
153
154
static void
155 224
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 224
        u1 = vjsn_unumber(js);
160 224
        if (js->err)
161 12
                return;
162
163 212
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 4
                js->err = "Lone second UTF-16 Surrogate";
165 4
                return;
166
        }
167 208
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 52
                u2 = vjsn_unumber(js);
169 52
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 24
                        js->err = "Bad UTF-16 Surrogate pair";
171 24
                        return;
172
                }
173 28
                u1 -= 0xd800;
174 28
                u2 -= 0xdc00;
175 28
                u1 <<= 10;
176 28
                u1 |= u2;
177 28
                u1 |= 0x10000;
178 28
        }
179 184
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 184
        if (u1 < 0x80)
182 36
                *(*d)++ = u1;
183 148
        else if (u1 < 0x800) {
184 76
                *(*d)++ = 0xc0 + u1 / 64;
185 76
                *(*d)++ = 0x80 + u1 % 64;
186 148
        } else if (u1 < 0x10000) {
187 44
                *(*d)++ = 0xe0 + u1 / 4096;
188 44
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 44
                *(*d)++ = 0x80 + u1 % 64;
190 44
        } else {
191 28
                *(*d)++ = 0xf0 + u1 / 262144;
192 28
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 28
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 28
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 224
}
198
199
static char *
200 5007920
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 5007920
        AN(e);
205 5007920
        vjsn_skip_ws(js);
206 5007920
        VJSN_EXPECT(js, '"', NULL);
207 5007840
        b = p = js->ptr;
208 68709845
        while (*js->ptr != '"') {
209 63702117
                if (*js->ptr == '\0') {
210 28
                        js->err = "Unterminated string";
211 28
                        return (NULL);
212
                }
213 63702089
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 12
                        js->err = "Unescaped control char in string";
215 12
                        return (NULL);
216
                }
217 63702077
                if (*js->ptr != '\\') {
218 62629277
                        *p++ = *js->ptr++;
219 62629277
                        continue;
220
                }
221 1072800
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 11852
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 4
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 4
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 950500
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 110180
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 4
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 224
                        vjsn_unicode(js, &p);
232 224
                        if (js->err != NULL)
233 40
                                return (NULL);
234 184
                        break;
235
                default:
236 32
                        js->err = "Bad string escape";
237 32
                        return (NULL);
238
                }
239
        }
240 5007728
        VJSN_EXPECT(js, '"', NULL);
241 5007728
        *p = '\0';
242 5007728
        *e = p;
243 5007728
        return (b);
244 5007920
}
245
246
static struct vjsn_val *
247 224032
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 224032
        VJSN_EXPECT(js, '{', NULL);
253
254 224032
        jsv = vjsn_val_new(VJSN_OBJECT);
255 224032
        AN(jsv);
256
257 224032
        vjsn_skip_ws(js);
258 224032
        if (*js->ptr != '}') {
259 1957576
                while (1) {
260 1957576
                        s = vjsn_string(js, &e);
261 1957576
                        if (js->err != NULL)
262 84
                                return (jsv);
263 1957492
                        vjsn_skip_ws(js);
264 1957492
                        VJSN_EXPECT(js, ':', jsv);
265 1957472
                        jsve = vjsn_value(js);
266 1957472
                        if (js->err != NULL) {
267 20
                                if (jsve != NULL)
268 4
                                        vjsn_val_delete(jsve);
269 20
                                return (jsv);
270
                        }
271 1957452
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 1957452
                        jsve->name = s;
273 1957452
                        jsve->name_e = e;
274 1957452
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 1957452
                        vjsn_skip_ws(js);
276 1957452
                        if (*js->ptr == '}')
277 223872
                                break;
278 1733580
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 223872
        }
281 223900
        VJSN_EXPECT(js, '}', jsv);
282 223900
        return (jsv);
283 224032
}
284
285
static struct vjsn_val *
286 503056
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 503056
        VJSN_EXPECT(js, '[', NULL);
291
292 503056
        jsv = vjsn_val_new(VJSN_ARRAY);
293 503056
        AN(jsv);
294
295 503056
        vjsn_skip_ws(js);
296 503056
        if (*js->ptr != ']') {
297 2198264
                while (1) {
298 2198264
                        jsve = vjsn_value(js);
299 2198264
                        if (js->err != NULL) {
300 388
                                if (jsve != NULL)
301 212
                                        vjsn_val_delete(jsve);
302 388
                                return (jsv);
303
                        }
304 2197876
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 2197876
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 2197876
                        vjsn_skip_ws(js);
307 2197876
                        if (*js->ptr == ']')
308 502272
                                break;
309 1695604
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 502272
        }
312 502576
        VJSN_EXPECT(js, ']', jsv);
313 502576
        return (jsv);
314 503056
}
315
316
static struct vjsn_val *
317 217492
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 217492
        jsv = vjsn_val_new(VJSN_NUMBER);
322 217492
        AN(jsv);
323
324 217492
        jsv->value = js->ptr;
325
326 217492
        if (*js->ptr == '-')
327 132
                js->ptr++;
328 217492
        if (*js->ptr < '0' || *js->ptr > '9') {
329 24
                js->err = "Bad number";
330 24
                return (jsv);
331
        }
332 217468
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 12
                js->err = "Bad number";
334 12
                return (jsv);
335
        }
336 855524
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 638068
                js->ptr++;
338 217456
        if (*js->ptr == '.') {
339 724
                js->ptr++;
340 724
                if (*js->ptr < '0' || *js->ptr > '9') {
341 28
                        js->err = "Bad number";
342 28
                        return (jsv);
343
                }
344 3484
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 2788
                        js->ptr++;
346 696
        }
347 217428
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 108
                js->ptr++;
349 108
                if (*js->ptr == '-' || *js->ptr == '+')
350 52
                        js->ptr++;
351 108
                if (*js->ptr < '0' || *js->ptr > '9') {
352 52
                        js->err = "Bad number";
353 52
                        return (jsv);
354
                }
355 136
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 80
                        js->ptr++;
357 56
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 217376
        return (jsv);
363 217492
}
364
365
static struct vjsn_val *
366 4168448
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 4168448
        AZ(js->err);
371 4168448
        vjsn_skip_ws(js);
372 4168448
        if (*js->ptr == '{')
373 224032
                return (vjsn_object(js));
374 3944416
        if (*js->ptr== '[')
375 503056
                return (vjsn_array(js));
376 3441360
        if (*js->ptr== '"') {
377 3050344
                jsv = vjsn_val_new(VJSN_STRING);
378 3050344
                jsv->value = vjsn_string(js, &jsv->value_e);
379 3050344
                if (js->err != NULL)
380 108
                        return (jsv);
381 3050236
                AN(jsv->value);
382 3050236
                return (jsv);
383
        }
384 391016
        if (!vstrncmp(js->ptr, "true", 4)) {
385 42844
                js->ptr += 4;
386 42844
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 348172
        if (!vstrncmp(js->ptr, "false", 5)) {
389 8492
                js->ptr += 5;
390 8492
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 339680
        if (!vstrncmp(js->ptr, "null", 4)) {
393 121944
                js->ptr += 4;
394 121944
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 217736
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 217492
                return (vjsn_number(js));
398 244
        js->err = "Unrecognized value";
399 244
        return (NULL);
400 4168448
}
401
402
struct vjsn *
403 12712
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 12712
        AN(from);
410
411 12712
        AN(err);
412 12712
        *err = NULL;
413
414 12712
        if (to == NULL)
415 12712
                to = strchr(from, '\0');
416 12712
        AN(to);
417
418 12712
        sz = to - from;
419
420 12712
        p = malloc(sz + 1L);
421 12712
        AN(p);
422 12712
        vmemcpy(p, from, sz);
423 12712
        p[sz] = '\0';
424 12712
        e = p + sz;
425
426 12712
        ALLOC_OBJ(js, VJSN_MAGIC);
427 12712
        AN(js);
428 12712
        js->raw = p;
429 12712
        js->ptr = p;
430
431 12712
        js->value = vjsn_value(js);
432 12712
        if (js->err != NULL) {
433 672
                *err = js->err;
434 672
                vjsn_delete(&js);
435 672
                return (NULL);
436
        }
437
438 12040
        vjsn_skip_ws(js);
439 12040
        if (js->ptr != e) {
440 64
                *err = "Garbage after value";
441 64
                vjsn_delete(&js);
442 64
                return (NULL);
443
        }
444 11976
        return (js);
445 12712
}
446
447
struct vjsn *
448 12712
vjsn_parse(const char *src, const char **err)
449
{
450
451 12712
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 2006108
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 2006108
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 2006108
        AN(key);
461 9427566
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 9422398
                if (vc->name != NULL && !vstrcmp(vc->name, key))
463 2000940
                        return (vc);
464 7421458
        }
465 5168
        return (NULL);
466 2006108
}
467
468
static void
469 772
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 772
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 772
        printf("%*s", indent, "");
475 772
        if (jsv->name != NULL)
476 68
                printf("[\"%s\"]: ", jsv->name);
477 772
        printf("{%s}", jsv->type);
478 772
        if (jsv->value != NULL) {
479 364
                if (vstrlen(jsv->value) < 20)
480 348
                        printf(" <%s", jsv->value);
481
                else
482 16
                        printf(" <%.10s[...#%zu]",
483 16
                            jsv->value, vstrlen(jsv->value + 10));
484 364
                printf(">");
485 364
        }
486 772
        printf("\n");
487 1164
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 392
                vjsn_dump_i(jsve, fo, indent + 2);
489 772
}
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 380
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 380
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 380
        AN(fo);
504 380
        vjsn_dump_i(js->value, fo, 0);
505 380
}
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 3653122
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
def emit(fin):
561
    x = bytearray(open(fin, 'rb').read())
562
    if 0 in x:
563
        print("\t// SKIP: NUL in", fin)
564
        return
565
    if len(x) > 1000:
566
        print("\t// SKIP: LONG ", fin)
567
        return
568
    t = '\t"'
569
    for i in x:
570
        t += "\\x%02x" % i
571
        if len(t) > 64:
572
            print(t + '"')
573
            t = '\t"'
574
    print(t + '",')
575
576
print("static const char *good[] = {")
577
for f in sorted(glob.glob("y_*")):
578
    emit(f)
579
print("\tNULL")
580
print("};\n")
581
582
print("static const char *bad[] = {")
583
for f in sorted(glob.glob("n_*")):
584
        emit(f)
585
print("\tNULL")
586
print("};")
587
588
 */
589
590
static const char *good[] = {
591
        "\x5b\x5b\x5d\x20\x20\x20\x5d",
592
        "\x5b\x22\x22\x5d",
593
        "\x5b\x5d",
594
        "\x5b\x22\x61\x22\x5d",
595
        "\x5b\x66\x61\x6c\x73\x65\x5d",
596
        "\x5b\x6e\x75\x6c\x6c\x2c\x20\x31\x2c\x20\x22\x31\x22\x2c\x20\x7b"
597
        "\x7d\x5d",
598
        "\x5b\x6e\x75\x6c\x6c\x5d",
599
        "\x5b\x31\x0a\x5d",
600
        "\x20\x5b\x31\x5d",
601
        "\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c"
602
        "\x6c\x2c\x32\x5d",
603
        "\x5b\x32\x5d\x20",
604
        "\x5b\x31\x32\x33\x65\x36\x35\x5d",
605
        "\x5b\x30\x65\x2b\x31\x5d",
606
        "\x5b\x30\x65\x31\x5d",
607
        "\x5b\x20\x34\x5d",
608
        "\x5b\x2d\x30\x2e\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
609
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
610
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
611
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
612
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
613
        "\x30\x31\x5d\x0a",
614
        "\x5b\x32\x30\x65\x31\x5d",
615
        "\x5b\x2d\x30\x5d",
616
        "\x5b\x2d\x31\x32\x33\x5d",
617
        "\x5b\x2d\x31\x5d",
618
        "\x5b\x2d\x30\x5d",
619
        "\x5b\x31\x45\x32\x32\x5d",
620
        "\x5b\x31\x45\x2d\x32\x5d",
621
        "\x5b\x31\x45\x2b\x32\x5d",
622
        "\x5b\x31\x32\x33\x65\x34\x35\x5d",
623
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x65\x37\x38\x5d",
624
        "\x5b\x31\x65\x2d\x32\x5d",
625
        "\x5b\x31\x65\x2b\x32\x5d",
626
        "\x5b\x31\x32\x33\x5d",
627
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x37\x38\x39\x5d",
628
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x2c\x20\x22\x64"
629
        "\x66\x67\x22\x3a\x22\x66\x67\x68\x22\x7d",
630
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x7d",
631
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x63\x22"
632
        "\x7d",
633
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x62\x22"
634
        "\x7d",
635
        "\x7b\x7d",
636
        "\x7b\x22\x22\x3a\x30\x7d",
637
        "\x7b\x22\x66\x6f\x6f\x5c\x75\x30\x30\x30\x30\x62\x61\x72\x22\x3a"
638
        "\x20\x34\x32\x7d",
639
        "\x7b\x20\x22\x6d\x69\x6e\x22\x3a\x20\x2d\x31\x2e\x30\x65\x2b\x32"
640
        "\x38\x2c\x20\x22\x6d\x61\x78\x22\x3a\x20\x31\x2e\x30\x65\x2b\x32"
641
        "\x38\x20\x7d",
642
        "\x7b\x22\x78\x22\x3a\x5b\x7b\x22\x69\x64\x22\x3a\x20\x22\x78\x78"
643
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
644
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
645
        "\x78\x78\x78\x78\x78\x78\x22\x7d\x5d\x2c\x20\x22\x69\x64\x22\x3a"
646
        "\x20\x22\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
647
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
648
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x22\x7d",
649
        "\x7b\x22\x61\x22\x3a\x5b\x5d\x7d",
650
        "\x7b\x22\x74\x69\x74\x6c\x65\x22\x3a\x22\x5c\x75\x30\x34\x31\x66"
651
        "\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x33\x62\x5c\x75\x30\x34"
652
        "\x34\x32\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x34\x30\x5c\x75"
653
        "\x30\x34\x33\x30\x20\x5c\x75\x30\x34\x31\x37\x5c\x75\x30\x34\x33"
654
        "\x35\x5c\x75\x30\x34\x33\x63\x5c\x75\x30\x34\x33\x62\x5c\x75\x30"
655
        "\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c"
656
        "\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d",
657
        "\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d",
658
        "\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75"
659
        "\x31\x32\x41\x42\x22\x5d",
660
        "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d"
661
        "",
662
        "\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75"
663
        "\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d",
664
        "\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72"
665
        "\x5c\x74\x22\x5d",
666
        "\x5b\x22\x5c\x5c\x75\x30\x30\x30\x30\x22\x5d",
667
        "\x5b\x22\x5c\x22\x22\x5d",
668
        "\x5b\x22\x61\x2f\x2a\x62\x2a\x2f\x63\x2f\x2a\x64\x2f\x2f\x65\x22"
669
        "\x5d",
670
        "\x5b\x22\x5c\x5c\x61\x22\x5d",
671
        "\x5b\x22\x5c\x5c\x6e\x22\x5d",
672
        "\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d",
673
        "\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d",
674
        "\x5b\x22\x61\x73\x64\x22\x5d",
675
        "\x5b\x20\x22\x61\x73\x64\x22\x5d",
676
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d"
677
        "",
678
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22"
679
        "\x5d",
680
        "\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d",
681
        "\x5b\x22\xef\xbf\xbf\x22\x5d",
682
        "\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d",
683
        "\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d",
684
        "\x5b\x22\xcf\x80\x22\x5d",
685
        "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d",
686
        "\x5b\x22\x61\x73\x64\x20\x22\x5d",
687
        "\x22\x20\x22",
688
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d"
689
        "",
690
        "\x5b\x22\x5c\x75\x30\x38\x32\x31\x22\x5d",
691
        "\x5b\x22\x5c\x75\x30\x31\x32\x33\x22\x5d",
692
        "\x5b\x22\xe2\x80\xa8\x22\x5d",
693
        "\x5b\x22\xe2\x80\xa9\x22\x5d",
694
        "\x5b\x22\x5c\x75\x30\x30\x36\x31\x5c\x75\x33\x30\x61\x66\x5c\x75"
695
        "\x33\x30\x45\x41\x5c\x75\x33\x30\x62\x39\x22\x5d",
696
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x30\x41\x6c\x69\x6e\x65\x22"
697
        "\x5d",
698
        "\x5b\x22\x7f\x22\x5d",
699
        "\x5b\x22\x5c\x75\x41\x36\x36\x44\x22\x5d",
700
        "\x5b\x22\x5c\x75\x30\x30\x35\x43\x22\x5d",
701
        "\x5b\x22\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82\x22\x5d",
702
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
703
        "",
704
        "\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
705
        "",
706
        "\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d",
707
        "\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d",
708
        "\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d",
709
        "\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d",
710
        "\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d",
711
        "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d",
712
        "\x5b\x22\x61\x7f\x61\x22\x5d",
713
        "\x66\x61\x6c\x73\x65",
714
        "\x34\x32",
715
        "\x2d\x30\x2e\x31",
716
        "\x6e\x75\x6c\x6c",
717
        "\x22\x61\x73\x64\x22",
718
        "\x74\x72\x75\x65",
719
        "\x22\x22",
720
        "\x5b\x22\x61\x22\x5d\x0a",
721
        "\x5b\x74\x72\x75\x65\x5d",
722
        "\x20\x5b\x5d\x20",
723
        NULL
724
};
725
726
static const char *bad[] = {
727
        "\x5b\x31\x20\x74\x72\x75\x65\x5d",
728
        "\x5b\x61\xe5\x5d",
729
        "\x5b\x22\x22\x3a\x20\x31\x5d",
730
        "\x5b\x22\x22\x5d\x2c",
731
        "\x5b\x2c\x31\x5d",
732
        "\x5b\x31\x2c\x2c\x32\x5d",
733
        "\x5b\x22\x78\x22\x2c\x2c\x5d",
734
        "\x5b\x22\x78\x22\x5d\x5d",
735
        "\x5b\x22\x22\x2c\x5d",
736
        "\x5b\x22\x78\x22",
737
        "\x5b\x78",
738
        "\x5b\x33\x5b\x34\x5d\x5d",
739
        "\x5b\xff\x5d",
740
        "\x5b\x31\x3a\x32\x5d",
741
        "\x5b\x2c\x5d",
742
        "\x5b\x2d\x5d",
743
        "\x5b\x20\x20\x20\x2c\x20\x22\x22\x5d",
744
        "\x5b\x22\x61\x22\x2c\x0a\x34\x0a\x2c\x31\x2c",
745
        "\x5b\x31\x2c\x5d",
746
        "\x5b\x31\x2c\x2c\x5d",
747
        "\x5b\x22\x0b\x61\x22\x5c\x66\x5d",
748
        "\x5b\x2a\x5d",
749
        "\x5b\x22\x22",
750
        "\x5b\x31\x2c",
751
        "\x5b\x31\x2c\x0a\x31\x0a\x2c\x31",
752
        "\x5b\x7b\x7d",
753
        "\x5b\x66\x61\x6c\x73\x5d",
754
        "\x5b\x6e\x75\x6c\x5d",
755
        "\x5b\x74\x72\x75\x5d",
756
        // SKIP: NUL in n_multidigit_number_then_00.json
757
        "\x5b\x2b\x2b\x31\x32\x33\x34\x5d",
758
        "\x5b\x2b\x31\x5d",
759
        "\x5b\x2b\x49\x6e\x66\x5d",
760
        "\x5b\x2d\x30\x31\x5d",
761
        "\x5b\x2d\x31\x2e\x30\x2e\x5d",
762
        "\x5b\x2d\x32\x2e\x5d",
763
        "\x5b\x2d\x4e\x61\x4e\x5d",
764
        "\x5b\x2e\x2d\x31\x5d",
765
        "\x5b\x2e\x32\x65\x2d\x33\x5d",
766
        "\x5b\x30\x2e\x31\x2e\x32\x5d",
767
        "\x5b\x30\x2e\x33\x65\x2b\x5d",
768
        "\x5b\x30\x2e\x33\x65\x5d",
769
        "\x5b\x30\x2e\x65\x31\x5d",
770
        "\x5b\x30\x45\x2b\x5d",
771
        "\x5b\x30\x45\x5d",
772
        "\x5b\x30\x65\x2b\x5d",
773
        "\x5b\x30\x65\x5d",
774
        "\x5b\x31\x2e\x30\x65\x2b\x5d",
775
        "\x5b\x31\x2e\x30\x65\x2d\x5d",
776
        "\x5b\x31\x2e\x30\x65\x5d",
777
        "\x5b\x31\x20\x30\x30\x30\x2e\x30\x5d",
778
        "\x5b\x31\x65\x45\x32\x5d",
779
        "\x5b\x32\x2e\x65\x2b\x33\x5d",
780
        "\x5b\x32\x2e\x65\x2d\x33\x5d",
781
        "\x5b\x32\x2e\x65\x33\x5d",
782
        "\x5b\x39\x2e\x65\x2b\x5d",
783
        "\x5b\x49\x6e\x66\x5d",
784
        "\x5b\x4e\x61\x4e\x5d",
785
        "\x5b\xef\xbc\x91\x5d",
786
        "\x5b\x31\x2b\x32\x5d",
787
        "\x5b\x30\x78\x31\x5d",
788
        "\x5b\x30\x78\x34\x32\x5d",
789
        "\x5b\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
790
        "\x5b\x30\x65\x2b\x2d\x31\x5d",
791
        "\x5b\x2d\x31\x32\x33\x2e\x31\x32\x33\x66\x6f\x6f\x5d",
792
        "\x5b\x31\x32\x33\xe5\x5d",
793
        "\x5b\x31\x65\x31\xe5\x5d",
794
        "\x5b\x30\xe5\x5d\x0a",
795
        "\x5b\x2d\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
796
        "\x5b\x2d\x66\x6f\x6f\x5d",
797
        "\x5b\x2d\x20\x31\x5d",
798
        "\x5b\x2d\x30\x31\x32\x5d",
799
        "\x5b\x2d\x2e\x31\x32\x33\x5d",
800
        "\x5b\x2d\x31\x78\x5d",
801
        "\x5b\x31\x65\x61\x5d",
802
        "\x5b\x31\x65\xe5\x5d",
803
        "\x5b\x31\x2e\x5d",
804
        "\x5b\x2e\x31\x32\x33\x5d",
805
        "\x5b\x31\x2e\x32\x61\x2d\x33\x5d",
806
        "\x5b\x31\x2e\x38\x30\x31\x31\x36\x37\x30\x30\x33\x33\x33\x37\x36"
807
        "\x35\x31\x34\x48\x2d\x33\x30\x38\x5d",
808
        "\x5b\x30\x31\x32\x5d",
809
        "\x5b\x22\x78\x22\x2c\x20\x74\x72\x75\x74\x68\x5d",
810
        "\x7b\x5b\x3a\x20\x22\x78\x22\x7d\x0a",
811
        "\x7b\x22\x78\x22\x2c\x20\x6e\x75\x6c\x6c\x7d",
812
        "\x7b\x22\x78\x22\x3a\x3a\x22\x62\x22\x7d",
813
        "\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d",
814
        "\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d",
815
        "\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d",
816
        "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d",
817
        "\x7b\x22\x61\x22\x20\x62\x7d",
818
        "\x7b\x3a\x22\x62\x22\x7d",
819
        "\x7b\x22\x61\x22\x20\x22\x62\x22\x7d",
820
        "\x7b\x22\x61\x22\x3a",
821
        "\x7b\x22\x61\x22",
822
        "\x7b\x31\x3a\x31\x7d",
823
        "\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d",
824
        "\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a"
825
        "\x6e\x75\x6c\x6c\x7d",
826
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d",
827
        "\x7b\x27\x61\x27\x3a\x30\x7d",
828
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x7d",
829
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f",
830
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f\x2f",
831
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2f",
832
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f",
833
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x2c\x22\x63\x22\x3a\x22\x64"
834
        "\x22\x7d",
835
        "\x7b\x61\x3a\x20\x22\x62\x22\x7d",
836
        "\x7b\x22\x61\x22\x3a\x22\x61",
837
        "\x7b\x20\x22\x66\x6f\x6f\x22\x20\x3a\x20\x22\x62\x61\x72\x22\x2c"
838
        "\x20\x22\x61\x22\x20\x7d",
839
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23",
840
        "\x20",
841
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x22\x5d",
842
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x22\x5d",
843
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d",
844
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d",
845
        "\x5b\xc3\xa9\x5d",
846
        // SKIP: NUL in n_string_backslash_00.json
847
        "\x5b\x22\x5c\x78\x30\x30\x22\x5d",
848
        "\x5b\x22\x5c\x5c\x5c\x22\x5d",
849
        "\x5b\x22\x5c\x09\x22\x5d",
850
        "\x5b\x22\x5c\xf0\x9f\x8c\x80\x22\x5d",
851
        "\x5b\x22\x5c\x22\x5d",
852
        "\x5b\x22\x5c\x75\x30\x30\x41\x22\x5d",
853
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x22\x5d",
854
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x44\x38\x30\x30\x5c\x78"
855
        "\x22\x5d",
856
        "\x5b\x22\x5c\x75\xe5\x22\x5d",
857
        "\x5b\x22\x5c\x61\x22\x5d",
858
        "\x5b\x22\x5c\x75\x71\x71\x71\x71\x22\x5d",
859
        "\x5b\x22\x5c\xe5\x22\x5d",
860
        "\x5b\x5c\x75\x30\x30\x32\x30\x22\x61\x73\x64\x22\x5d",
861
        "\x5b\x5c\x6e\x5d",
862
        "\x22",
863
        "\x5b\x27\x73\x69\x6e\x67\x6c\x65\x20\x71\x75\x6f\x74\x65\x27\x5d"
864
        "",
865
        "\x61\x62\x63",
866
        "\x5b\x22\x5c",
867
        // SKIP: NUL in n_string_unescaped_ctrl_char.json
868
        "\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d",
869
        "\x5b\x22\x09\x22\x5d",
870
        "\x22\x5c\x55\x41\x36\x36\x44\x22",
871
        "\x22\x22\x78",
872
        // SKIP: LONG  n_structure_100000_opening_arrays.json
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
        // SKIP: NUL in n_structure_null-byte-outside-string.json
891
        "\x32\x40",
892
        "\x7b\x7d\x7d",
893
        "\x7b\x22\x22\x3a",
894
        "\x7b\x22\x61\x22\x3a\x2f\x2a\x63\x6f\x6d\x6d\x65\x6e\x74\x2a\x2f"
895
        "\x22\x62\x22\x7d",
896
        "\x7b\x22\x61\x22\x3a\x20\x74\x72\x75\x65\x7d\x20\x22\x78\x22",
897
        "\x5b\x27",
898
        "\x5b\x2c",
899
        // SKIP: LONG  n_structure_open_array_object.json
900
        "\x5b\x7b",
901
        "\x5b\x22\x61",
902
        "\x5b\x22\x61\x22",
903
        "\x7b",
904
        "\x7b\x5d",
905
        "\x7b\x2c",
906
        "\x7b\x5b",
907
        "\x7b\x22\x61",
908
        "\x7b\x27\x61\x27",
909
        "\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b"
910
        "",
911
        "\xe9",
912
        "\x2a",
913
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23\x7b\x7d",
914
        "\x5b\x5c\x75\x30\x30\x30\x41\x22\x22\x5d",
915
        "\x5b\x31",
916
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x6e\x75\x6c",
917
        "\x5b\x20\x74\x72\x75\x65\x2c\x20\x66\x61\x6c\x73",
918
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x74\x72\x75",
919
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x61\x73\x64\x22",
920
        "\xc3\xa5",
921
        "\x5b\xe2\x81\xa0\x5d",
922
        "\x5b\x0c\x5d",
923
        NULL
924
};
925
926
static void
927 380
test_good(const char *j)
928
{
929
        struct vjsn *js;
930
        const char *err;
931
932 380
        js = vjsn_parse(j, &err);
933 380
        if (js == NULL || err != NULL) {
934 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
935 0
                exit(1);
936
        }
937 380
        printf("GOOD: %s\n", j);
938 380
        vjsn_dump(js, stdout);
939 380
        vjsn_delete(&js);
940 380
}
941
942
static void
943 732
test_bad(const char *j)
944
{
945
        struct vjsn *js;
946
        const char *err;
947
948 732
        js = vjsn_parse(j, &err);
949 732
        if (js != NULL || err == NULL) {
950 0
                fprintf(stderr, "Parse succeeded %s\n", j);
951 0
                exit(1);
952
        }
953 732
        printf("BAD: %s %s\n", err, j);
954 732
}
955
956
int
957 4
main(int argc, char **argv)
958
{
959
        const char **s;
960
961 4
        (void)argc;
962 4
        (void)argv;
963 384
        for (s = good; *s != NULL; s++)
964 380
                test_good(*s);
965 732
        for (s = bad; *s != NULL; s++)
966 728
                test_bad(*s);
967
968
        /*
969
         * This is part of Nicolas i(ndeterminate) test set, for reasons I
970
         * do not fully grasp, but we want it to test bad.
971
         */
972 4
        test_bad("\"\\uDFAA\"");
973 4
        printf("Tests done\n");
974 4
        return (0);
975
}
976
977
#endif