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 21292336
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 21292336
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 21292336
        AN(jsv);
70 21292336
        VTAILQ_INIT(&jsv->children);
71 21292336
        jsv->type = type;
72 21292336
        return (jsv);
73
}
74
75
static void
76 9138952
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 9138952
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 9138952
        do {
82 18223867
                jsve = VTAILQ_FIRST(&jsv->children);
83 18223867
                if (jsve != NULL) {
84 9084915
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 9084915
                        vjsn_val_delete(jsve);
86 9084915
                }
87 18223867
        } while (jsve != NULL);
88 9138952
        FREE_OBJ(jsv);
89 9138952
}
90
91
void
92 53094
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 53094
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 53094
        if (js->value != NULL)
98 52795
                vjsn_val_delete(js->value);
99 53094
        free(js->raw);
100 53094
        FREE_OBJ(js);
101 53094
}
102
103
static void
104 81183497
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 81183497
        while (1) {
109 181158540
                c = js->ptr[0];
110 181158540
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 99975043
                        *js->ptr++ = '\0';
112 99975043
                        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 81183497
                return;
124
        }
125
}
126
127
static unsigned
128 1587
vjsn_unumber(struct vjsn *js)
129
{
130 1587
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 1587
        VJSN_EXPECT(js, '\\', 0);
135 1587
        VJSN_EXPECT(js, 'u', 0);
136 7337
        for (i = 0; i < 4; i++) {
137 5934
                u <<= 4;
138 5934
                c = *js->ptr;
139 5934
                if (c >= '0' && c <= '9')
140 3772
                        u |= c - '0';                   /*lint !e737 */
141 2162
                else if (c >= 'A' && c <= 'F')
142 1357
                        u |= c - '7';                   /*lint !e737 */
143 805
                else if (c >= 'a' && c <= 'f')
144 644
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 161
                        js->err = "Illegal \\uXXXX sequence";
147 161
                        return (0);
148
                }
149 5773
                js->ptr++;
150 5773
        }
151 1403
        return (u);
152 1587
}
153
154
static void
155 1288
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 1288
        u1 = vjsn_unumber(js);
160 1288
        if (js->err)
161 69
                return;
162
163 1219
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 23
                js->err = "Lone second UTF-16 Surrogate";
165 23
                return;
166
        }
167 1196
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 299
                u2 = vjsn_unumber(js);
169 299
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 138
                        js->err = "Bad UTF-16 Surrogate pair";
171 138
                        return;
172
                }
173 161
                u1 -= 0xd800;
174 161
                u2 -= 0xdc00;
175 161
                u1 <<= 10;
176 161
                u1 |= u2;
177 161
                u1 |= 0x10000;
178 161
        }
179 1058
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 1058
        if (u1 < 0x80)
182 207
                *(*d)++ = u1;
183 851
        else if (u1 < 0x800) {
184 437
                *(*d)++ = 0xc0 + u1 / 64;
185 437
                *(*d)++ = 0x80 + u1 % 64;
186 851
        } else if (u1 < 0x10000) {
187 253
                *(*d)++ = 0xe0 + u1 / 4096;
188 253
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 253
                *(*d)++ = 0x80 + u1 % 64;
190 253
        } else {
191 161
                *(*d)++ = 0xf0 + u1 / 262144;
192 161
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 161
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 161
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 1288
}
198
199
static char *
200 25204916
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 25204916
        AN(e);
205 25204916
        vjsn_skip_ws(js);
206 25204916
        VJSN_EXPECT(js, '"', NULL);
207 25204456
        b = p = js->ptr;
208 346429858
        while (*js->ptr != '"') {
209 321226046
                if (*js->ptr == '\0') {
210 161
                        js->err = "Unterminated string";
211 161
                        return (NULL);
212
                }
213 321225885
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 69
                        js->err = "Unescaped control char in string";
215 69
                        return (NULL);
216
                }
217 321225816
                if (*js->ptr != '\\') {
218 315951424
                        *p++ = *js->ptr++;
219 315951424
                        continue;
220
                }
221 5274392
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 65803
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 23
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 23
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 4667791
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 539257
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 23
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 1288
                        vjsn_unicode(js, &p);
232 1288
                        if (js->err != NULL)
233 230
                                return (NULL);
234 1058
                        break;
235
                default:
236 184
                        js->err = "Bad string escape";
237 184
                        return (NULL);
238
                }
239
        }
240 25203812
        VJSN_EXPECT(js, '"', NULL);
