vinyl-cache/lib/libvinyl/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 22555536
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 22555536
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 22555536
        AN(jsv);
70 22555536
        VTAILQ_INIT(&jsv->children);
71 22555536
        jsv->type = type;
72 22555536
        return (jsv);
73
}
74
75
static void
76 9977985
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 9977985
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 9977985
        do {
82 19903308
                jsve = VTAILQ_FIRST(&jsv->children);
83 19903308
                if (jsve != NULL) {
84 9925323
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 9925323
                        vjsn_val_delete(jsve);
86 9925323
                }
87 19903308
        } while (jsve != NULL);
88 9977985
        FREE_OBJ(jsv);
89 9977985
}
90
91
void
92 51801
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 51801
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 51801
        if (js->value != NULL)
98 51528
                vjsn_val_delete(js->value);
99 51801
        free(js->raw);
100 51801
        FREE_OBJ(js);
101 51801
}
102
103
static void
104 86498688
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 86498688
        while (1) {
109 189302256
                c = js->ptr[0];
110 189302256
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 102803568
                        *js->ptr++ = '\0';
112 102803568
                        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 86498688
                return;
124
        }
125
}
126
127
static unsigned
128 1449
vjsn_unumber(struct vjsn *js)
129
{
130 1449
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 1449
        VJSN_EXPECT(js, '\\', 0);
135 1449
        VJSN_EXPECT(js, 'u', 0);
136 6699
        for (i = 0; i < 4; i++) {
137 5418
                u <<= 4;
138 5418
                c = *js->ptr;
139 5418
                if (c >= '0' && c <= '9')
140 3444
                        u |= c - '0';                   /*lint !e737 */
141 1974
                else if (c >= 'A' && c <= 'F')
142 1239
                        u |= c - '7';                   /*lint !e737 */
143 735
                else if (c >= 'a' && c <= 'f')
144 588
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 147
                        js->err = "Illegal \\uXXXX sequence";
147 147
                        return (0);
148
                }
149 5271
                js->ptr++;
150 5271
        }
151 1281
        return (u);
152 1449
}
153
154
static void
155 1176
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 1176
        u1 = vjsn_unumber(js);
160 1176
        if (js->err)
161 63
                return;
162
163 1113
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 21
                js->err = "Lone second UTF-16 Surrogate";
165 21
                return;
166
        }
167 1092
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 273
                u2 = vjsn_unumber(js);
169 273
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 126
                        js->err = "Bad UTF-16 Surrogate pair";
171 126
                        return;
172
                }
173 147
                u1 -= 0xd800;
174 147
                u2 -= 0xdc00;
175 147
                u1 <<= 10;
176 147
                u1 |= u2;
177 147
                u1 |= 0x10000;
178 147
        }
179 966
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 966
        if (u1 < 0x80)
182 189
                *(*d)++ = u1;
183 777
        else if (u1 < 0x800) {
184 399
                *(*d)++ = 0xc0 + u1 / 64;
185 399
                *(*d)++ = 0x80 + u1 % 64;
186 777
        } else if (u1 < 0x10000) {
187 231
                *(*d)++ = 0xe0 + u1 / 4096;
188 231
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 231
                *(*d)++ = 0x80 + u1 % 64;
190 231
        } else {
191 147
                *(*d)++ = 0xf0 + u1 / 262144;
192 147
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 147
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 147
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 1176
}
198
199
static char *
200 26962095
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 26962095
        AN(e);
205 26962095
        vjsn_skip_ws(js);
206 26962095
        VJSN_EXPECT(js, '"', NULL);
207 26961675
        b = p = js->ptr;
208 370782371
        while (*js->ptr != '"') {
209 343821284
                if (*js->ptr == '\0') {
210 147
                        js->err = "Unterminated string";
211 147
                        return (NULL);
212
                }
213 343821137
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 63
                        js->err = "Unescaped control char in string";
215 63
                        return (NULL);
216
                }
