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 20387413
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 20387413
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 20387413
        AN(jsv);
70 20387413
        VTAILQ_INIT(&jsv->children);
71 20387413
        jsv->type = type;
72 20387413
        return (jsv);
73
}
74
75
static void
76 9280488
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 9280488
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 9280488
        do {
82 18504775
                jsve = VTAILQ_FIRST(&jsv->children);
83 18504775
                if (jsve != NULL) {
84 9224287
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 9224287
                        vjsn_val_delete(jsve);
86 9224287
                }
87 18504775
        } while (jsve != NULL);
88 9280488
        FREE_OBJ(jsv);
89 9280488
}
90
91
void
92 55176
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 55176
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 55176
        if (js->value != NULL)
98 54851
                vjsn_val_delete(js->value);
99 55176
        free(js->raw);
100 55176
        FREE_OBJ(js);
101 55176
}
102
103
static void
104 78888616
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 78888616
        while (1) {
109 169289241
                c = js->ptr[0];
110 169289241
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 90400625
                        *js->ptr++ = '\0';
112 90400625
                        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 78888616
                return;
124
        }
125
}
126
127
static unsigned
128 1725
vjsn_unumber(struct vjsn *js)
129
{
130 1725
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 1725
        VJSN_EXPECT(js, '\\', 0);
135 1725
        VJSN_EXPECT(js, 'u', 0);
136 7975
        for (i = 0; i < 4; i++) {
137 6450
                u <<= 4;
138 6450
                c = *js->ptr;
139 6450
                if (c >= '0' && c <= '9')
140 4100
                        u |= c - '0';                   /*lint !e737 */
141 2350
                else if (c >= 'A' && c <= 'F')
142 1475
                        u |= c - '7';                   /*lint !e737 */
143 875
                else if (c >= 'a' && c <= 'f')
144 700
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 175
                        js->err = "Illegal \\uXXXX sequence";
147 175
                        return (0);
148
                }
149 6275
                js->ptr++;
150 6275
        }
151 1525
        return (u);
152 1725
}
153
154
static void
155 1400
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 1400
        u1 = vjsn_unumber(js);
160 1400
        if (js->err)
161 75
                return;
162
163 1325
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 25
                js->err = "Lone second UTF-16 Surrogate";
165 25
                return;
166
        }
167 1300
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 325
                u2 = vjsn_unumber(js);
169 325
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 150
                        js->err = "Bad UTF-16 Surrogate pair";
171 150
                        return;
172
                }
173 175
                u1 -= 0xd800;
174 175
                u2 -= 0xdc00;
175 175
                u1 <<= 10;
176 175
                u1 |= u2;
177 175
                u1 |= 0x10000;
178 175
        }
179 1150
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 1150
        if (u1 < 0x80)
182 225
                *(*d)++ = u1;
183 925
        else if (u1 < 0x800) {
184 475
                *(*d)++ = 0xc0 + u1 / 64;
185 475
                *(*d)++ = 0x80 + u1 % 64;
186 925
        } else if (u1 < 0x10000) {
187 275
                *(*d)++ = 0xe0 + u1 / 4096;
188 275
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 275
                *(*d)++ = 0x80 + u1 % 64;
190 275
        } else {
191 175
                *(*d)++ = 0xf0 + u1 / 262144;
192 175
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 175
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 175
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 1400
}
198
199
static char *
200 24604256
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 24604256
        AN(e);
205 24604256
        vjsn_skip_ws(js);
206 24604256
        VJSN_EXPECT(js, '"', NULL);
207 24603756
        b = p = js->ptr;
208 340125056
        while (*js->ptr != '"') {
209 315522000
                if (*js->ptr == '\0') {
210 175
                        js->err = "Unterminated string";
211 175
                        return (NULL);
212
                }
213 315521825
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 75
                        js->err = "Unescaped control char in string";
215 75
                        return (NULL);
216
                }
217 315521750
                if (*js->ptr != '\\') {
218 310330760
                        *p++ = *js->ptr++;
219 310330760
                        continue;
220
                }
221 5190990
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 67025
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 25
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 25
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 4611899
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 510391
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 25
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 1400
                        vjsn_unicode(js, &p);
232 1400
                        if (js->err != NULL)
233 250
                                return (NULL);
234 1150
                        break;
235
                default:
236 200
                        js->err = "Bad string escape";
237 200
                        return (NULL);
238
                }
239
        }
240 24603056
        VJSN_EXPECT(js, '"', NULL);
241 24603056
        *p = '\0';
242 24603056
        *e = p;
243 24603056
        return (b);
244 24604256
}
245
246
static struct vjsn_val *
247 1117572
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 1117572
        VJSN_EXPECT(js, '{', NULL);
253
254 1117572
        jsv = vjsn_val_new(VJSN_OBJECT);
255 1117572
        AN(jsv);
256
257 1117572
        vjsn_skip_ws(js);
258 1117572
        if (*js->ptr != '}') {
259 9712437
                while (1) {
260 9712437
                        s = vjsn_string(js, &e);
261 9712437
                        if (js->err != NULL)
262 525
                                return (jsv);
263 9711912
                        vjsn_skip_ws(js);
264 9711912
                        VJSN_EXPECT(js, ':', jsv);
265 9711787
                        jsve = vjsn_value(js);
266 9711787
                        if (js->err != NULL) {
267 125
                                if (jsve != NULL)
268 25
                                        vjsn_val_delete(jsve);
269 125
                                return (jsv);
270
                        }
271 9711662
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 9711662
                        jsve->name = s;
273 9711662
                        jsve->name_e = e;
274 9711662
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 9711662
                        vjsn_skip_ws(js);
276 9711662
                        if (*js->ptr == '}')
277 1116572
                                break;
278 8595090
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 1116572
        }
281 1116747
        VJSN_EXPECT(js, '}', jsv);
282 1116747
        return (jsv);
283 1117572
}
284
285
static struct vjsn_val *
286 2683750
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 2683750
        VJSN_EXPECT(js, '[', NULL);
291
292 2683750
        jsv = vjsn_val_new(VJSN_ARRAY);
293 2683750
        AN(jsv);
294
295 2683750
        vjsn_skip_ws(js);
296 2683750
        if (*js->ptr != ']') {
297 10606050
                while (1) {
298 10606050
                        jsve = vjsn_value(js);
299 10606050
                        if (js->err != NULL) {
300 2425
                                if (jsve != NULL)
301 1325
                                        vjsn_val_delete(jsve);
302 2425
                                return (jsv);
303
                        }
304 10603625
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 10603625
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 10603625
                        vjsn_skip_ws(js);
307 10603625
                        if (*js->ptr == ']')
308 2678850
                                break;
309 7924775
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 2678850
        }
312 2680750
        VJSN_EXPECT(js, ']', jsv);
313 2680750
        return (jsv);
314 2683750
}
315
316
static struct vjsn_val *
317 1080922
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 1080922
        jsv = vjsn_val_new(VJSN_NUMBER);
322 1080922
        AN(jsv);
323
324 1080922
        jsv->value = js->ptr;
325
326 1080922
        if (*js->ptr == '-')
327 825
                js->ptr++;
328 1080922
        if (*js->ptr < '0' || *js->ptr > '9') {
329 150
                js->err = "Bad number";
330 150
                return (jsv);
331
        }
332 1080772
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 75
                js->err = "Bad number";
334 75
                return (jsv);
335
        }
336 4103471
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 3022774
                js->ptr++;
338 1080697
        if (*js->ptr == '.') {
339 4425
                js->ptr++;
340 4425
                if (*js->ptr < '0' || *js->ptr > '9') {
341 175
                        js->err = "Bad number";
342 175
                        return (jsv);
343
                }
344 21300
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 17050
                        js->ptr++;
346 4250
        }
347 1080522
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 675
                js->ptr++;
349 675
                if (*js->ptr == '-' || *js->ptr == '+')
350 325
                        js->ptr++;
351 675
                if (*js->ptr < '0' || *js->ptr > '9') {
352 325
                        js->err = "Bad number";
353 325
                        return (jsv);
354
                }
355 850
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 500
                        js->ptr++;
357 350
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 1080197
        return (jsv);
363 1080922
}
364
365
static struct vjsn_val *
366 20388938
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 20388938
        AZ(js->err);
371 20388938
        vjsn_skip_ws(js);
372 20388938
        if (*js->ptr == '{')
373 1117572
                return (vjsn_object(js));
374 19271366
        if (*js->ptr== '[')
375 2683750
                return (vjsn_array(js));