241 25203812
        *p = '\0';
242 25203812
        *e = p;
243 25203812
        return (b);
244 25204916
}
245
246
static struct vjsn_val *
247 1101782
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 1101782
        VJSN_EXPECT(js, '{', NULL);
253
254 1101782
        jsv = vjsn_val_new(VJSN_OBJECT);
255 1101782
        AN(jsv);
256
257 1101782
        vjsn_skip_ws(js);
258 1101782
        if (*js->ptr != '}') {
259 9580312
                while (1) {
260 9580312
                        s = vjsn_string(js, &e);
261 9580312
                        if (js->err != NULL)
262 483
                                return (jsv);
263 9579829
                        vjsn_skip_ws(js);
264 9579829
                        VJSN_EXPECT(js, ':', jsv);
265 9579714
                        jsve = vjsn_value(js);
266 9579714
                        if (js->err != NULL) {
267 115
                                if (jsve != NULL)
268 23
                                        vjsn_val_delete(jsve);
269 115
                                return (jsv);
270
                        }
271 9579599
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 9579599
                        jsve->name = s;
273 9579599
                        jsve->name_e = e;
274 9579599
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 9579599
                        vjsn_skip_ws(js);
276 9579599
                        if (*js->ptr == '}')
277 1100862
                                break;
278 8478737
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 1100862
        }
281 1101023
        VJSN_EXPECT(js, '}', jsv);
282 1101023
        return (jsv);
283 1101782
}
284
285
static struct vjsn_val *
286 2715702
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 2715702
        VJSN_EXPECT(js, '[', NULL);
291
292 2715702
        jsv = vjsn_val_new(VJSN_ARRAY);
293 2715702
        AN(jsv);
294
295 2715702
        vjsn_skip_ws(js);
296 2715702
        if (*js->ptr != ']') {
297 11644877
                while (1) {
298 11644877
                        jsve = vjsn_value(js);
299 11644877
                        if (js->err != NULL) {
300 2231
                                if (jsve != NULL)
301 1219
                                        vjsn_val_delete(jsve);
302 2231
                                return (jsv);
303
                        }
304 11642646
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 11642646
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 11642646
                        vjsn_skip_ws(js);
307 11642646
                        if (*js->ptr == ']')
308 2711194
                                break;
309 8931452
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 2711194
        }
312 2712942
        VJSN_EXPECT(js, ']', jsv);
313 2712942
        return (jsv);
314 2715702
}
315
316
static struct vjsn_val *
317 1065695
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 1065695
        jsv = vjsn_val_new(VJSN_NUMBER);
322 1065695
        AN(jsv);
323
324 1065695
        jsv->value = js->ptr;
325
326 1065695
        if (*js->ptr == '-')
327 759
                js->ptr++;
328 1065695
        if (*js->ptr < '0' || *js->ptr > '9') {
329 138
                js->err = "Bad number";
330 138
                return (jsv);
331
        }
332 1065557
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 69
                js->err = "Bad number";
334 69
                return (jsv);
335
        }
336 4081531
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 3016043
                js->ptr++;
338 1065488
        if (*js->ptr == '.') {
339 4140
                js->ptr++;
340 4140
                if (*js->ptr < '0' || *js->ptr > '9') {
341 161
                        js->err = "Bad number";
342 161
                        return (jsv);
343
                }
344 19941
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 15962
                        js->ptr++;
346 3979
        }
347 1065327
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 621
                js->ptr++;
349 621
                if (*js->ptr == '-' || *js->ptr == '+')
350 299
                        js->ptr++;
351 621
                if (*js->ptr < '0' || *js->ptr > '9') {
352 299
                        js->err = "Bad number";
353 299
                        return (jsv);
354
                }
355 782
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 460
                        js->ptr++;
357 322
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 1065028
        return (jsv);
363 1065695
}
364
365
static struct vjsn_val *
366 21293739
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 21293739
        AZ(js->err);
371 21293739
        vjsn_skip_ws(js);
372 21293739
        if (*js->ptr == '{')
373 1101782
                return (vjsn_object(js));
374 20191957
        if (*js->ptr== '[')
375 2715702
                return (vjsn_array(js));
376 17476255
        if (*js->ptr== '"') {
377 15624604
                jsv = vjsn_val_new(VJSN_STRING);
378 15624604
                jsv->value = vjsn_string(js, &jsv->value_e);
379 15624604
                if (js->err != NULL)
380 621
                        return (jsv);
381 15623983
                AN(jsv->value);
382 15623983
                return (jsv);
383
        }