217 343821074
                if (*js->ptr != '\\') {
218 338054660
                        *p++ = *js->ptr++;
219 338054660
                        continue;
220
                }
221 5766414
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 62559
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 21
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 21
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 5113125
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 589323
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 21
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 1176
                        vjsn_unicode(js, &p);
232 1176
                        if (js->err != NULL)
233 210
                                return (NULL);
234 966
                        break;
235
                default:
236 168
                        js->err = "Bad string escape";
237 168
                        return (NULL);
238
                }
239
        }
240 26961087
        VJSN_EXPECT(js, '"', NULL);
241 26961087
        *p = '\0';
242 26961087
        *e = p;
243 26961087
        return (b);
244 26962095
}
245
246
static struct vjsn_val *
247 1197213
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 1197213
        VJSN_EXPECT(js, '{', NULL);
253
254 1197213
        jsv = vjsn_val_new(VJSN_OBJECT);
255 1197213
        AN(jsv);
256
257 1197213
        vjsn_skip_ws(js);
258 1197213
        if (*js->ptr != '}') {
259 10470168
                while (1) {
260 10470168
                        s = vjsn_string(js, &e);
261 10470168
                        if (js->err != NULL)
262 441
                                return (jsv);
263 10469727
                        vjsn_skip_ws(js);
264 10469727
                        VJSN_EXPECT(js, ':', jsv);
265 10469622
                        jsve = vjsn_value(js);
266 10469622
                        if (js->err != NULL) {
267 105
                                if (jsve != NULL)
268 21
                                        vjsn_val_delete(jsve);
269 105
                                return (jsv);
270
                        }
271 10469517
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 10469517
                        jsve->name = s;
273 10469517
                        jsve->name_e = e;
274 10469517
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 10469517
                        vjsn_skip_ws(js);
276 10469517
                        if (*js->ptr == '}')
277 1196373
                                break;
278 9273144
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 1196373
        }
281 1196520
        VJSN_EXPECT(js, '}', jsv);
282 1196520
        return (jsv);
283 1197213
}
284
285
static struct vjsn_val *
286 2761689
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 2761689
        VJSN_EXPECT(js, '[', NULL);
291
292 2761689
        jsv = vjsn_val_new(VJSN_ARRAY);
293 2761689
        AN(jsv);
294
295 2761689
        vjsn_skip_ws(js);
296 2761689
        if (*js->ptr != ']') {
297 12019581
                while (1) {
298 12019581
                        jsve = vjsn_value(js);
299 12019581
                        if (js->err != NULL) {
300 2037
                                if (jsve != NULL)
301 1113
                                        vjsn_val_delete(jsve);
302 2037
                                return (jsv);
303
                        }
304 12017544
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 12017544
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 12017544
                        vjsn_skip_ws(js);
307 12017544
                        if (*js->ptr == ']')
308 2757573
                                break;
309 9259971
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 2757573
        }
312 2759169
        VJSN_EXPECT(js, ']', jsv);
313 2759169
        return (jsv);
314 2761689
}
315
316
static struct vjsn_val *
317 1162206
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 1162206
        jsv = vjsn_val_new(VJSN_NUMBER);
322 1162206
        AN(jsv);
323
324 1162206
        jsv->value = js->ptr;
325
326 1162206
        if (*js->ptr == '-')
327 693
                js->ptr++;
328 1162206
        if (*js->ptr < '0' || *js->ptr > '9') {
329 126
                js->err = "Bad number";
330 126
                return (jsv);
331
        }
332 1162080
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 63
                js->err = "Bad number";
334 63
                return (jsv);
335
        }
336 4576308
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 3414291
                js->ptr++;
338 1162017
        if (*js->ptr == '.') {
339 3801
                js->ptr++;
340 3801
                if (*js->ptr < '0' || *js->ptr > '9') {
341 147
                        js->err = "Bad number";
342 147
                        return (jsv);
343
                }
344 18291
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 14637
                        js->ptr++;
346 3654
        }
