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 878653
vjsn_val_new(const char *type)
65
{
66
        struct vjsn_val *jsv;
67
68 878653
        ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
69 878653
        AN(jsv);
70 878653
        VTAILQ_INIT(&jsv->children);
71 878653
        jsv->type = type;
72 878653
        return (jsv);
73
}
74
75
static void
76 393467
vjsn_val_delete(struct vjsn_val *jsv)
77
{
78
        struct vjsn_val *jsve;
79
80 393467
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
81 393467
        do {
82 784653
                jsve = VTAILQ_FIRST(&jsv->children);
83 784653
                if (jsve != NULL) {
84 391186
                        VTAILQ_REMOVE(&jsv->children, jsve, list);
85 391186
                        vjsn_val_delete(jsve);
86 391186
                }
87 784653
        } while (jsve != NULL);
88 393467
        FREE_OBJ(jsv);
89 393467
}
90
91
void
92 2240
vjsn_delete(struct vjsn **jp)
93
{
94
        struct vjsn *js;
95
96 2240
        TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
97 2240
        if (js->value != NULL)
98 2227
                vjsn_val_delete(js->value);
99 2240
        free(js->raw);
100 2240
        FREE_OBJ(js);
101 2240
}
102
103
static void
104 3389837
vjsn_skip_ws(struct vjsn *js)
105
{
106
        char c;
107
108 3389837
        while (1) {
109 7325195
                c = js->ptr[0];
110 7325195
                if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
111 3935358
                        *js->ptr++ = '\0';
112 3935358
                        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 3389837
                return;
124
        }
125
}
126
127
static unsigned
128 69
vjsn_unumber(struct vjsn *js)
129
{
130 69
        unsigned u = 0;
131
        char c;
132
        int i;
133
134 69
        VJSN_EXPECT(js, '\\', 0);
135 69
        VJSN_EXPECT(js, 'u', 0);
136 319
        for (i = 0; i < 4; i++) {
137 258
                u <<= 4;
138 258
                c = *js->ptr;
139 258
                if (c >= '0' && c <= '9')
140 164
                        u |= c - '0';                   /*lint !e737 */
141 94
                else if (c >= 'A' && c <= 'F')
142 59
                        u |= c - '7';                   /*lint !e737 */
143 35
                else if (c >= 'a' && c <= 'f')
144 28
                        u |= c - 'W';                   /*lint !e737 */
145
                else {
146 7
                        js->err = "Illegal \\uXXXX sequence";
147 7
                        return (0);
148
                }
149 251
                js->ptr++;
150 251
        }
151 61
        return (u);
152 69
}
153
154
static void
155 56
vjsn_unicode(struct vjsn *js, char **d)
156
{
157
        unsigned u1, u2;
158
159 56
        u1 = vjsn_unumber(js);
160 56
        if (js->err)
161 3
                return;
162
163 53
        if (u1 >= 0xdc00 && u1 <= 0xdfff) {
164 1
                js->err = "Lone second UTF-16 Surrogate";
165 1
                return;
166
        }
167 52
        if (u1 >= 0xd800 && u1 <= 0xdc00) {
168 13
                u2 = vjsn_unumber(js);
169 13
                if (u2 < 0xdc00 || u2 > 0xdfff) {
170 6
                        js->err = "Bad UTF-16 Surrogate pair";
171 6
                        return;
172
                }
173 7
                u1 -= 0xd800;
174 7
                u2 -= 0xdc00;
175 7
                u1 <<= 10;
176 7
                u1 |= u2;
177 7
                u1 |= 0x10000;
178 7
        }
179 46
        assert(u1 < 0x110000);
180
        /*lint -save -e734 -e713 */
181 46
        if (u1 < 0x80)
182 9
                *(*d)++ = u1;
183 37
        else if (u1 < 0x800) {
184 19
                *(*d)++ = 0xc0 + u1 / 64;
185 19
                *(*d)++ = 0x80 + u1 % 64;
186 37
        } else if (u1 < 0x10000) {
187 11
                *(*d)++ = 0xe0 + u1 / 4096;
188 11
                *(*d)++ = 0x80 + u1 / 64 % 64;
189 11
                *(*d)++ = 0x80 + u1 % 64;
190 11
        } else {
191 7
                *(*d)++ = 0xf0 + u1 / 262144;
192 7
                *(*d)++ = 0x80 + u1 / 4096 % 64;
193 7
                *(*d)++ = 0x80 + u1 / 64 % 64;
194 7
                *(*d)++ = 0x80 + u1 % 64;
195
        }
196
        /*lint -restore */
197 56
}
198
199
static char *
200 1054797
vjsn_string(struct vjsn *js, char **e)
201
{
202
        char *p, *b;
203
204 1054797
        AN(e);
205 1054797
        vjsn_skip_ws(js);
206 1054797
        VJSN_EXPECT(js, '"', NULL);
207 1054777
        b = p = js->ptr;
208 14779536
        while (*js->ptr != '"') {
209 13724787
                if (*js->ptr == '\0') {
210 7
                        js->err = "Unterminated string";
211 7
                        return (NULL);
212
                }
213 13724780
                if ((unsigned char)(*js->ptr) <= 0x1f) {
214 3
                        js->err = "Unescaped control char in string";
215 3
                        return (NULL);
216
                }
217 13724777
                if (*js->ptr != '\\') {
218 13496558
                        *p++ = *js->ptr++;
219 13496558
                        continue;
220
                }
221 228219
                switch (js->ptr[1]) {
222
                case '\\':
223
                case '/':
224 2861
                case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
225 1
                case 'b': *p++ = 0x08; js->ptr += 2; break;
226 1
                case 'f': *p++ = 0x0c; js->ptr += 2; break;
227 202074
                case 't': *p++ = 0x09; js->ptr += 2; break;
228 23217
                case 'n': *p++ = 0x0a; js->ptr += 2; break;
229 1
                case 'r': *p++ = 0x0d; js->ptr += 2; break;
230
                case 'u':
231 56
                        vjsn_unicode(js, &p);
232 56
                        if (js->err != NULL)
233 10
                                return (NULL);
234 46
                        break;
235
                default:
236 8
                        js->err = "Bad string escape";
237 8
                        return (NULL);
238
                }
239
        }
240 1054749
        VJSN_EXPECT(js, '"', NULL);
241 1054749
        *p = '\0';
242 1054749
        *e = p;
243 1054749
        return (b);
244 1054797
}
245
246
static struct vjsn_val *
247 47439
vjsn_object(struct vjsn *js)
248
{
249
        struct vjsn_val *jsv, *jsve;
250
        char *s, *e;
251
252 47439
        VJSN_EXPECT(js, '{', NULL);
253
254 47439
        jsv = vjsn_val_new(VJSN_OBJECT);
255 47439
        AN(jsv);
256
257 47439
        vjsn_skip_ws(js);
258 47439
        if (*js->ptr != '}') {
259 413169
                while (1) {
260 413169
                        s = vjsn_string(js, &e);
261 413169
                        if (js->err != NULL)
262 21
                                return (jsv);
263 413148
                        vjsn_skip_ws(js);
264 413148
                        VJSN_EXPECT(js, ':', jsv);
265 413143
                        jsve = vjsn_value(js);
266 413143
                        if (js->err != NULL) {
267 5
                                if (jsve != NULL)
268 1
                                        vjsn_val_delete(jsve);
269 5
                                return (jsv);
270
                        }
271 413138
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
272 413138
                        jsve->name = s;
273 413138
                        jsve->name_e = e;
274 413138
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
275 413138
                        vjsn_skip_ws(js);
276 413138
                        if (*js->ptr == '}')
277 47399
                                break;
278 365739
                        VJSN_EXPECT(js, ',', jsv);
279
                }
280 47399
        }
281 47406
        VJSN_EXPECT(js, '}', jsv);
282 47406
        return (jsv);
283 47439
}
284
285
static struct vjsn_val *
286 117295
vjsn_array(struct vjsn *js)
287
{
288
        struct vjsn_val *jsv, *jsve;
289
290 117295
        VJSN_EXPECT(js, '[', NULL);
291
292 117295
        jsv = vjsn_val_new(VJSN_ARRAY);
293 117295
        AN(jsv);
294
295 117295
        vjsn_skip_ws(js);
296 117295
        if (*js->ptr != ']') {
297 462649
                while (1) {
298 462649
                        jsve = vjsn_value(js);
299 462649
                        if (js->err != NULL) {
300 97
                                if (jsve != NULL)
301 53
                                        vjsn_val_delete(jsve);
302 97
                                return (jsv);
303
                        }
304 462552
                        CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
305 462552
                        VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
306 462552
                        vjsn_skip_ws(js);
307 462552
                        if (*js->ptr == ']')
308 117097
                                break;
309 345455
                        VJSN_EXPECT(js, ',', jsv);
310
                }
311 117097
        }
312 117175
        VJSN_EXPECT(js, ']', jsv);
313 117175
        return (jsv);
314 117295
}
315
316
static struct vjsn_val *
317 45869
vjsn_number(struct vjsn *js)
318
{
319
        struct vjsn_val *jsv;
320
321 45869
        jsv = vjsn_val_new(VJSN_NUMBER);
322 45869
        AN(jsv);
323
324 45869
        jsv->value = js->ptr;
325
326 45869
        if (*js->ptr == '-')
327 33
                js->ptr++;
328 45869
        if (*js->ptr < '0' || *js->ptr > '9') {
329 6
                js->err = "Bad number";
330 6
                return (jsv);
331
        }
332 45863
        if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
333 3
                js->err = "Bad number";
334 3
                return (jsv);
335
        }