376 16587616
        if (*js->ptr== '"') {
377 14891819
                jsv = vjsn_val_new(VJSN_STRING);
378 14891819
                jsv->value = vjsn_string(js, &jsv->value_e);
379 14891819
                if (js->err != NULL)
380 675
                        return (jsv);
381 14891144
                AN(jsv->value);
382 14891144
                return (jsv);
383
        }
384 1695797
        if (!strncmp(js->ptr, "true", 4)) {
385 184600
                js->ptr += 4;
386 184600
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 1511197
        if (!strncmp(js->ptr, "false", 5)) {
389 49250
                js->ptr += 5;
390 49250
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 1461947
        if (!strncmp(js->ptr, "null", 4)) {
393 379500
                js->ptr += 4;
394 379500
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 1082447
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 1080922
                return (vjsn_number(js));
398 1525
        js->err = "Unrecognized value";
399 1525
        return (NULL);
400 20388938
}
401
402
struct vjsn *
403 71101
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 71101
        AN(from);
410
411 71101
        AN(err);
412 71101
        *err = NULL;
413
414 71101
        if (to == NULL)
415 71101
                to = strchr(from, '\0');
416 71101
        AN(to);
417
418 71101
        sz = to - from;
419
420 71101
        p = malloc(sz + 1L);
421 71101
        AN(p);
422 71101
        memcpy(p, from, sz);
423 71101
        p[sz] = '\0';
424 71101
        e = p + sz;
425
426 71101
        ALLOC_OBJ(js, VJSN_MAGIC);
427 71101
        AN(js);
428 71101
        js->raw = p;
429 71101
        js->ptr = p;
430
431 71101
        js->value = vjsn_value(js);
432 71101
        if (js->err != NULL) {
433 4200
                *err = js->err;
434 4200
                vjsn_delete(&js);
435 4200
                return (NULL);
436
        }
437
438 66901
        vjsn_skip_ws(js);
439 66901
        if (js->ptr != e) {
440 400
                *err = "Garbage after value";
441 400
                vjsn_delete(&js);
442 400
                return (NULL);
443
        }
444 66501
        return (js);
445 71101
}
446
447
struct vjsn *
448 71101
vjsn_parse(const char *src, const char **err)
449
{
450
451 71101
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 10468157
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 10468157
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 10468157
        AN(key);
461 49276530
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 49247405
                if (vc->name != NULL && !strcmp(vc->name, key))
463 10439032
                        return (vc);
464 38808373
        }
465 29125
        return (NULL);
466 10468157
}
467
468
static void
469 4825
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 4825
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 4825
        printf("%*s", indent, "");
475 4825
        if (jsv->name != NULL)
476 425
                printf("[\"%s\"]: ", jsv->name);
477 4825
        printf("{%s}", jsv->type);
478 4825
        if (jsv->value != NULL) {
479 2275
                if (strlen(jsv->value) < 20)
480 2175
                        printf(" <%s", jsv->value);
481
                else
482 100
                        printf(" <%.10s[...#%zu]",
483 100
                            jsv->value, strlen(jsv->value + 10));
484 2275
                printf(">");
485 2275
        }
486 4825
        printf("\n");
487 7275
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 2450
                vjsn_dump_i(jsve, fo, indent + 2);
489 4825
}
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 2375
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 2375
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 2375
        AN(fo);
504 2375
        vjsn_dump_i(js->value, fo, 0);