347 1161870
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 567
                js->ptr++;
349 567
                if (*js->ptr == '-' || *js->ptr == '+')
350 273
                        js->ptr++;
351 567
                if (*js->ptr < '0' || *js->ptr > '9') {
352 273
                        js->err = "Bad number";
353 273
                        return (jsv);
354
                }
355 714
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 420
                        js->ptr++;
357 294
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 1161597
        return (jsv);
363 1162206
}
364
365
static struct vjsn_val *
366 22556817
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 22556817
        AZ(js->err);
371 22556817
        vjsn_skip_ws(js);
372 22556817
        if (*js->ptr == '{')
373 1197213
                return (vjsn_object(js));
374 21359604
        if (*js->ptr== '[')
375 2761689
                return (vjsn_array(js));
376 18597915
        if (*js->ptr== '"') {
377 16491927
                jsv = vjsn_val_new(VJSN_STRING);
378 16491927
                jsv->value = vjsn_string(js, &jsv->value_e);
379 16491927
                if (js->err != NULL)
380 567
                        return (jsv);
381 16491360
                AN(jsv->value);
382 16491360
                return (jsv);
383
        }
384 2105988
        if (!vstrncmp(js->ptr, "true", 4)) {
385 226695
                js->ptr += 4;
386 226695
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 1879293
        if (!vstrncmp(js->ptr, "false", 5)) {
389 44940
                js->ptr += 5;
390 44940
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 1834353
        if (!vstrncmp(js->ptr, "null", 4)) {
393 670866
                js->ptr += 4;
394 670866
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 1163487
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 1162206
                return (vjsn_number(js));
398 1281
        js->err = "Unrecognized value";
399 1281
        return (NULL);
400 22556817
}
401
402
struct vjsn *
403 67614
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 67614
        AN(from);
410
411 67614
        AN(err);
412 67614
        *err = NULL;
413
414 67614
        if (to == NULL)
415 67614
                to = strchr(from, '\0');
416 67614
        AN(to);
417
418 67614
        sz = to - from;
419
420 67614
        p = malloc(sz + 1L);
421 67614
        AN(p);
422 67614
        vmemcpy(p, from, sz);
423 67614
        p[sz] = '\0';
424 67614
        e = p + sz;
425
426 67614
        ALLOC_OBJ(js, VJSN_MAGIC);
427 67614
        AN(js);
428 67614
        js->raw = p;
429 67614
        js->ptr = p;
430
431 67614
        js->value = vjsn_value(js);
432 67614
        if (js->err != NULL) {
433 3528
                *err = js->err;
434 3528
                vjsn_delete(&js);
435 3528
                return (NULL);
436
        }
437
438 64086
        vjsn_skip_ws(js);
439 64086
        if (js->ptr != e) {
440 336
                *err = "Garbage after value";
441 336
                vjsn_delete(&js);
442 336
                return (NULL);
443
        }
444 63750
        return (js);
445 67614
}
446
447
struct vjsn *
448 67614
vjsn_parse(const char *src, const char **err)
449
{
450
451 67614
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 10703451
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 10703451
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 10703451
        AN(key);
461 50306543
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 50279054
                if (vc->name != NULL && !vstrcmp(vc->name, key))
463 10675962
                        return (vc);
464 39603092
        }
465 27489
        return (NULL);
466 10703451
}
467
468
static void
469 4053
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 4053
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 4053
        printf("%*s", indent, "");
475 4053
        if (jsv->name != NULL)
476 357
                printf("[\"%s\"]: ", jsv->name);
477 4053
        printf("{%s}", jsv->type);
478 4053
        if (jsv->value != NULL) {
479 1911
                if (vstrlen(jsv->value) < 20)
480 1827
                        printf(" <%s", jsv->value);
481
                else
482 84
                        printf(" <%.10s[...#%zu]",
483 84
                            jsv->value, vstrlen(jsv->value + 10));
484 1911
                printf(">");
485 1911
        }
