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 14935221
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 14935221
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 14935221
        AN(jsv);
70 14935221
        VTAILQ_INIT(&jsv->children);
71 14935221
        jsv->type = type;
72 14935221
        return (jsv);
73
}
74
75
static void
76 6687059
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 6687059
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 6687059
        do {
82 13335351
                jsve = VTAILQ_FIRST(&jsv->children);
83 13335351
                if (jsve != NULL) {
84 6648292
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 6648292
                        vjsn_val_delete(jsve);
86 6648292
                }
87 13335351
        } while (jsve != NULL);
88 6687059
        FREE_OBJ(jsv);
89 6687059
}
90
91
void
92 38070
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 38070
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 38070
        if (js->value != NULL)
98 37849
                vjsn_val_delete(js->value);
99 38070
        free(js->raw);
100 38070
        FREE_OBJ(js);
101 38070
}
102
103
static void
104 57618069
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 57618069
        while (1) {
109 124519155
                c = js->ptr[0];
110 124519155
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 66901086
                        *js->ptr++ = '\0';
112 66901086
                        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 57618069
                return;
124
        }
125
}
126
127
static unsigned
128 1173
vjsn_unumber(struct vjsn *js)
129
{
130 1173
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 1173
        VJSN_EXPECT(js, '\\', 0);
135 1173
        VJSN_EXPECT(js, 'u', 0);
136 5423
        for (i = 0; i < 4; i++) {
137 4386
                u <<= 4;
138 4386
                c = *js->ptr;
139 4386
                if (c >= '0' && c <= '9')
140 2788
                        u |= c - '0';                   /*lint !e737 */
141 1598
                else if (c >= 'A' && c <= 'F')
142 1003
                        u |= c - '7';                   /*lint !e737 */
143 595
                else if (c >= 'a' && c <= 'f')
144 476
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 119
                        js->err = "Illegal \\uXXXX sequence";
147 119
                        return (0);
148
                }
149 4267
                js->ptr++;
150 4267
        }
151 1037
        return (u);
152 1173
}
153
154
static void
155 952
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 952
        u1 = vjsn_unumber(js);
160 952
        if (js->err)
161 51
                return;
162
163 901
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 17
                js->err = "Lone second UTF-16 Surrogate";
165 17
                return;
166
        }
167 884
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 221
                u2 = vjsn_unumber(js);
169 221
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 102
                        js->err = "Bad UTF-16 Surrogate pair";
171 102
                        return;
172
                }
173 119
                u1 -= 0xd800;
174 119
                u2 -= 0xdc00;
175 119
                u1 <<= 10;
176 119
                u1 |= u2;
177 119
                u1 |= 0x10000;
178 119
        }
179 782
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 782
        if (u1 < 0x80)
182 153
                *(*d)++ = u1;
183 629
        else if (u1 < 0x800) {
184 323
                *(*d)++ = 0xc0 + u1 / 64;
185 323
                *(*d)++ = 0x80 + u1 % 64;
186 629
        } else if (u1 < 0x10000) {
187 187
                *(*d)++ = 0xe0 + u1 / 4096;
188 187
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 187
                *(*d)++ = 0x80 + u1 % 64;
190 187
        } else {
191 119
                *(*d)++ = 0xf0 + u1 / 262144;
192 119
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 119
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 119
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 952
}
198
199
static char *
200 17928239
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 17928239
        AN(e);
205 17928239
        vjsn_skip_ws(js);
206 17928239
        VJSN_EXPECT(js, '"', NULL);
207 17927899
        b = p = js->ptr;
208 251211662
        while (*js->ptr != '"') {
209 233284239
                if (*js->ptr == '\0') {
210 119
                        js->err = "Unterminated string";
211 119
                        return (NULL);
212
                }
213 233284120
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 51
                        js->err = "Unescaped control char in string";
215 51
                        return (NULL);
216
                }
217 233284069
                if (*js->ptr != '\\') {
218 229404746
                        *p++ = *js->ptr++;
219 229404746
                        continue;
220
                }
221 3879323
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 48637
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 17
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 17
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 3435018
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 394529
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 17
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 952
                        vjsn_unicode(js, &p);
232 952
                        if (js->err != NULL)
233 170
                                return (NULL);
234 782
                        break;
235
                default:
236 136
                        js->err = "Bad string escape";
237 136
                        return (NULL);
238
                }
239
        }
240 17927423
        VJSN_EXPECT(js, '"', NULL);