505 2375
}
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 19270856
VJSN_TYPES
515
#undef VJSN_TYPE_MACRO
516
517
518
#ifdef VJSN_TEST
519
520
/*
521
 * Test-cases by Nicolas Seriot
522
 *
523
 * See: http://seriot.ch/parsing_json.php
524
 *
525
 * MIT License
526
 *
527
 * Copyright (c) 2016 Nicolas Seriot
528
 *
529
 * Permission is hereby granted, free of charge, to any person obtaining a copy
530
 * of this software and associated documentation files (the "Software"), to deal
531
 * in the Software without restriction, including without limitation the rights
532
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
533
 * copies of the Software, and to permit persons to whom the Software is
534
 * furnished to do so, subject to the following conditions:
535
 *
536
 * The above copyright notice and this permission notice shall be included in
537
 * all copies or substantial portions of the Software.
538
 *
539
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
540
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
541
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
542
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
543
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
544
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
545
 * SOFTWARE.
546
 *
547
 * We skip tests containing NUL, because we're lazy (The code will actually
548
 * pass these tests if you provide for a way to pass the true length of the
549
 * input to it, and we skip really huge tests, because we are only limited
550
 * by available memory.
551
 *
552
 * To produce the C-data-structures:
553
 *
554
 * Clone https://github.com/nst/JSONTestSuite.git
555
 *
556
 * And run this python in test_parsing:
557
558
        import glob
559
560
        skip = {}
561
562
        def emit(fin):
563
                if fin in skip:
564
                        return
565
                x = bytearray(open(fin).read())
566
                if 0 in x:
567
                        return
568
                if len(x) > 1000:
569
                        return
570
                t = '\t"'
571
                for i in x:
572
                        t += "\\x%02x" % i
573
                        if len(t) > 64:
574
                                print(t + '"')
575
                                t = '\t"'
576
                print(t + '",')
577
578
        print("const char *good[] = {")
579
        l = list(glob.glob("y_*"))
580
        l.sort()
581
        for f in l:
582
                emit(f)
583
        print("\tNULL")
584
        print("};")
585
586
        print("const char *bad[] = {")
587
        l = list(glob.glob("n_*"))
588
        l.sort()
589
        for f in l:
590
                emit(f)
591
        print("\tNULL")
592
        print("};")
593
 */