486 4053
        printf("\n");
487 6111
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 2058
                vjsn_dump_i(jsve, fo, indent + 2);
489 4053
}
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 1995
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 1995
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 1995
        AN(fo);
504 1995
        vjsn_dump_i(js->value, fo, 0);
505 1995
}
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 19798828
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
def emit(fin):
561
    x = bytearray(open(fin, 'rb').read())
562
    if 0 in x:
563
        print("\t// SKIP: NUL in", fin)
564
        return
565
    if len(x) > 1000:
566
        print("\t// SKIP: LONG ", fin)
567
        return
568
    t = '\t"'
569
    for i in x:
570
        t += "\\x%02x" % i
571
        if len(t) > 64:
572
            print(t + '"')
573
            t = '\t"'
574
    print(t + '",')
575
576
print("static const char *good[] = {")
577
for f in sorted(glob.glob("y_*")):
578
    emit(f)
579
print("\tNULL")
580
print("};\n")
581
582
print("static const char *bad[] = {")
583
for f in sorted(glob.glob("n_*")):
584
        emit(f)
585
print("\tNULL")
586
print("};")
587
588
 */
589
590
static const char *good[] = {
591
        "\x5b\x5b\x5d\x20\x20\x20\x5d",
592
        "\x5b\x22\x22\x5d",
593
        "\x5b\x5d",
594
        "\x5b\x22\x61\x22\x5d",
595
        "\x5b\x66\x61\x6c\x73\x65\x5d",
596
        "\x5b\x6e\x75\x6c\x6c\x2c\x20\x31\x2c\x20\x22\x31\x22\x2c\x20\x7b"
597
        "\x7d\x5d",
598
        "\x5b\x6e\x75\x6c\x6c\x5d",
599
        "\x5b\x31\x0a\x5d",
600
        "\x20\x5b\x31\x5d",
601
        "\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c"
602
        "\x6c\x2c\x32\x5d",
603
        "\x5b\x32\x5d\x20",
604
        "\x5b\x31\x32\x33\x65\x36\x35\x5d",
605
        "\x5b\x30\x65\x2b\x31\x5d",
606
        "\x5b\x30\x65\x31\x5d",
607
        "\x5b\x20\x34\x5d",
608
        "\x5b\x2d\x30\x2e\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
609
        "\x30\x30\x30\x30\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\x31\x5d\x0a",
614
        "\x5b\x32\x30\x65\x31\x5d",
615
        "\x5b\x2d\x30\x5d",
616
        "\x5b\x2d\x31\x32\x33\x5d",
617
        "\x5b\x2d\x31\x5d",
618
        "\x5b\x2d\x30\x5d",
619
        "\x5b\x31\x45\x32\x32\x5d",
620
        "\x5b\x31\x45\x2d\x32\x5d",
621
        "\x5b\x31\x45\x2b\x32\x5d",
622
        "\x5b\x31\x32\x33\x65\x34\x35\x5d",
623
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x65\x37\x38\x5d",
624
        "\x5b\x31\x65\x2d\x32\x5d",
625
        "\x5b\x31\x65\x2b\x32\x5d",
626
        "\x5b\x31\x32\x33\x5d",
627
        "\x5b\x31\x32\x33\x2e\x34\x35\x36\x37\x38\x39\x5d",
628
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x2c\x20\x22\x64"
629
        "\x66\x67\x22\x3a\x22\x66\x67\x68\x22\x7d",
630
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x7d",
631
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x63\x22"
632
        "\x7d",
633
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x62\x22"
634
        "\x7d",
635
        "\x7b\x7d",
636
        "\x7b\x22\x22\x3a\x30\x7d",
637
        "\x7b\x22\x66\x6f\x6f\x5c\x75\x30\x30\x30\x30\x62\x61\x72\x22\x3a"
638
        "\x20\x34\x32\x7d",
639
        "\x7b\x20\x22\x6d\x69\x6e\x22\x3a\x20\x2d\x31\x2e\x30\x65\x2b\x32"
640
        "\x38\x2c\x20\x22\x6d\x61\x78\x22\x3a\x20\x31\x2e\x30\x65\x2b\x32"
641
        "\x38\x20\x7d",
642
        "\x7b\x22\x78\x22\x3a\x5b\x7b\x22\x69\x64\x22\x3a\x20\x22\x78\x78"
643
        "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\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\x22\x7d\x5d\x2c\x20\x22\x69\x64\x22\x3a"
646
        "\x20\x22\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
647
        "\x78\x78\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\x22\x7d",
649
        "\x7b\x22\x61\x22\x3a\x5b\x5d\x7d",
650
        "\x7b\x22\x74\x69\x74\x6c\x65\x22\x3a\x22\x5c\x75\x30\x34\x31\x66"
651
        "\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x33\x62\x5c\x75\x30\x34"
652
        "\x34\x32\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x34\x30\x5c\x75"
653
        "\x30\x34\x33\x30\x20\x5c\x75\x30\x34\x31\x37\x5c\x75\x30\x34\x33"
654
        "\x35\x5c\x75\x30\x34\x33\x63\x5c\x75\x30\x34\x33\x62\x5c\x75\x30"
655
        "\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c"
656
        "\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d",
657
        "\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d",
658
        "\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75"
659
        "\x31\x32\x41\x42\x22\x5d",
660
        "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d"
661
        "",
662
        "\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75"
663
        "\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d",
664
        "\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72"
665
        "\x5c\x74\x22\x5d",
666
        "\x5b\x22\x5c\x5c\x75\x30\x30\x30\x30\x22\x5d",
667
        "\x5b\x22\x5c\x22\x22\x5d",
668
        "\x5b\x22\x61\x2f\x2a\x62\x2a\x2f\x63\x2f\x2a\x64\x2f\x2f\x65\x22"
669
        "\x5d",
670
        "\x5b\x22\x5c\x5c\x61\x22\x5d",
671
        "\x5b\x22\x5c\x5c\x6e\x22\x5d",
672
        "\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d",
673
        "\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d",
674
        "\x5b\x22\x61\x73\x64\x22\x5d",
675
        "\x5b\x20\x22\x61\x73\x64\x22\x5d",
676
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d"
677
        "",
678
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22"
679
        "\x5d",
680
        "\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d",
681
        "\x5b\x22\xef\xbf\xbf\x22\x5d",
682
        "\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d",
683
        "\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d",
684
        "\x5b\x22\xcf\x80\x22\x5d",
685
        "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d",
686
        "\x5b\x22\x61\x73\x64\x20\x22\x5d",
687
        "\x22\x20\x22",
688
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d"
689
        "",
690
        "\x5b\x22\x5c\x75\x30\x38\x32\x31\x22\x5d",
691
        "\x5b\x22\x5c\x75\x30\x31\x32\x33\x22\x5d",
692
        "\x5b\x22\xe2\x80\xa8\x22\x5d",
693
        "\x5b\x22\xe2\x80\xa9\x22\x5d",
694
        "\x5b\x22\x5c\x75\x30\x30\x36\x31\x5c\x75\x33\x30\x61\x66\x5c\x75"
695
        "\x33\x30\x45\x41\x5c\x75\x33\x30\x62\x39\x22\x5d",
696
        "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x30\x41\x6c\x69\x6e\x65\x22"
697
        "\x5d",
698
        "\x5b\x22\x7f\x22\x5d",
699
        "\x5b\x22\x5c\x75\x41\x36\x36\x44\x22\x5d",
700
        "\x5b\x22\x5c\x75\x30\x30\x35\x43\x22\x5d",
701
        "\x5b\x22\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82\x22\x5d",
702
        "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
703
        "",
704
        "\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
705
        "",
706
        "\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d",
707
        "\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d",
708
        "\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d",
709
        "\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d",
710
        "\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d",
711
        "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d",
712
        "\x5b\x22\x61\x7f\x61\x22\x5d",
713
        "\x66\x61\x6c\x73\x65",
714
        "\x34\x32",
715
        "\x2d\x30\x2e\x31",
716
        "\x6e\x75\x6c\x6c",
717
        "\x22\x61\x73\x64\x22",
718
        "\x74\x72\x75\x65",
719
        "\x22\x22",
720
        "\x5b\x22\x61\x22\x5d\x0a",
721
        "\x5b\x74\x72\x75\x65\x5d",
722
        "\x20\x5b\x5d\x20",
723
        NULL
724
};
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
        // SKIP: NUL in n_multidigit_number_then_00.json