384 1851651
        if (!strncmp(js->ptr, "true", 4)) {
385 181355
                js->ptr += 4;
386 181355
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 1670296
        if (!strncmp(js->ptr, "false", 5)) {
389 47472
                js->ptr += 5;
390 47472
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 1622824
        if (!strncmp(js->ptr, "null", 4)) {
393 555726
                js->ptr += 4;
394 555726
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 1067098
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 1065695
                return (vjsn_number(js));
398 1403
        js->err = "Unrecognized value";
399 1403
        return (NULL);
400 21293739
}
401
402
struct vjsn *
403 69148
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 69148
        AN(from);
410
411 69148
        AN(err);
412 69148
        *err = NULL;
413
414 69148
        if (to == NULL)
415 69148
                to = strchr(from, '\0');
416 69148
        AN(to);
417
418 69148
        sz = to - from;
419
420 69148
        p = malloc(sz + 1L);
421 69148
        AN(p);
422 69148
        memcpy(p, from, sz);
423 69148
        p[sz] = '\0';
424 69148
        e = p + sz;
425
426 69148
        ALLOC_OBJ(js, VJSN_MAGIC);
427 69148
        AN(js);
428 69148
        js->raw = p;
429 69148
        js->ptr = p;
430
431 69148
        js->value = vjsn_value(js);
432 69148
        if (js->err != NULL) {
433 3864
                *err = js->err;
434 3864
                vjsn_delete(&js);
435 3864
                return (NULL);
436
        }
437
438 65284
        vjsn_skip_ws(js);
439 65284
        if (js->ptr != e) {
440 368
                *err = "Garbage after value";
441 368
                vjsn_delete(&js);
442 368
                return (NULL);
443
        }
444 64916
        return (js);
445 69148
}
446
447
struct vjsn *
448 69148
vjsn_parse(const char *src, const char **err)
449
{
450
451 69148
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 9728626
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 9728626
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 9728626
        AN(key);
461 45883386
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 45855234
                if (vc->name != NULL && !strcmp(vc->name, key))
463 9700474
                        return (vc);
464 36154760
        }
465 28152
        return (NULL);
466 9728626
}
467
468
static void
469 4439
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 4439
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 4439
        printf("%*s", indent, "");
475 4439
        if (jsv->name != NULL)
476 391
                printf("[\"%s\"]: ", jsv->name);
477 4439
        printf("{%s}", jsv->type);
478 4439
        if (jsv->value != NULL) {
479 2093
                if (strlen(jsv->value) < 20)
480 2001
                        printf(" <%s", jsv->value);
481
                else
482 92
                        printf(" <%.10s[...#%zu]",
483 92
                            jsv->value, strlen(jsv->value + 10));
484 2093
                printf(">");
485 2093
        }
486 4439
        printf("\n");
487 6693
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 2254
                vjsn_dump_i(jsve, fo, indent + 2);
489 4439
}
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 2185
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 2185
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 2185
        AN(fo);
504 2185
        vjsn_dump_i(js->value, fo, 0);
505 2185
}
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 18747818
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 2185
test_good(const char *j)
927
{
928
        struct vjsn *js;
929
        const char *err;
930
931 2185
        js = vjsn_parse(j, &err);
932 2185
        if (js == NULL || err != NULL) {
933 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
934 0
                exit(1);
935
        }
936 2185
        printf("GOOD: %s\n", j);
937 2185
        vjsn_dump(js, stdout);
938 2185
        vjsn_delete(&js);
939 2185
}
940
941
static void
942 4209
test_bad(const char *j)
943
{
944
        struct vjsn *js;
945
        const char *err;
946
947 4209
        js = vjsn_parse(j, &err);
948 4209
        if (js != NULL || err == NULL) {
949 0
                fprintf(stderr, "Parse succeeded %s\n", j);
950 0
                exit(1);
951
        }
952 4209
        printf("BAD: %s %s\n", err, j);
953 4209
}
954
955
int
956 23
main(int argc, char **argv)
957
{
958
        const char **s;
959
960 23
        (void)argc;
961 23
        (void)argv;
962 2208
        for (s = good; *s != NULL; s++)
963 2185
                test_good(*s);
964 4209
        for (s = bad; *s != NULL; s++)
965 4186
                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 23
        test_bad("\"\\uDFAA\"");
972 23
        printf("Tests done\n");
973 23
        return (0);
974
}
975
976
#endif