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