757
        "\x5b\x2b\x2b\x31\x32\x33\x34\x5d",
758
        "\x5b\x2b\x31\x5d",
759
        "\x5b\x2b\x49\x6e\x66\x5d",
760
        "\x5b\x2d\x30\x31\x5d",
761
        "\x5b\x2d\x31\x2e\x30\x2e\x5d",
762
        "\x5b\x2d\x32\x2e\x5d",
763
        "\x5b\x2d\x4e\x61\x4e\x5d",
764
        "\x5b\x2e\x2d\x31\x5d",
765
        "\x5b\x2e\x32\x65\x2d\x33\x5d",
766
        "\x5b\x30\x2e\x31\x2e\x32\x5d",
767
        "\x5b\x30\x2e\x33\x65\x2b\x5d",
768
        "\x5b\x30\x2e\x33\x65\x5d",
769
        "\x5b\x30\x2e\x65\x31\x5d",
770
        "\x5b\x30\x45\x2b\x5d",
771
        "\x5b\x30\x45\x5d",
772
        "\x5b\x30\x65\x2b\x5d",
773
        "\x5b\x30\x65\x5d",
774
        "\x5b\x31\x2e\x30\x65\x2b\x5d",
775
        "\x5b\x31\x2e\x30\x65\x2d\x5d",