241 17927423
        *p = '\0';
242 17927423
        *e = p;
243 17927423
        return (b);
244 17928239
}
245
246
static struct vjsn_val *
247 806243
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 806243
        VJSN_EXPECT(js, '{', NULL);
253
254 806243
        jsv = vjsn_val_new(VJSN_OBJECT);
255 806243
        AN(jsv);
256
257 806243
        vjsn_skip_ws(js);
258 806243
        if (*js->ptr != '}') {
259 7022003
                while (1) {
260 7022003
                        s = vjsn_string(js, &e);
261 7022003
                        if (js->err != NULL)
262 357
                                return (jsv);
263 7021646
                        vjsn_skip_ws(js);
264 7021646
                        VJSN_EXPECT(js, ':', jsv);
265 7021561
                        jsve = vjsn_value(js);
266 7021561
                        if (js->err != NULL) {
267 85
                                if (jsve != NULL)
268 17
                                        vjsn_val_delete(jsve);
269 85
                                return (jsv);
270
                        }
271 7021476
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 7021476
                        jsve->name = s;
273 7021476
                        jsve->name_e = e;
274 7021476
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 7021476
                        vjsn_skip_ws(js);
276 7021476
                        if (*js->ptr == '}')
277 805563
                                break;
278 6215913
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 805563
        }
281 805682
        VJSN_EXPECT(js, '}', jsv);
282 805682
        return (jsv);
283 806243
}
284
285
static struct vjsn_val *
286 1994015
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 1994015
        VJSN_EXPECT(js, '[', NULL);
291
292 1994015
        jsv = vjsn_val_new(VJSN_ARRAY);
293 1994015
        AN(jsv);
294
295 1994015
        vjsn_skip_ws(js);
296 1994015
        if (*js->ptr != ']') {
297 7865033
                while (1) {
298 7865033
                        jsve = vjsn_value(js);
299 7865033
                        if (js->err != NULL) {
300 1649
                                if (jsve != NULL)
301 901
                                        vjsn_val_delete(jsve);
302 1649
                                return (jsv);
303
                        }
304 7863384
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 7863384
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 7863384
                        vjsn_skip_ws(js);
307 7863384
                        if (*js->ptr == ']')
308 1990649
                                break;
309 5872735
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 1990649
        }
312 1991975
        VJSN_EXPECT(js, ']', jsv);
313 1991975
        return (jsv);
314 1994015
}
315
316
static struct vjsn_val *
317 779553
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 779553
        jsv = vjsn_val_new(VJSN_NUMBER);
322 779553
        AN(jsv);
323
324 779553
        jsv->value = js->ptr;
325
326 779553
        if (*js->ptr == '-')
327 561
                js->ptr++;
328 779553
        if (*js->ptr < '0' || *js->ptr > '9') {
329 102
                js->err = "Bad number";
330 102
                return (jsv);
331
        }
332 779451
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 51
                js->err = "Bad number";
334 51
                return (jsv);
335
        }
336 2993364
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 2213964
                js->ptr++;
338 779400
        if (*js->ptr == '.') {
339 3043
                js->ptr++;
340 3043
                if (*js->ptr < '0' || *js->ptr > '9') {
341 119
                        js->err = "Bad number";
342 119
                        return (jsv);
343
                }
344 14620
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 11696
                        js->ptr++;
346 2924
        }
347 779281
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 459
                js->ptr++;
349 459
                if (*js->ptr == '-' || *js->ptr == '+')
350 221
                        js->ptr++;
351 459
                if (*js->ptr < '0' || *js->ptr > '9') {
352 221
                        js->err = "Bad number";
353 221
                        return (jsv);
354
                }
355 578
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 340
                        js->ptr++;
357 238
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 779060
        return (jsv);
363 779553
}
364
365
static struct vjsn_val *
366 14936258
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 14936258
        AZ(js->err);
371 14936258
        vjsn_skip_ws(js);
372 14936258
        if (*js->ptr == '{')
373 806243
                return (vjsn_object(js));
374 14130015
        if (*js->ptr== '[')
375 1994015
                return (vjsn_array(js));
376 12136000
        if (*js->ptr== '"') {
377 10906236
                jsv = vjsn_val_new(VJSN_STRING);
378 10906236
                jsv->value = vjsn_string(js, &jsv->value_e);
379 10906236
                if (js->err != NULL)
380 459
                        return (jsv);
381 10905777
                AN(jsv->value);
382 10905777
                return (jsv);
383
        }