594
595
static const char *good[] = {
596
        "\x5b\x5b\x5d\x20\x20\x20\x5d",
597
        "\x5b\x22\x22\x5d",
598
        "\x5b\x5d",
599
        "\x5b\x22\x61\x22\x5d",
600
        "\x5b\x66\x61\x6c\x73\x65\x5d",
601
        "\x5b\x6e\x75\x6c\x6c\x2c\x20\x31\x2c\x20\x22\x31\x22\x2c\x20\x7b"
602
        "\x7d\x5d",
603
        "\x5b\x6e\x75\x6c\x6c\x5d",
604
        "\x5b\x31\x0a\x5d",
605
        "\x20\x5b\x31\x5d",
606
        "\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c"
607
        "\x6c\x2c\x32\x5d",
608
        "\x5b\x32\x5d\x20",
609
        "\x5b\x31\x32\x33\x65\x36\x35\x5d",
610
        "\x5b\x30\x65\x2b\x31\x5d",
611
        "\x5b\x30\x65\x31\x5d",
612
        "\x5b\x20\x34\x5d",
613
        "\x5b\x2d\x30\x2e\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
614
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
615
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
616
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
617
        "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
618
        "\x30\x31\x5d\x0a",
619
        "\x5b\x32\x30\x65\x31\x5d",
620
        "\x5b\x2d\x30\x5d",
621
        "\x5b\x2d\x31\x32\x33\x5d",
622
        "\x5b\x2d\x31\x5d",
623
        "\x5b\x2d\x30\x5d",
624
        "\x5b\x31\x45\x32\x32\x5d",
625
        "\x5b\x31\x45\x2d\x32\x5d",
626
        "\x5b\x31\x45\x2b\x32\x5d",
627
        "\x5b\x31\x32\x33\x65\x34\x35\x5d",
628
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x65\x37\x38\x5d",
629
        "\x5b\x31\x65\x2d\x32\x5d",
630
        "\x5b\x31\x65\x2b\x32\x5d",
631
        "\x5b\x31\x32\x33\x5d",
632
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x37\x38\x39\x5d",
633
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x2c\x20\x22\x64"
634
        "\x66\x67\x22\x3a\x22\x66\x67\x68\x22\x7d",
635
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x7d",
636
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x63\x22"
637
        "\x7d",
638
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x62\x22"
639
        "\x7d",
640
        "\x7b\x7d",
641
        "\x7b\x22\x22\x3a\x30\x7d",
642
        "\x7b\x22\x66\x6f\x6f\x5c\x75\x30\x30\x30\x30\x62\x61\x72\x22\x3a"
643
        "\x20\x34\x32\x7d",
644
        "\x7b\x20\x22\x6d\x69\x6e\x22\x3a\x20\x2d\x31\x2e\x30\x65\x2b\x32"
645
        "\x38\x2c\x20\x22\x6d\x61\x78\x22\x3a\x20\x31\x2e\x30\x65\x2b\x32"
646
        "\x38\x20\x7d",
647
        "\x7b\x22\x78\x22\x3a\x5b\x7b\x22\x69\x64\x22\x3a\x20\x22\x78\x78"
648
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
649
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
650
        "\x78\x78\x78\x78\x78\x78\x22\x7d\x5d\x2c\x20\x22\x69\x64\x22\x3a"
651
        "\x20\x22\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
652
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
653
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x22\x7d",
654
        "\x7b\x22\x61\x22\x3a\x5b\x5d\x7d",
655
        "\x7b\x22\x74\x69\x74\x6c\x65\x22\x3a\x22\x5c\x75\x30\x34\x31\x66"
656
        "\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x33\x62\x5c\x75\x30\x34"
657
        "\x34\x32\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x34\x30\x5c\x75"
658
        "\x30\x34\x33\x30\x20\x5c\x75\x30\x34\x31\x37\x5c\x75\x30\x34\x33"
659
        "\x35\x5c\x75\x30\x34\x33\x63\x5c\x75\x30\x34\x33\x62\x5c\x75\x30"
660
        "\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c"
661
        "\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d",
662
        "\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d",
663
        "\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75"
664
        "\x31\x32\x41\x42\x22\x5d",
665
        "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d"
666
        "",
667
        "\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75"
668
        "\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d",
669
        "\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72"
670
        "\x5c\x74\x22\x5d",
671
        "\x5b\x22\x5c\x5c\x75\x30\x30\x30\x30\x22\x5d",
672
        "\x5b\x22\x5c\x22\x22\x5d",
673
        "\x5b\x22\x61\x2f\x2a\x62\x2a\x2f\x63\x2f\x2a\x64\x2f\x2f\x65\x22"
674
        "\x5d",
675
        "\x5b\x22\x5c\x5c\x61\x22\x5d",
676
        "\x5b\x22\x5c\x5c\x6e\x22\x5d",
677
        "\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d",
678
        "\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d",
679
        "\x5b\x22\x61\x73\x64\x22\x5d",
680
        "\x5b\x20\x22\x61\x73\x64\x22\x5d",
681
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d"
682
        "",
683
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22"
684
        "\x5d",
685
        "\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d",
686
        "\x5b\x22\xef\xbf\xbf\x22\x5d",
687
        "\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d",
688
        "\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d",
689
        "\x5b\x22\xcf\x80\x22\x5d",
690
        "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d",
691
        "\x5b\x22\x61\x73\x64\x20\x22\x5d",
692
        "\x22\x20\x22",
693
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d"
694
        "",
695
        "\x5b\x22\x5c\x75\x30\x38\x32\x31\x22\x5d",
696
        "\x5b\x22\x5c\x75\x30\x31\x32\x33\x22\x5d",
697
        "\x5b\x22\xe2\x80\xa8\x22\x5d",
698
        "\x5b\x22\xe2\x80\xa9\x22\x5d",
699
        "\x5b\x22\x5c\x75\x30\x30\x36\x31\x5c\x75\x33\x30\x61\x66\x5c\x75"
700
        "\x33\x30\x45\x41\x5c\x75\x33\x30\x62\x39\x22\x5d",
701
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x30\x41\x6c\x69\x6e\x65\x22"
702
        "\x5d",
703
        "\x5b\x22\x7f\x22\x5d",
704
        "\x5b\x22\x5c\x75\x41\x36\x36\x44\x22\x5d",
705
        "\x5b\x22\x5c\x75\x30\x30\x35\x43\x22\x5d",
706
        "\x5b\x22\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82\x22\x5d",
707
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
708
        "",
709
        "\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
710
        "",
711
        "\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d",
712
        "\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d",
713
        "\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d",
714
        "\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d",
715
        "\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d",
716
        "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d",
717
        "\x5b\x22\x61\x7f\x61\x22\x5d",
718
        "\x66\x61\x6c\x73\x65",
719
        "\x34\x32",
720
        "\x2d\x30\x2e\x31",
721
        "\x6e\x75\x6c\x6c",
722
        "\x22\x61\x73\x64\x22",
723
        "\x74\x72\x75\x65",
724
        "\x22\x22",
725
        "\x5b\x22\x61\x22\x5d\x0a",
726
        "\x5b\x74\x72\x75\x65\x5d",
727
        "\x20\x5b\x5d\x20",
728
        NULL
729
};
730
static const char *bad[] = {
731
        "\x5b\x31\x20\x74\x72\x75\x65\x5d",
732
        "\x5b\x61\xe5\x5d",
733
        "\x5b\x22\x22\x3a\x20\x31\x5d",
734
        "\x5b\x22\x22\x5d\x2c",
735
        "\x5b\x2c\x31\x5d",
736
        "\x5b\x31\x2c\x2c\x32\x5d",
737
        "\x5b\x22\x78\x22\x2c\x2c\x5d",
738
        "\x5b\x22\x78\x22\x5d\x5d",
739
        "\x5b\x22\x22\x2c\x5d",
740
        "\x5b\x22\x78\x22",
741
        "\x5b\x78",
742
        "\x5b\x33\x5b\x34\x5d\x5d",
743
        "\x5b\xff\x5d",
744
        "\x5b\x31\x3a\x32\x5d",
745
        "\x5b\x2c\x5d",
746
        "\x5b\x2d\x5d",
747
        "\x5b\x20\x20\x20\x2c\x20\x22\x22\x5d",
748
        "\x5b\x22\x61\x22\x2c\x0a\x34\x0a\x2c\x31\x2c",
749
        "\x5b\x31\x2c\x5d",
750
        "\x5b\x31\x2c\x2c\x5d",
751
        "\x5b\x22\x0b\x61\x22\x5c\x66\x5d",
752
        "\x5b\x2a\x5d",
753
        "\x5b\x22\x22",
754
        "\x5b\x31\x2c",
755
        "\x5b\x31\x2c\x0a\x31\x0a\x2c\x31",
756
        "\x5b\x7b\x7d",
757
        "\x5b\x66\x61\x6c\x73\x5d",
758
        "\x5b\x6e\x75\x6c\x5d",
759
        "\x5b\x74\x72\x75\x5d",
760
        "\x5b\x2b\x2b\x31\x32\x33\x34\x5d",
761
        "\x5b\x2b\x31\x5d",
762
        "\x5b\x2b\x49\x6e\x66\x5d",
763
        "\x5b\x2d\x30\x31\x5d",
764
        "\x5b\x2d\x31\x2e\x30\x2e\x5d",
765
        "\x5b\x2d\x32\x2e\x5d",
766
        "\x5b\x2d\x4e\x61\x4e\x5d",
767
        "\x5b\x2e\x2d\x31\x5d",
768
        "\x5b\x2e\x32\x65\x2d\x33\x5d",
769
        "\x5b\x30\x2e\x31\x2e\x32\x5d",
770
        "\x5b\x30\x2e\x33\x65\x2b\x5d",
771
        "\x5b\x30\x2e\x33\x65\x5d",
772
        "\x5b\x30\x2e\x65\x31\x5d",
773
        "\x5b\x30\x45\x2b\x5d",
774
        "\x5b\x30\x45\x5d",
775
        "\x5b\x30\x65\x2b\x5d",
776
        "\x5b\x30\x65\x5d",
777
        "\x5b\x31\x2e\x30\x65\x2b\x5d",
778
        "\x5b\x31\x2e\x30\x65\x2d\x5d",
779
        "\x5b\x31\x2e\x30\x65\x5d",
780
        "\x5b\x31\x20\x30\x30\x30\x2e\x30\x5d",
781
        "\x5b\x31\x65\x45\x32\x5d",
782
        "\x5b\x32\x2e\x65\x2b\x33\x5d",
783
        "\x5b\x32\x2e\x65\x2d\x33\x5d",
784
        "\x5b\x32\x2e\x65\x33\x5d",
785
        "\x5b\x39\x2e\x65\x2b\x5d",
786
        "\x5b\x49\x6e\x66\x5d",
787
        "\x5b\x4e\x61\x4e\x5d",
788
        "\x5b\xef\xbc\x91\x5d",
789
        "\x5b\x31\x2b\x32\x5d",
790
        "\x5b\x30\x78\x31\x5d",
791
        "\x5b\x30\x78\x34\x32\x5d",
792
        "\x5b\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
793
        "\x5b\x30\x65\x2b\x2d\x31\x5d",
794
        "\x5b\x2d\x31\x32\x33\x2e\x31\x32\x33\x66\x6f\x6f\x5d",
795
        "\x5b\x31\x32\x33\xe5\x5d",
796
        "\x5b\x31\x65\x31\xe5\x5d",
797
        "\x5b\x30\xe5\x5d\x0a",
798
        "\x5b\x2d\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
799
        "\x5b\x2d\x66\x6f\x6f\x5d",
800
        "\x5b\x2d\x20\x31\x5d",
801
        "\x5b\x2d\x30\x31\x32\x5d",
802
        "\x5b\x2d\x2e\x31\x32\x33\x5d",
803
        "\x5b\x2d\x31\x78\x5d",
804
        "\x5b\x31\x65\x61\x5d",
805
        "\x5b\x31\x65\xe5\x5d",
806
        "\x5b\x31\x2e\x5d",
807
        "\x5b\x2e\x31\x32\x33\x5d",
808
        "\x5b\x31\x2e\x32\x61\x2d\x33\x5d",
809
        "\x5b\x31\x2e\x38\x30\x31\x31\x36\x37\x30\x30\x33\x33\x33\x37\x36"
810
        "\x35\x31\x34\x48\x2d\x33\x30\x38\x5d",
811
        "\x5b\x30\x31\x32\x5d",
812
        "\x5b\x22\x78\x22\x2c\x20\x74\x72\x75\x74\x68\x5d",
813
        "\x7b\x5b\x3a\x20\x22\x78\x22\x7d\x0a",
814
        "\x7b\x22\x78\x22\x2c\x20\x6e\x75\x6c\x6c\x7d",
815
        "\x7b\x22\x78\x22\x3a\x3a\x22\x62\x22\x7d",
816
        "\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d",
817
        "\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d",
818
        "\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d",
819
        "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d",
820
        "\x7b\x22\x61\x22\x20\x62\x7d",
821
        "\x7b\x3a\x22\x62\x22\x7d",
822
        "\x7b\x22\x61\x22\x20\x22\x62\x22\x7d",
823
        "\x7b\x22\x61\x22\x3a",
824
        "\x7b\x22\x61\x22",
825
        "\x7b\x31\x3a\x31\x7d",
826
        "\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d",
827
        "\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a"
828
        "\x6e\x75\x6c\x6c\x7d",
829
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d",
830
        "\x7b\x27\x61\x27\x3a\x30\x7d",
831
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x7d",
832
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f",
833
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f\x2f",
834
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2f",
835
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f",
836
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x2c\x22\x63\x22\x3a\x22\x64"
837
        "\x22\x7d",
838
        "\x7b\x61\x3a\x20\x22\x62\x22\x7d",
839
        "\x7b\x22\x61\x22\x3a\x22\x61",
840
        "\x7b\x20\x22\x66\x6f\x6f\x22\x20\x3a\x20\x22\x62\x61\x72\x22\x2c"
841
        "\x20\x22\x61\x22\x20\x7d",
842
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23",
843
        "\x20",
844
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x22\x5d",
845
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x22\x5d",
846
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d",
847
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d",
848
        "\x5b\xc3\xa9\x5d",
849
        "\x5b\x22\x5c\x78\x30\x30\x22\x5d",
850
        "\x5b\x22\x5c\x5c\x5c\x22\x5d",
851
        "\x5b\x22\x5c\x09\x22\x5d",
852
        "\x5b\x22\x5c\xf0\x9f\x8c\x80\x22\x5d",
853
        "\x5b\x22\x5c\x22\x5d",
854
        "\x5b\x22\x5c\x75\x30\x30\x41\x22\x5d",
855
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x22\x5d",
856
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x44\x38\x30\x30\x5c\x78"
857
        "\x22\x5d",
858
        "\x5b\x22\x5c\x75\xe5\x22\x5d",
859
        "\x5b\x22\x5c\x61\x22\x5d",
860
        "\x5b\x22\x5c\x75\x71\x71\x71\x71\x22\x5d",
861
        "\x5b\x22\x5c\xe5\x22\x5d",
862
        "\x5b\x5c\x75\x30\x30\x32\x30\x22\x61\x73\x64\x22\x5d",
863
        "\x5b\x5c\x6e\x5d",
864
        "\x22",
865
        "\x5b\x27\x73\x69\x6e\x67\x6c\x65\x20\x71\x75\x6f\x74\x65\x27\x5d"
866
        "",
867
        "\x61\x62\x63",
868
        "\x5b\x22\x5c",
869
        "\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d",
870
        "\x5b\x22\x09\x22\x5d",
871
        "\x22\x5c\x55\x41\x36\x36\x44\x22",
872
        "\x22\x22\x78",
873
        "\x5b\xe2\x81\xa0\x5d",
874
        "\xef\xbb\xbf",
875
        "\x3c\x2e\x3e",
876
        "\x5b\x3c\x6e\x75\x6c\x6c\x3e\x5d",
877
        "\x5b\x31\x5d\x78",
878
        "\x5b\x31\x5d\x5d",
879
        "\x5b\x22\x61\x73\x64\x5d",
880
        "\x61\xc3\xa5",
881
        "\x5b\x54\x72\x75\x65\x5d",
882
        "\x31\x5d",
883
        "\x7b\x22\x78\x22\x3a\x20\x74\x72\x75\x65\x2c",
884
        "\x5b\x5d\x5b\x5d",
885
        "\x5d",
886
        "\xef\xbb\x7b\x7d",
887
        "\xe5",
888
        "\x5b",
889
        "",
890
        "\x32\x40",
891
        "\x7b\x7d\x7d",
892
        "\x7b\x22\x22\x3a",
893
        "\x7b\x22\x61\x22\x3a\x2f\x2a\x63\x6f\x6d\x6d\x65\x6e\x74\x2a\x2f"
894
        "\x22\x62\x22\x7d",
895
        "\x7b\x22\x61\x22\x3a\x20\x74\x72\x75\x65\x7d\x20\x22\x78\x22",
896
        "\x5b\x27",
897
        "\x5b\x2c",
898
        "\x5b\x7b",
899
        "\x5b\x22\x61",
900
        "\x5b\x22\x61\x22",
901
        "\x7b",
902
        "\x7b\x5d",
903
        "\x7b\x2c",
904
        "\x7b\x5b",
905
        "\x7b\x22\x61",
906
        "\x7b\x27\x61\x27",
907
        "\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b"
908
        "",
909
        "\xe9",
910
        "\x2a",
911
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23\x7b\x7d",
912
        "\x5b\x5c\x75\x30\x30\x30\x41\x22\x22\x5d",
913
        "\x5b\x31",
914
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x6e\x75\x6c",
915
        "\x5b\x20\x74\x72\x75\x65\x2c\x20\x66\x61\x6c\x73",
916
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x74\x72\x75",
917
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x61\x73\x64\x22",
918
        "\xc3\xa5",
919
        "\x5b\xe2\x81\xa0\x5d",
920
        "\x5b\x0c\x5d",
921
        NULL
922
};
923
924
static void
925 2375
test_good(const char *j)
926
{
927
        struct vjsn *js;
928
        const char *err;
929
930 2375
        js = vjsn_parse(j, &err);
931 2375
        if (js == NULL || err != NULL) {
932 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
933 0
                exit(1);
934
        }
935 2375
        printf("GOOD: %s\n", j);
936 2375
        vjsn_dump(js, stdout);
937 2375
        vjsn_delete(&js);
938 2375
}
939
940
static void
941 4575
test_bad(const char *j)
942
{
943
        struct vjsn *js;
944
        const char *err;
945
946 4575
        js = vjsn_parse(j, &err);
947 4575
        if (js != NULL || err == NULL) {
948 0
                fprintf(stderr, "Parse succeeded %s\n", j);
949 0
                exit(1);
950
        }
951 4575
        printf("BAD: %s %s\n", err, j);
952 4575
}
953
954
int
955 25
main(int argc, char **argv)
956
{
957
        const char **s;
958
959 25
        (void)argc;
960 25
        (void)argv;
961 2400
        for (s = good; *s != NULL; s++)
962 2375
                test_good(*s);
963 4575
        for (s = bad; *s != NULL; s++)
964 4550
                test_bad(*s);
965
966
        /*
967
         * This is part of Nicolas i(ndeterminate) test set, for reasons I
968
         * do not fully grasp, but we want it to test bad.
969
         */
970 25
        test_bad("\"\\uDFAA\"");
971 25
        printf("Tests done\n");
972 25
        return (0);
973
}
974
975
#endif