776
        "\x5b\x31\x2e\x30\x65\x5d",
777
        "\x5b\x31\x20\x30\x30\x30\x2e\x30\x5d",
778
        "\x5b\x31\x65\x45\x32\x5d",
779
        "\x5b\x32\x2e\x65\x2b\x33\x5d",
780
        "\x5b\x32\x2e\x65\x2d\x33\x5d",
781
        "\x5b\x32\x2e\x65\x33\x5d",
782
        "\x5b\x39\x2e\x65\x2b\x5d",
783
        "\x5b\x49\x6e\x66\x5d",
784
        "\x5b\x4e\x61\x4e\x5d",
785
        "\x5b\xef\xbc\x91\x5d",
786
        "\x5b\x31\x2b\x32\x5d",
787
        "\x5b\x30\x78\x31\x5d",
788
        "\x5b\x30\x78\x34\x32\x5d",
789
        "\x5b\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
790
        "\x5b\x30\x65\x2b\x2d\x31\x5d",
791
        "\x5b\x2d\x31\x32\x33\x2e\x31\x32\x33\x66\x6f\x6f\x5d",
792
        "\x5b\x31\x32\x33\xe5\x5d",
793
        "\x5b\x31\x65\x31\xe5\x5d",
794
        "\x5b\x30\xe5\x5d\x0a",
795
        "\x5b\x2d\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
796
        "\x5b\x2d\x66\x6f\x6f\x5d",
797
        "\x5b\x2d\x20\x31\x5d",
798
        "\x5b\x2d\x30\x31\x32\x5d",
799
        "\x5b\x2d\x2e\x31\x32\x33\x5d",
800
        "\x5b\x2d\x31\x78\x5d",
801
        "\x5b\x31\x65\x61\x5d",
