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 3108568
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 3108568
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 3108568
        AN(jsv);
70 3108568
        VTAILQ_INIT(&jsv->children);
71 3108568
        jsv->type = type;
72 3108568
        return (jsv);
73
}
74
75
static void
76 1392883
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 1392883
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 1392883
        do {
82 2778348
                jsve = VTAILQ_FIRST(&jsv->children);
83 2778348
                if (jsve != NULL) {
84 1385465
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 1385465
                        vjsn_val_delete(jsve);
86 1385465
                }
87 2778348
        } while (jsve != NULL);
88 1392883
        FREE_OBJ(jsv);
89 1392883
}
90
91
void
92 7295
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 7295
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 7295
        if (js->value != NULL)
98 7256
                vjsn_val_delete(js->value);
99 7295
        free(js->raw);
100 7295
        FREE_OBJ(js);
101 7295
}
102
103
static void
104 11960415
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 11960415
        while (1) {
109 25973379
                c = js->ptr[0];
110 25973379
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 14012964
                        *js->ptr++ = '\0';
112 14012964
                        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 11960415
                return;
124
        }
125
}
126
127
static unsigned
128 207
vjsn_unumber(struct vjsn *js)
129
{
130 207
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 207
        VJSN_EXPECT(js, '\\', 0);
135 207
        VJSN_EXPECT(js, 'u', 0);
136 957
        for (i = 0; i < 4; i++) {
137 774
                u <<= 4;
138 774
                c = *js->ptr;
139 774
                if (c >= '0' && c <= '9')
140 492
                        u |= c - '0';                   /*lint !e737 */
141 282
                else if (c >= 'A' && c <= 'F')
142 177
                        u |= c - '7';                   /*lint !e737 */
143 105
                else if (c >= 'a' && c <= 'f')
144 84
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 21
                        js->err = "Illegal \\uXXXX sequence";
147 21
                        return (0);
148
                }
149 753
                js->ptr++;
150 753
        }
151 183
        return (u);
152 207
}
153
154
static void
155 168
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 168
        u1 = vjsn_unumber(js);
160 168
        if (js->err)
161 9
                return;
162
163 159
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 3
                js->err = "Lone second UTF-16 Surrogate";
165 3
                return;
166
        }
167 156
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 39
                u2 = vjsn_unumber(js);
169 39
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 18
                        js->err = "Bad UTF-16 Surrogate pair";
171 18
                        return;
172
                }
173 21
                u1 -= 0xd800;
174 21
                u2 -= 0xdc00;
175 21
                u1 <<= 10;
176 21
                u1 |= u2;
177 21
                u1 |= 0x10000;
178 21
        }
179 138
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 138
        if (u1 < 0x80)
182 27
                *(*d)++ = u1;
183 111
        else if (u1 < 0x800) {
184 57
                *(*d)++ = 0xc0 + u1 / 64;
185 57
                *(*d)++ = 0x80 + u1 % 64;
186 111
        } else if (u1 < 0x10000) {
187 33
                *(*d)++ = 0xe0 + u1 / 4096;
188 33
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 33
                *(*d)++ = 0x80 + u1 % 64;
190 33
        } else {
191 21
                *(*d)++ = 0xf0 + u1 / 262144;
192 21
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 21
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 21
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 168
}
198
199
static char *
200 3738730
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 3738730
        AN(e);
205 3738730
        vjsn_skip_ws(js);
206 3738730
        VJSN_EXPECT(js, '"', NULL);
207 3738670
        b = p = js->ptr;
208 51269614
        while (*js->ptr != '"') {
209 47531028
                if (*js->ptr == '\0') {
210 21
                        js->err = "Unterminated string";
211 21
                        return (NULL);
212
                }
213 47531007
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 9
                        js->err = "Unescaped control char in string";
215 9
                        return (NULL);
216
                }
217 47530998
                if (*js->ptr != '\\') {
218 46729901
                        *p++ = *js->ptr++;
219 46729901
                        continue;
220
                }
221 801097
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 8859
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 3
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 3
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 709584
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 82453
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 3
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 168
                        vjsn_unicode(js, &p);
232 168
                        if (js->err != NULL)
233 30
                                return (NULL);
234 138
                        break;
235
                default:
236 24
                        js->err = "Bad string escape";
237 24
                        return (NULL);
238
                }
239
        }
240 3738586
        VJSN_EXPECT(js, '"', NULL);