384 1229764
        if (!strncmp(js->ptr, "true", 4)) {
385 134028
                js->ptr += 4;
386 134028
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 1095736
        if (!strncmp(js->ptr, "false", 5)) {
389 35088
                js->ptr += 5;
390 35088
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 1060648
        if (!strncmp(js->ptr, "null", 4)) {
393 280058
                js->ptr += 4;
394 280058
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 780590
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 779553
                return (vjsn_number(js));
398 1037
        js->err = "Unrecognized value";
399 1037
        return (NULL);
400 14936258
}
401
402
struct vjsn *
403 49664
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 49664
        AN(from);
410
411 49664
        AN(err);
412 49664
        *err = NULL;
413
414 49664
        if (to == NULL)
415 49664
                to = strchr(from, '\0');
416 49664
        AN(to);
417
418 49664
        sz = to - from;
419
420 49664
        p = malloc(sz + 1L);
421 49664
        AN(p);
422 49664
        memcpy(p, from, sz);
423 49664
        p[sz] = '\0';
424 49664
        e = p + sz;
425
426 49664
        ALLOC_OBJ(js, VJSN_MAGIC);
427 49664
        AN(js);
428 49664
        js->raw = p;
429 49664
        js->ptr = p;
430
431 49664
        js->value = vjsn_value(js);
432 49664
        if (js->err != NULL) {
433 2856
                *err = js->err;
434 2856
                vjsn_delete(&js);
435 2856
                return (NULL);
436
        }
437
438 46808
        vjsn_skip_ws(js);
439 46808
        if (js->ptr != e) {
440 272
                *err = "Garbage after value";
441 272
                vjsn_delete(&js);
442 272
                return (NULL);
443
        }
444 46536
        return (js);
445 49664
}
446
447
struct vjsn *
448 49664
vjsn_parse(const char *src, const char **err)
449
{
450
451 49664
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 7132353
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 7132353
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 7132353
        AN(key);
461 33639024
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 33618369
                if (vc->name != NULL && !strcmp(vc->name, key))
463 7111698
                        return (vc);
464 26506671
        }
465 20655
        return (NULL);
466 7132353
}
467
468
static void
469 3281
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 3281
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 3281
        printf("%*s", indent, "");
475 3281
        if (jsv->name != NULL)
476 289
                printf("[\"%s\"]: ", jsv->name);
477 3281
        printf("{%s}", jsv->type);
478 3281
        if (jsv->value != NULL) {
479 1547
                if (strlen(jsv->value) < 20)
480 1479
                        printf(" <%s", jsv->value);
481
                else
482 68
                        printf(" <%.10s[...#%zu]",
483 68
                            jsv->value, strlen(jsv->value + 10));
484 1547
                printf(">");
485 1547
        }
486 3281
        printf("\n");
487 4947
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 1666
                vjsn_dump_i(jsve, fo, indent + 2);
489 3281
}
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 1615
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 1615
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 1615
        AN(fo);
504 1615
        vjsn_dump_i(js->value, fo, 0);
505 1615
}
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 13772317
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 1615
test_good(const char *j)
927
{
928
        struct vjsn *js;
929
        const char *err;
930
931 1615
        js = vjsn_parse(j, &err);
932 1615
        if (js == NULL || err != NULL) {
933 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
934 0
                exit(1);
935
        }
936 1615
        printf("GOOD: %s\n", j);
937 1615
        vjsn_dump(js, stdout);
938 1615
        vjsn_delete(&js);
939 1615
}
940
941
static void
942 3111
test_bad(const char *j)
943
{
944
        struct vjsn *js;
945
        const char *err;
946
947 3111
        js = vjsn_parse(j, &err);
948 3111
        if (js != NULL || err == NULL) {
949 0
                fprintf(stderr, "Parse succeeded %s\n", j);
950 0
                exit(1);
951
        }
952 3111
        printf("BAD: %s %s\n", err, j);
953 3111
}
954
955
int
956 17
main(int argc, char **argv)
957
{
958
        const char **s;
959
960 17
        (void)argc;
961 17
        (void)argv;
962 1632
        for (s = good; *s != NULL; s++)
963 1615
                test_good(*s);
964 3111
        for (s = bad; *s != NULL; s++)
965 3094
                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 17
        test_bad("\"\\uDFAA\"");
972 17
        printf("Tests done\n");
973 17
        return (0);
974
}
975
976
#endif