802
        "\x5b\x31\x65\xe5\x5d",
803
        "\x5b\x31\x2e\x5d",
804
        "\x5b\x2e\x31\x32\x33\x5d",
805
        "\x5b\x31\x2e\x32\x61\x2d\x33\x5d",
806
        "\x5b\x31\x2e\x38\x30\x31\x31\x36\x37\x30\x30\x33\x33\x33\x37\x36"
807
        "\x35\x31\x34\x48\x2d\x33\x30\x38\x5d",
808
        "\x5b\x30\x31\x32\x5d",
809
        "\x5b\x22\x78\x22\x2c\x20\x74\x72\x75\x74\x68\x5d",
810
        "\x7b\x5b\x3a\x20\x22\x78\x22\x7d\x0a",
811
        "\x7b\x22\x78\x22\x2c\x20\x6e\x75\x6c\x6c\x7d",
812
        "\x7b\x22\x78\x22\x3a\x3a\x22\x62\x22\x7d",
813
        "\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d",
814
        "\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d",
815
        "\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d",
816
        "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d",
817
        "\x7b\x22\x61\x22\x20\x62\x7d",
818
        "\x7b\x3a\x22\x62\x22\x7d",
819
        "\x7b\x22\x61\x22\x20\x22\x62\x22\x7d",
820
        "\x7b\x22\x61\x22\x3a",
821
        "\x7b\x22\x61\x22",
822
        "\x7b\x31\x3a\x31\x7d",
823
        "\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d",
824
        "\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a"
825
        "\x6e\x75\x6c\x6c\x7d",
826
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d",
827
        "\x7b\x27\x61\x27\x3a\x30\x7d",
828
        "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x7d",
829
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f",
830
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f\x2f",
831
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2f",
832
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f",
833
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x2c\x22\x63\x22\x3a\x22\x64"
834
        "\x22\x7d",
835
        "\x7b\x61\x3a\x20\x22\x62\x22\x7d",
836
        "\x7b\x22\x61\x22\x3a\x22\x61",
837
        "\x7b\x20\x22\x66\x6f\x6f\x22\x20\x3a\x20\x22\x62\x61\x72\x22\x2c"
838
        "\x20\x22\x61\x22\x20\x7d",
839
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23",
840
        "\x20",
841
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x22\x5d",
842
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x22\x5d",
843
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d",
844
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d",
845
        "\x5b\xc3\xa9\x5d",
846
        // SKIP: NUL in n_string_backslash_00.json
847
        "\x5b\x22\x5c\x78\x30\x30\x22\x5d",
848
        "\x5b\x22\x5c\x5c\x5c\x22\x5d",
849
        "\x5b\x22\x5c\x09\x22\x5d",
850
        "\x5b\x22\x5c\xf0\x9f\x8c\x80\x22\x5d",
851
        "\x5b\x22\x5c\x22\x5d",
852
        "\x5b\x22\x5c\x75\x30\x30\x41\x22\x5d",
853
        "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x22\x5d",
854
        "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x44\x38\x30\x30\x5c\x78"
855
        "\x22\x5d",
856
        "\x5b\x22\x5c\x75\xe5\x22\x5d",
857
        "\x5b\x22\x5c\x61\x22\x5d",
858
        "\x5b\x22\x5c\x75\x71\x71\x71\x71\x22\x5d",
859
        "\x5b\x22\x5c\xe5\x22\x5d",
860
        "\x5b\x5c\x75\x30\x30\x32\x30\x22\x61\x73\x64\x22\x5d",
861
        "\x5b\x5c\x6e\x5d",
862
        "\x22",
863
        "\x5b\x27\x73\x69\x6e\x67\x6c\x65\x20\x71\x75\x6f\x74\x65\x27\x5d"
864
        "",
865
        "\x61\x62\x63",
866
        "\x5b\x22\x5c",
867
        // SKIP: NUL in n_string_unescaped_ctrl_char.json