241 3738586
        *p = '\0';
242 3738586
        *e = p;
243 3738586
        return (b);
244 3738730
}
245
246
static struct vjsn_val *
247 167479
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 167479
        VJSN_EXPECT(js, '{', NULL);
253
254 167479
        jsv = vjsn_val_new(VJSN_OBJECT);
255 167479
        AN(jsv);
256
257 167479
        vjsn_skip_ws(js);
258 167479
        if (*js->ptr != '}') {
259 1463783
                while (1) {
260 1463783
                        s = vjsn_string(js, &e);
261 1463783
                        if (js->err != NULL)
262 63
                                return (jsv);
263 1463720
                        vjsn_skip_ws(js);
264 1463720
                        VJSN_EXPECT(js, ':', jsv);
265 1463705
                        jsve = vjsn_value(js);
266 1463705
                        if (js->err != NULL) {
267 15
                                if (jsve != NULL)
268 3
                                        vjsn_val_delete(jsve);
269 15
                                return (jsv);
270
                        }
271 1463690
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 1463690
                        jsve->name = s;
273 1463690
                        jsve->name_e = e;
274 1463690
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 1463690
                        vjsn_skip_ws(js);
276 1463690
                        if (*js->ptr == '}')
277 167359
                                break;
278 1296331
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 167359
        }
281 167380
        VJSN_EXPECT(js, '}', jsv);
282 167380
        return (jsv);
283 167479
}
284
285
static struct vjsn_val *
286 373794
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 373794
        VJSN_EXPECT(js, '[', NULL);
291
292 373794
        jsv = vjsn_val_new(VJSN_ARRAY);
293 373794
        AN(jsv);
294
295 373794
        vjsn_skip_ws(js);
296 373794
        if (*js->ptr != ']') {
297 1635549
                while (1) {
298 1635549
                        jsve = vjsn_value(js);
299 1635549
                        if (js->err != NULL) {
300 291
                                if (jsve != NULL)
301 159
                                        vjsn_val_delete(jsve);
302 291
                                return (jsv);
303
                        }
304 1635258
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 1635258
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 1635258
                        vjsn_skip_ws(js);
307 1635258
                        if (*js->ptr == ']')
308 373206
                                break;
309 1262052
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 373206
        }
312 373434
        VJSN_EXPECT(js, ']', jsv);
313 373434
        return (jsv);
314 373794
}
315
316
static struct vjsn_val *
317 162610
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 162610
        jsv = vjsn_val_new(VJSN_NUMBER);
322 162610
        AN(jsv);
323
324 162610
        jsv->value = js->ptr;
325
326 162610
        if (*js->ptr == '-')
327 99
                js->ptr++;
328 162610
        if (*js->ptr < '0' || *js->ptr > '9') {
329 18
                js->err = "Bad number";
330 18
                return (jsv);
331
        }
332 162592
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 9
                js->err = "Bad number";
334 9
                return (jsv);
335
        }
336 639858
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 477275
                js->ptr++;
338 162583
        if (*js->ptr == '.') {
339 543
                js->ptr++;
340 543
                if (*js->ptr < '0' || *js->ptr > '9') {
341 21
                        js->err = "Bad number";
342 21
                        return (jsv);
343
                }
344 2613
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 2091
                        js->ptr++;
346 522
        }
347 162562
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 81
                js->ptr++;
349 81
                if (*js->ptr == '-' || *js->ptr == '+')
350 39
                        js->ptr++;
351 81
                if (*js->ptr < '0' || *js->ptr > '9') {
352 39
                        js->err = "Bad number";
353 39
                        return (jsv);
354
                }
355 102
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 60
                        js->ptr++;
357 42
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 162523
        return (jsv);
363 162610
}
364
365
static struct vjsn_val *
366 3108751
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 3108751
        AZ(js->err);
371 3108751
        vjsn_skip_ws(js);
372 3108751
        if (*js->ptr == '{')
373 167479
                return (vjsn_object(js));
374 2941272
        if (*js->ptr== '[')
375 373794
                return (vjsn_array(js));
376 2567478
        if (*js->ptr== '"') {
377 2274947
                jsv = vjsn_val_new(VJSN_STRING);
378 2274947
                jsv->value = vjsn_string(js, &jsv->value_e);
379 2274947
                if (js->err != NULL)
380 81
                        return (jsv);
381 2274866
                AN(jsv->value);
382 2274866
                return (jsv);
383
        }
