1/*
2 * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
3 * Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
4 *
5 * Jansson is free software; you can redistribute it and/or modify
6 * it under the terms of the MIT license. See LICENSE for details.
7 */
8
9#include <string.h>
10#include "jansson.h"
11#include "jansson_private.h"
12#include "utf.h"
13
14typedef struct {
15    int line;
16    int column;
17    size_t pos;
18    char token;
19} token_t;
20
21typedef struct {
22    const char *start;
23    const char *fmt;
24    token_t prev_token;
25    token_t token;
26    token_t next_token;
27    json_error_t *error;
28    size_t flags;
29    int line;
30    int column;
31    size_t pos;
32} scanner_t;
33
34#define token(scanner) ((scanner)->token.token)
35
36static const char * const type_names[] = {
37    "object",
38    "array",
39    "string",
40    "integer",
41    "real",
42    "true",
43    "false",
44    "null"
45};
46
47#define type_name(x) type_names[json_typeof(x)]
48
49static const char unpack_value_starters[] = "{[siIbfFOon";
50
51
52static void scanner_init(scanner_t *s, json_error_t *error,
53                         size_t flags, const char *fmt)
54{
55    s->error = error;
56    s->flags = flags;
57    s->fmt = s->start = fmt;
58    memset(&s->prev_token, 0, sizeof(token_t));
59    memset(&s->token, 0, sizeof(token_t));
60    memset(&s->next_token, 0, sizeof(token_t));
61    s->line = 1;
62    s->column = 0;
63    s->pos = 0;
64}
65
66static void next_token(scanner_t *s)
67{
68    const char *t;
69    s->prev_token = s->token;
70
71    if(s->next_token.line) {
72        s->token = s->next_token;
73        s->next_token.line = 0;
74        return;
75    }
76
77    t = s->fmt;
78    s->column++;
79    s->pos++;
80
81    /* skip space and ignored chars */
82    while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
83        if(*t == '\n') {
84            s->line++;
85            s->column = 1;
86        }
87        else
88            s->column++;
89
90        s->pos++;
91        t++;
92    }
93
94    s->token.token = *t;
95    s->token.line = s->line;
96    s->token.column = s->column;
97    s->token.pos = s->pos;
98
99    t++;
100    s->fmt = t;
101}
102
103static void prev_token(scanner_t *s)
104{
105    s->next_token = s->token;
106    s->token = s->prev_token;
107}
108
109static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
110{
111    va_list ap;
112    va_start(ap, fmt);
113
114    jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
115                     fmt, ap);
116
117    jsonp_error_set_source(s->error, source);
118
119    va_end(ap);
120}
121
122static json_t *pack(scanner_t *s, va_list *ap);
123
124
125/* ours will be set to 1 if jsonp_free() must be called for the result
126   afterwards */
127static char *read_string(scanner_t *s, va_list *ap,
128                         const char *purpose, size_t *out_len, int *ours)
129{
130    char t;
131    strbuffer_t strbuff;
132    const char *str;
133    size_t length;
134
135    next_token(s);
136    t = token(s);
137    prev_token(s);
138
139    if(t != '#' && t != '%' && t != '+') {
140        /* Optimize the simple case */
141        str = va_arg(*ap, const char *);
142
143        if(!str) {
144            set_error(s, "<args>", "NULL string argument");
145            return NULL;
146        }
147
148        length = strlen(str);
149
150        if(!utf8_check_string(str, length)) {
151            set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
152            return NULL;
153        }
154
155        *out_len = length;
156        *ours = 0;
157        return (char *)str;
158    }
159
160    strbuffer_init(&strbuff);
161
162    while(1) {
163        str = va_arg(*ap, const char *);
164        if(!str) {
165            set_error(s, "<args>", "NULL string argument");
166            strbuffer_close(&strbuff);
167            return NULL;
168        }
169
170        next_token(s);
171
172        if(token(s) == '#') {
173            length = va_arg(*ap, int);
174        }
175        else if(token(s) == '%') {
176            length = va_arg(*ap, size_t);
177        }
178        else {
179            prev_token(s);
180            length = strlen(str);
181        }
182
183        if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
184            set_error(s, "<internal>", "Out of memory");
185            strbuffer_close(&strbuff);
186            return NULL;
187        }
188
189        next_token(s);
190        if(token(s) != '+') {
191            prev_token(s);
192            break;
193        }
194    }
195
196    if(!utf8_check_string(strbuff.value, strbuff.length)) {
197        set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
198        strbuffer_close(&strbuff);
199        return NULL;
200    }
201
202    *out_len = strbuff.length;
203    *ours = 1;
204    return strbuffer_steal_value(&strbuff);
205}
206
207static json_t *pack_object(scanner_t *s, va_list *ap)
208{
209    json_t *object = json_object();
210    next_token(s);
211
212    while(token(s) != '}') {
213        char *key;
214        size_t len;
215        int ours;
216        json_t *value;
217
218        if(!token(s)) {
219            set_error(s, "<format>", "Unexpected end of format string");
220            goto error;
221        }
222
223        if(token(s) != 's') {
224            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
225            goto error;
226        }
227
228        key = read_string(s, ap, "object key", &len, &ours);
229        if(!key)
230            goto error;
231
232        next_token(s);
233
234        value = pack(s, ap);
235        if(!value) {
236            if(ours)
237                jsonp_free(key);
238
239            goto error;
240        }
241
242        if(json_object_set_new_nocheck(object, key, value)) {
243            if(ours)
244                jsonp_free(key);
245
246            set_error(s, "<internal>", "Unable to add key \"%s\"", key);
247            goto error;
248        }
249
250        if(ours)
251            jsonp_free(key);
252
253        next_token(s);
254    }
255
256    return object;
257
258error:
259    json_decref(object);
260    return NULL;
261}
262
263static json_t *pack_array(scanner_t *s, va_list *ap)
264{
265    json_t *array = json_array();
266    next_token(s);
267
268    while(token(s) != ']') {
269        json_t *value;
270
271        if(!token(s)) {
272            set_error(s, "<format>", "Unexpected end of format string");
273            goto error;
274        }
275
276        value = pack(s, ap);
277        if(!value)
278            goto error;
279
280        if(json_array_append_new(array, value)) {
281            set_error(s, "<internal>", "Unable to append to array");
282            goto error;
283        }
284
285        next_token(s);
286    }
287    return array;
288
289error:
290    json_decref(array);
291    return NULL;
292}
293
294static json_t *pack(scanner_t *s, va_list *ap)
295{
296    switch(token(s)) {
297        case '{':
298            return pack_object(s, ap);
299
300        case '[':
301            return pack_array(s, ap);
302
303        case 's': /* string */
304        {
305            char *str;
306            size_t len;
307            int ours;
308
309            str = read_string(s, ap, "string", &len, &ours);
310            if(!str)
311                return NULL;
312
313            if (ours)
314                return jsonp_stringn_nocheck_own(str, len);
315            else
316                return json_stringn_nocheck(str, len);
317        }
318
319        case 'n': /* null */
320            return json_null();
321
322        case 'b': /* boolean */
323            return va_arg(*ap, int) ? json_true() : json_false();
324
325        case 'i': /* integer from int */
326            return json_integer(va_arg(*ap, int));
327
328        case 'I': /* integer from json_int_t */
329            return json_integer(va_arg(*ap, json_int_t));
330
331        case 'f': /* real */
332            return json_real(va_arg(*ap, double));
333
334        case 'O': /* a json_t object; increments refcount */
335            return json_incref(va_arg(*ap, json_t *));
336
337        case 'o': /* a json_t object; doesn't increment refcount */
338            return va_arg(*ap, json_t *);
339
340        default:
341            set_error(s, "<format>", "Unexpected format character '%c'",
342                      token(s));
343            return NULL;
344    }
345}
346
347static int unpack(scanner_t *s, json_t *root, va_list *ap);
348
349static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
350{
351    int ret = -1;
352    int strict = 0;
353    int gotopt = 0;
354
355    /* Use a set (emulated by a hashtable) to check that all object
356       keys are accessed. Checking that the correct number of keys
357       were accessed is not enough, as the same key can be unpacked
358       multiple times.
359    */
360    hashtable_t key_set;
361
362    if(hashtable_init(&key_set)) {
363        set_error(s, "<internal>", "Out of memory");
364        return -1;
365    }
366
367    if(root && !json_is_object(root)) {
368        set_error(s, "<validation>", "Expected object, got %s",
369                  type_name(root));
370        goto out;
371    }
372    next_token(s);
373
374    while(token(s) != '}') {
375        const char *key;
376        json_t *value;
377        int opt = 0;
378
379        if(strict != 0) {
380            set_error(s, "<format>", "Expected '}' after '%c', got '%c'",
381                      (strict == 1 ? '!' : '*'), token(s));
382            goto out;
383        }
384
385        if(!token(s)) {
386            set_error(s, "<format>", "Unexpected end of format string");
387            goto out;
388        }
389
390        if(token(s) == '!' || token(s) == '*') {
391            strict = (token(s) == '!' ? 1 : -1);
392            next_token(s);
393            continue;
394        }
395
396        if(token(s) != 's') {
397            set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
398            goto out;
399        }
400
401        key = va_arg(*ap, const char *);
402        if(!key) {
403            set_error(s, "<args>", "NULL object key");
404            goto out;
405        }
406
407        next_token(s);
408
409        if(token(s) == '?') {
410            opt = gotopt = 1;
411            next_token(s);
412        }
413
414        if(!root) {
415            /* skipping */
416            value = NULL;
417        }
418        else {
419            value = json_object_get(root, key);
420            if(!value && !opt) {
421                set_error(s, "<validation>", "Object item not found: %s", key);
422                goto out;
423            }
424        }
425
426        if(unpack(s, value, ap))
427            goto out;
428
429        hashtable_set(&key_set, key, 0, json_null());
430        next_token(s);
431    }
432
433    if(strict == 0 && (s->flags & JSON_STRICT))
434        strict = 1;
435
436    if(root && strict == 1) {
437        /* We need to check that all non optional items have been parsed */
438        const char *key;
439        json_t *value;
440        long unpacked = 0;
441        if (gotopt) {
442            /* We have optional keys, we need to iter on each key */
443            json_object_foreach(root, key, value) {
444                if(!hashtable_get(&key_set, key)) {
445                    unpacked++;
446                }
447            }
448        } else {
449            /* No optional keys, we can just compare the number of items */
450            unpacked = (long)json_object_size(root) - (long)key_set.size;
451        }
452        if (unpacked) {
453            set_error(s, "<validation>", "%li object item(s) left unpacked", unpacked);
454            goto out;
455        }
456    }
457
458    ret = 0;
459
460out:
461    hashtable_close(&key_set);
462    return ret;
463}
464
465static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
466{
467    size_t i = 0;
468    int strict = 0;
469
470    if(root && !json_is_array(root)) {
471        set_error(s, "<validation>", "Expected array, got %s", type_name(root));
472        return -1;
473    }
474    next_token(s);
475
476    while(token(s) != ']') {
477        json_t *value;
478
479        if(strict != 0) {
480            set_error(s, "<format>", "Expected ']' after '%c', got '%c'",
481                      (strict == 1 ? '!' : '*'),
482                      token(s));
483            return -1;
484        }
485
486        if(!token(s)) {
487            set_error(s, "<format>", "Unexpected end of format string");
488            return -1;
489        }
490
491        if(token(s) == '!' || token(s) == '*') {
492            strict = (token(s) == '!' ? 1 : -1);
493            next_token(s);
494            continue;
495        }
496
497        if(!strchr(unpack_value_starters, token(s))) {
498            set_error(s, "<format>", "Unexpected format character '%c'",
499                      token(s));
500            return -1;
501        }
502
503        if(!root) {
504            /* skipping */
505            value = NULL;
506        }
507        else {
508            value = json_array_get(root, i);
509            if(!value) {
510                set_error(s, "<validation>", "Array index %lu out of range",
511                          (unsigned long)i);
512                return -1;
513            }
514        }
515
516        if(unpack(s, value, ap))
517            return -1;
518
519        next_token(s);
520        i++;
521    }
522
523    if(strict == 0 && (s->flags & JSON_STRICT))
524        strict = 1;
525
526    if(root && strict == 1 && i != json_array_size(root)) {
527        long diff = (long)json_array_size(root) - (long)i;
528        set_error(s, "<validation>", "%li array item(s) left unpacked", diff);
529        return -1;
530    }
531
532    return 0;
533}
534
535static int unpack(scanner_t *s, json_t *root, va_list *ap)
536{
537    switch(token(s))
538    {
539        case '{':
540            return unpack_object(s, root, ap);
541
542        case '[':
543            return unpack_array(s, root, ap);
544
545        case 's':
546            if(root && !json_is_string(root)) {
547                set_error(s, "<validation>", "Expected string, got %s",
548                          type_name(root));
549                return -1;
550            }
551
552            if(!(s->flags & JSON_VALIDATE_ONLY)) {
553                const char **str_target;
554                size_t *len_target = NULL;
555
556                str_target = va_arg(*ap, const char **);
557                if(!str_target) {
558                    set_error(s, "<args>", "NULL string argument");
559                    return -1;
560                }
561
562                next_token(s);
563
564                if(token(s) == '%') {
565                    len_target = va_arg(*ap, size_t *);
566                    if(!len_target) {
567                        set_error(s, "<args>", "NULL string length argument");
568                        return -1;
569                    }
570                }
571                else
572                    prev_token(s);
573
574                if(root) {
575                    *str_target = json_string_value(root);
576                    if(len_target)
577                        *len_target = json_string_length(root);
578                }
579            }
580            return 0;
581
582        case 'i':
583            if(root && !json_is_integer(root)) {
584                set_error(s, "<validation>", "Expected integer, got %s",
585                          type_name(root));
586                return -1;
587            }
588
589            if(!(s->flags & JSON_VALIDATE_ONLY)) {
590                int *target = va_arg(*ap, int*);
591                if(root)
592                    *target = (int)json_integer_value(root);
593            }
594
595            return 0;
596
597        case 'I':
598            if(root && !json_is_integer(root)) {
599                set_error(s, "<validation>", "Expected integer, got %s",
600                          type_name(root));
601                return -1;
602            }
603
604            if(!(s->flags & JSON_VALIDATE_ONLY)) {
605                json_int_t *target = va_arg(*ap, json_int_t*);
606                if(root)
607                    *target = json_integer_value(root);
608            }
609
610            return 0;
611
612        case 'b':
613            if(root && !json_is_boolean(root)) {
614                set_error(s, "<validation>", "Expected true or false, got %s",
615                          type_name(root));
616                return -1;
617            }
618
619            if(!(s->flags & JSON_VALIDATE_ONLY)) {
620                int *target = va_arg(*ap, int*);
621                if(root)
622                    *target = json_is_true(root);
623            }
624
625            return 0;
626
627        case 'f':
628            if(root && !json_is_real(root)) {
629                set_error(s, "<validation>", "Expected real, got %s",
630                          type_name(root));
631                return -1;
632            }
633
634            if(!(s->flags & JSON_VALIDATE_ONLY)) {
635                double *target = va_arg(*ap, double*);
636                if(root)
637                    *target = json_real_value(root);
638            }
639
640            return 0;
641
642        case 'F':
643            if(root && !json_is_number(root)) {
644                set_error(s, "<validation>", "Expected real or integer, got %s",
645                          type_name(root));
646                return -1;
647            }
648
649            if(!(s->flags & JSON_VALIDATE_ONLY)) {
650                double *target = va_arg(*ap, double*);
651                if(root)
652                    *target = json_number_value(root);
653            }
654
655            return 0;
656
657        case 'O':
658            if(root && !(s->flags & JSON_VALIDATE_ONLY))
659                json_incref(root);
660            /* Fall through */
661
662        case 'o':
663            if(!(s->flags & JSON_VALIDATE_ONLY)) {
664                json_t **target = va_arg(*ap, json_t**);
665                if(root)
666                    *target = root;
667            }
668
669            return 0;
670
671        case 'n':
672            /* Never assign, just validate */
673            if(root && !json_is_null(root)) {
674                set_error(s, "<validation>", "Expected null, got %s",
675                          type_name(root));
676                return -1;
677            }
678            return 0;
679
680        default:
681            set_error(s, "<format>", "Unexpected format character '%c'",
682                      token(s));
683            return -1;
684    }
685}
686
687json_t *json_vpack_ex(json_error_t *error, size_t flags,
688                      const char *fmt, va_list ap)
689{
690    scanner_t s;
691    va_list ap_copy;
692    json_t *value;
693
694    if(!fmt || !*fmt) {
695        jsonp_error_init(error, "<format>");
696        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
697        return NULL;
698    }
699    jsonp_error_init(error, NULL);
700
701    scanner_init(&s, error, flags, fmt);
702    next_token(&s);
703
704    va_copy(ap_copy, ap);
705    value = pack(&s, &ap_copy);
706    va_end(ap_copy);
707
708    if(!value)
709        return NULL;
710
711    next_token(&s);
712    if(token(&s)) {
713        json_decref(value);
714        set_error(&s, "<format>", "Garbage after format string");
715        return NULL;
716    }
717
718    return value;
719}
720
721json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
722{
723    json_t *value;
724    va_list ap;
725
726    va_start(ap, fmt);
727    value = json_vpack_ex(error, flags, fmt, ap);
728    va_end(ap);
729
730    return value;
731}
732
733json_t *json_pack(const char *fmt, ...)
734{
735    json_t *value;
736    va_list ap;
737
738    va_start(ap, fmt);
739    value = json_vpack_ex(NULL, 0, fmt, ap);
740    va_end(ap);
741
742    return value;
743}
744
745int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
746                    const char *fmt, va_list ap)
747{
748    scanner_t s;
749    va_list ap_copy;
750
751    if(!root) {
752        jsonp_error_init(error, "<root>");
753        jsonp_error_set(error, -1, -1, 0, "NULL root value");
754        return -1;
755    }
756
757    if(!fmt || !*fmt) {
758        jsonp_error_init(error, "<format>");
759        jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
760        return -1;
761    }
762    jsonp_error_init(error, NULL);
763
764    scanner_init(&s, error, flags, fmt);
765    next_token(&s);
766
767    va_copy(ap_copy, ap);
768    if(unpack(&s, root, &ap_copy)) {
769        va_end(ap_copy);
770        return -1;
771    }
772    va_end(ap_copy);
773
774    next_token(&s);
775    if(token(&s)) {
776        set_error(&s, "<format>", "Garbage after format string");
777        return -1;
778    }
779
780    return 0;
781}
782
783int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
784{
785    int ret;
786    va_list ap;
787
788    va_start(ap, fmt);
789    ret = json_vunpack_ex(root, error, flags, fmt, ap);
790    va_end(ap);
791
792    return ret;
793}
794
795int json_unpack(json_t *root, const char *fmt, ...)
796{
797    int ret;
798    va_list ap;
799
800    va_start(ap, fmt);
801    ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
802    va_end(ap);
803
804    return ret;
805}
806