868
        "\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d",
869
        "\x5b\x22\x09\x22\x5d",
870
        "\x22\x5c\x55\x41\x36\x36\x44\x22",
871
        "\x22\x22\x78",
872
        // SKIP: LONG  n_structure_100000_opening_arrays.json
873
        "\x5b\xe2\x81\xa0\x5d",
874
        "\xef\xbb\xbf",
875
        "\x3c\x2e\x3e",
876
        "\x5b\x3c\x6e\x75\x6c\x6c\x3e\x5d",
877
        "\x5b\x31\x5d\x78",
878
        "\x5b\x31\x5d\x5d",
879
        "\x5b\x22\x61\x73\x64\x5d",
880
        "\x61\xc3\xa5",
881
        "\x5b\x54\x72\x75\x65\x5d",
882
        "\x31\x5d",
883
        "\x7b\x22\x78\x22\x3a\x20\x74\x72\x75\x65\x2c",
884
        "\x5b\x5d\x5b\x5d",
885
        "\x5d",
886
        "\xef\xbb\x7b\x7d",
887
        "\xe5",
888
        "\x5b",
889
        "",
890
        // SKIP: NUL in n_structure_null-byte-outside-string.json
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
        // SKIP: LONG  n_structure_open_array_object.json
900
        "\x5b\x7b",
901
        "\x5b\x22\x61",
902
        "\x5b\x22\x61\x22",
903
        "\x7b",
904
        "\x7b\x5d",
905
        "\x7b\x2c",
906
        "\x7b\x5b",
907
        "\x7b\x22\x61",
908
        "\x7b\x27\x61\x27",
909
        "\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b"
910
        "",
911
        "\xe9",
912
        "\x2a",
913
        "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23\x7b\x7d",
914
        "\x5b\x5c\x75\x30\x30\x30\x41\x22\x22\x5d",
915
        "\x5b\x31",
916
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x6e\x75\x6c",
917
        "\x5b\x20\x74\x72\x75\x65\x2c\x20\x66\x61\x6c\x73",
918
        "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x74\x72\x75",
919
        "\x7b\x22\x61\x73\x64\x22\x3a\x22\x61\x73\x64\x22",
920
        "\xc3\xa5",
921
        "\x5b\xe2\x81\xa0\x5d",
922
        "\x5b\x0c\x5d",
923
        NULL
924
};
925
926
static void
927 1995
test_good(const char *j)
928
{
929
        struct vjsn *js;
930
        const char *err;
931
932 1995
        js = vjsn_parse(j, &err);
933 1995
        if (js == NULL || err != NULL) {
934 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
935 0
                exit(1);
936
        }
937 1995
        printf("GOOD: %s\n", j);
938 1995
        vjsn_dump(js, stdout);
939 1995
        vjsn_delete(&js);
940 1995
}
941
942
static void
943 3843
test_bad(const char *j)
944
{
945
        struct vjsn *js;
946
        const char *err;
947
948 3843
        js = vjsn_parse(j, &err);
949 3843
        if (js != NULL || err == NULL) {
950 0
                fprintf(stderr, "Parse succeeded %s\n", j);
951 0
                exit(1);
952
        }
953 3843
        printf("BAD: %s %s\n", err, j);
954 3843
}
955
956
int
957 21
main(int argc, char **argv)
958
{
959
        const char **s;
960
961 21
        (void)argc;
962 21
        (void)argv;
963 2016
        for (s = good; *s != NULL; s++)
964 1995
                test_good(*s);
965 3843
        for (s = bad; *s != NULL; s++)
966 3822
                test_bad(*s);
967
968
        /*
969
         * This is part of Nicolas i(ndeterminate) test set, for reasons I
970
         * do not fully grasp, but we want it to test bad.
971
         */
972 21
        test_bad("\"\\uDFAA\"");
973 21
        printf("Tests done\n");
974 21
        return (0);
975
}
976
977
#endif