384 292531
        if (!strncmp(js->ptr, "true", 4)) {
385 32133
                js->ptr += 4;
386 32133
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 260398
        if (!strncmp(js->ptr, "false", 5)) {
389 6336
                js->ptr += 5;
390 6336
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 254062
        if (!strncmp(js->ptr, "null", 4)) {
393 91269
                js->ptr += 4;
394 91269
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 162793
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 162610
                return (vjsn_number(js));
398 183
        js->err = "Unrecognized value";
399 183
        return (NULL);
400 3108751
}
401
402
struct vjsn *
403 9497
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 9497
        AN(from);
410
411 9497
        AN(err);
412 9497
        *err = NULL;
413
414 9497
        if (to == NULL)
415 9497
                to = strchr(from, '\0');
416 9497
        AN(to);
417
418 9497
        sz = to - from;
419
420 9497
        p = malloc(sz + 1L);
421 9497
        AN(p);
422 9497
        memcpy(p, from, sz);
423 9497
        p[sz] = '\0';
424 9497
        e = p + sz;
425
426 9497
        ALLOC_OBJ(js, VJSN_MAGIC);
427 9497
        AN(js);
428 9497
        js->raw = p;
429 9497
        js->ptr = p;
430
431 9497
        js->value = vjsn_value(js);
432 9497
        if (js->err != NULL) {
433 504
                *err = js->err;
434 504
                vjsn_delete(&js);
435 504
                return (NULL);
436
        }
437
438 8993
        vjsn_skip_ws(js);
439 8993
        if (js->ptr != e) {
440 48
                *err = "Garbage after value";
441 48
                vjsn_delete(&js);
442 48
                return (NULL);
443
        }
444 8945
        return (js);
445 9497
}
446
447
struct vjsn *
448 9497
vjsn_parse(const char *src, const char **err)
449
{
450
451 9497
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 1502767
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 1502767
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 1502767
        AN(key);
461 7062641
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 7058780
                if (vc->name != NULL && !vstrcmp(vc->name, key))
463 1498906
                        return (vc);
464 5559874
        }
465 3861
        return (NULL);
466 1502767
}
467
468
static void
469 579
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 579
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 579
        printf("%*s", indent, "");
475 579
        if (jsv->name != NULL)
476 51
                printf("[\"%s\"]: ", jsv->name);
477 579
        printf("{%s}", jsv->type);
478 579
        if (jsv->value != NULL) {
479 273
                if (vstrlen(jsv->value) < 20)
480 261
                        printf(" <%s", jsv->value);
481
                else
482 12
                        printf(" <%.10s[...#%zu]",
483 12
                            jsv->value, vstrlen(jsv->value + 10));
484 273
                printf(">");
485 273
        }
486 579
        printf("\n");
487 873
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 294
                vjsn_dump_i(jsve, fo, indent + 2);
489 579
}
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 285
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 285
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 285
        AN(fo);
504 285
        vjsn_dump_i(js->value, fo, 0);
505 285
}
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 2723379
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 285
test_good(const char *j)
928
{
929
        struct vjsn *js;
930
        const char *err;
931
932 285
        js = vjsn_parse(j, &err);
933 285
        if (js == NULL || err != NULL) {
934 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
935 0
                exit(1);
936
        }
937 285
        printf("GOOD: %s\n", j);
938 285
        vjsn_dump(js, stdout);
939 285
        vjsn_delete(&js);
940 285
}
941
942
static void
943 549
test_bad(const char *j)
944
{
945
        struct vjsn *js;
946
        const char *err;
947
948 549
        js = vjsn_parse(j, &err);
949 549
        if (js != NULL || err == NULL) {
950 0
                fprintf(stderr, "Parse succeeded %s\n", j);
951 0
                exit(1);
952
        }
953 549
        printf("BAD: %s %s\n", err, j);
954 549
}
955
956
int
957 3
main(int argc, char **argv)
958
{
959
        const char **s;
960
961 3
        (void)argc;
962 3
        (void)argv;
963 288
        for (s = good; *s != NULL; s++)
964 285
                test_good(*s);
965 549
        for (s = bad; *s != NULL; s++)
966 546
                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 3
        test_bad("\"\\uDFAA\"");
973 3
        printf("Tests done\n");
974 3
        return (0);
975
}
976
977
#endif