336 176122
        while (*js->ptr >= '0' && *js->ptr <= '9')
337 130262
                js->ptr++;
338 45860
        if (*js->ptr == '.') {
339 179
                js->ptr++;
340 179
                if (*js->ptr < '0' || *js->ptr > '9') {
341 7
                        js->err = "Bad number";
342 7
                        return (jsv);
343
                }
344 860
                while (*js->ptr >= '0' && *js->ptr <= '9')
345 688
                        js->ptr++;
346 172
        }
347 45853
        if (*js->ptr == 'e' || *js->ptr == 'E') {
348 27
                js->ptr++;
349 27
                if (*js->ptr == '-' || *js->ptr == '+')
350 13
                        js->ptr++;
351 27
                if (*js->ptr < '0' || *js->ptr > '9') {
352 13
                        js->err = "Bad number";
353 13
                        return (jsv);
354
                }
355 34
                while (*js->ptr >= '0' && *js->ptr <= '9')
356 20
                        js->ptr++;
357 14
        }
358
        /*
359
         * The terminating NUL is supplied by the caller, once they
360
         * have decided if they like what occupies that spot.
361
         */
362 45840
        return (jsv);
363 45869
}
364
365
static struct vjsn_val *
366 878714
vjsn_value(struct vjsn *js)
367
{
368
        struct vjsn_val *jsv;
369
370 878714
        AZ(js->err);
371 878714
        vjsn_skip_ws(js);
372 878714
        if (*js->ptr == '{')
373 47439
                return (vjsn_object(js));
374 831275
        if (*js->ptr== '[')
375 117295
                return (vjsn_array(js));
376 713980
        if (*js->ptr== '"') {
377 641628
                jsv = vjsn_val_new(VJSN_STRING);
378 641628
                jsv->value = vjsn_string(js, &jsv->value_e);
379 641628
                if (js->err != NULL)
380 27
                        return (jsv);
381 641601
                AN(jsv->value);
382 641601
                return (jsv);
383
        }
384 72352
        if (!strncmp(js->ptr, "true", 4)) {
385 7884
                js->ptr += 4;
386 7884
                return (vjsn_val_new(VJSN_TRUE));
387
        }
388 64468
        if (!strncmp(js->ptr, "false", 5)) {
389 2064
                js->ptr += 5;
390 2064
                return (vjsn_val_new(VJSN_FALSE));
391
        }
392 62404
        if (!strncmp(js->ptr, "null", 4)) {
393 16474
                js->ptr += 4;
394 16474
                return (vjsn_val_new(VJSN_NULL));
395
        }
396 45930
        if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 45869
                return (vjsn_number(js));
398 61
        js->err = "Unrecognized value";
399 61
        return (NULL);
400 878714
}
401
402
struct vjsn *
403 2922
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 2922
        AN(from);
