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