410
411 2922
        AN(err);
412 2922
        *err = NULL;
413
414 2922
        if (to == NULL)
415 2922
                to = strchr(from, '\0');
416 2922
        AN(to);
417
418 2922
        sz = to - from;
419
420 2922
        p = malloc(sz + 1L);
421 2922
        AN(p);
422 2922
        memcpy(p, from, sz);
423 2922
        p[sz] = '\0';
424 2922
        e = p + sz;
425
426 2922
        ALLOC_OBJ(js, VJSN_MAGIC);
427 2922
        AN(js);
428 2922
        js->raw = p;
429 2922
        js->ptr = p;
430
431 2922
        js->value = vjsn_value(js);
432 2922
        if (js->err != NULL) {
433 168
                *err = js->err;
434 168
                vjsn_delete(&js);
435 168
                return (NULL);
436
        }
437
438 2754
        vjsn_skip_ws(js);
439 2754
        if (js->ptr != e) {
440 16
                *err = "Garbage after value";
441 16
                vjsn_delete(&js);
442 16
                return (NULL);
443
        }
444 2738
        return (js);
445 2922
}
446
447
struct vjsn *
448 2922
vjsn_parse(const char *src, const char **err)
449
{
450
451 2922
        return (vjsn_parse_end(src, NULL, err));
452
}
453
454
struct vjsn_val *
455 419529
vjsn_child(const struct vjsn_val *vv, const char *key)
456
{
457
        struct vjsn_val *vc;
458
459 419529
        CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 419529
        AN(key);
461 1978668
        VTAILQ_FOREACH(vc, &vv->children, list) {
462 1977453
                if (vc->name != NULL && !strcmp(vc->name, key))
463 418314
                        return (vc);
464 1559139
        }
465 1215
        return (NULL);
466 419529
}
467
468
static void
469 193
vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470
{
471
        struct vjsn_val *jsve;
472
473 193
        CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 193
        printf("%*s", indent, "");
475 193
        if (jsv->name != NULL)
476 17
                printf("[\"%s\"]: ", jsv->name);
477 193
        printf("{%s}", jsv->type);
478 193
        if (jsv->value != NULL) {
479 91
                if (strlen(jsv->value) < 20)
480 87
                        printf(" <%s", jsv->value);
481
                else
482 4
                        printf(" <%.10s[...#%zu]",
483 4
                            jsv->value, strlen(jsv->value + 10));
484 91
                printf(">");
485 91
        }
486 193
        printf("\n");
487 291
        VTAILQ_FOREACH(jsve, &jsv->children, list)
488 98
                vjsn_dump_i(jsve, fo, indent + 2);
489 193
}
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 95
vjsn_dump(const struct vjsn *js, FILE *fo)
500
{
501
502 95
        CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 95
        AN(fo);
504 95
        vjsn_dump_i(js->value, fo, 0);
505 95
}
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 810119
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 95
test_good(const char *j)
927
{
928
        struct vjsn *js;
929
        const char *err;
930
931 95
        js = vjsn_parse(j, &err);
932 95
        if (js == NULL || err != NULL) {
933 0
                fprintf(stderr, "Parse error: %s\n%s\n", err, j);
934 0
                exit(1);
935
        }
936 95
        printf("GOOD: %s\n", j);
937 95
        vjsn_dump(js, stdout);
938 95
        vjsn_delete(&js);
939 95
}
940
941
static void
942 183
test_bad(const char *j)
943
{
944
        struct vjsn *js;
945
        const char *err;
946
947 183
        js = vjsn_parse(j, &err);
948 183
        if (js != NULL || err == NULL) {
949 0
                fprintf(stderr, "Parse succeeded %s\n", j);
950 0
                exit(1);
951
        }
952 183
        printf("BAD: %s %s\n", err, j);
953 183
}
954
955
int
956 1
main(int argc, char **argv)
957
{
958
        const char **s;
959
960 1
        (void)argc;
961 1
        (void)argv;
962 96
        for (s = good; *s != NULL; s++)
963 95
                test_good(*s);
964 183
        for (s = bad; *s != NULL; s++)
965 182
                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 1
        test_bad("\"\\uDFAA\"");
972 1
        printf("Tests done\n");
973 1
        return (0);
974
}
975
976
#endif