Report errors from lexical and stream level in parser
[jansson.git] / src / load.c
1 #define _GNU_SOURCE
2 #include <ctype.h>
3 #include <errno.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdarg.h>
8 #include <unistd.h>
9 #include <assert.h>
10
11 #include <jansson.h>
12 #include "jansson_private.h"
13 #include "strbuffer.h"
14 #include "utf.h"
15
16 #define TOKEN_INVALID         -1
17 #define TOKEN_EOF              0
18 #define TOKEN_STRING         256
19 #define TOKEN_INTEGER        257
20 #define TOKEN_REAL           258
21 #define TOKEN_TRUE           259
22 #define TOKEN_FALSE          260
23 #define TOKEN_NULL           261
24
25 /* read one byte from stream, return EOF on end of file */
26 typedef int (*get_func)(void *data);
27
28 /* return non-zero if end of file has been reached */
29 typedef int (*eof_func)(void *data);
30
31 typedef struct {
32     get_func get;
33     eof_func eof;
34     void *data;
35     int stream_pos;
36     char buffer[5];
37     int buffer_pos;
38 } stream_t;
39
40
41 typedef struct {
42     stream_t stream;
43     strbuffer_t saved_text;
44     int token;
45     int line, column;
46     union {
47         char *string;
48         int integer;
49         double real;
50     } value;
51 } lex_t;
52
53
54 /*** error reporting ***/
55
56 static void error_init(json_error_t *error)
57 {
58     if(error)
59     {
60         error->text[0] = '\0';
61         error->line = -1;
62     }
63 }
64
65 static void error_set(json_error_t *error, const lex_t *lex,
66                       const char *msg, ...)
67 {
68     va_list ap;
69     char text[JSON_ERROR_TEXT_LENGTH];
70
71     if(!error || error->text[0] != '\0') {
72         /* error already set */
73         return;
74     }
75
76     va_start(ap, msg);
77     vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap);
78     va_end(ap);
79
80     if(lex)
81     {
82         const char *saved_text = strbuffer_value(&lex->saved_text);
83         error->line = lex->line;
84         if(saved_text && saved_text[0])
85         {
86             snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
87                      "%s near '%s'", text, saved_text);
88         }
89         else
90         {
91             snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
92                      "%s near end of file", text);
93         }
94     }
95     else
96     {
97         error->line = -1;
98         snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text);
99     }
100 }
101
102
103 /*** lexical analyzer ***/
104
105 void stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
106 {
107     stream->get = get;
108     stream->eof = eof;
109     stream->data = data;
110     stream->stream_pos = 0;
111     stream->buffer[0] = '\0';
112     stream->buffer_pos = 0;
113 }
114
115 static char stream_get(stream_t *stream, json_error_t *error)
116 {
117     char c;
118
119     if(!stream->buffer[stream->buffer_pos])
120     {
121         stream->buffer[0] = stream->get(stream->data);
122         stream->buffer_pos = 0;
123
124         c = stream->buffer[0];
125
126         if(c == EOF && stream->eof(stream->data))
127             return EOF;
128
129         if(c < 0)
130         {
131             /* multi-byte UTF-8 sequence */
132             int i, count;
133
134             count = utf8_check_first(c);
135             if(!count)
136                 goto out;
137
138             assert(count >= 2);
139
140             for(i = 1; i < count; i++)
141                 stream->buffer[i] = stream->get(stream->data);
142
143             if(!utf8_check_full(stream->buffer, count))
144                 goto out;
145
146             stream->stream_pos += count;
147             stream->buffer[count] = '\0';
148         }
149         else {
150             stream->buffer[1] = '\0';
151             stream->stream_pos++;
152         }
153     }
154
155     return (char)stream->buffer[stream->buffer_pos++];
156
157 out:
158     error_set(error, NULL, "unable to decode byte 0x%x at position %d",
159               (unsigned char)c, stream->stream_pos);
160     return EOF;
161 }
162
163 static void stream_unget(stream_t *stream, char c)
164 {
165     assert(stream->buffer_pos > 0);
166     stream->buffer_pos--;
167     assert(stream->buffer[stream->buffer_pos] == (unsigned char)c);
168 }
169
170
171 static int lex_get(lex_t *lex, json_error_t *error)
172 {
173     return stream_get(&lex->stream, error);
174 }
175
176 static int lex_eof(lex_t *lex)
177 {
178     return lex->stream.eof(lex->stream.data);
179 }
180
181 static void lex_save(lex_t *lex, char c)
182 {
183     strbuffer_append_byte(&lex->saved_text, c);
184 }
185
186 static int lex_get_save(lex_t *lex, json_error_t *error)
187 {
188     char c = stream_get(&lex->stream, error);
189     lex_save(lex, c);
190     return c;
191 }
192
193 static void lex_unget_unsave(lex_t *lex, char c)
194 {
195     char d;
196     if(c != EOF)
197         stream_unget(&lex->stream, c);
198     d = strbuffer_pop(&lex->saved_text);
199     assert(c == d);
200 }
201
202 static void lex_scan_string(lex_t *lex, json_error_t *error)
203 {
204     char c;
205     const char *p;
206     char *t;
207
208     lex->token = TOKEN_INVALID;
209
210     /* skip the " */
211     c = lex_get_save(lex, error);
212
213     while(c != '"') {
214         if(c == EOF) {
215             if(lex_eof(lex))
216                 error_set(error, lex, "premature end of input");
217             goto out;
218         }
219
220         else if(0 <= c && c <= 0x1F) {
221             /* control character */
222             lex_unget_unsave(lex, c);
223             if(c == '\n')
224                 error_set(error, lex, "unexpected newline", c);
225             else
226                 error_set(error, lex, "control character 0x%x", c);
227             goto out;
228         }
229
230         else if(c == '\\') {
231             c = lex_get_save(lex, error);
232             if(c == 'u') {
233                 c = lex_get_save(lex, error);
234                 for(int i = 0; i < 4; i++) {
235                     if(!isxdigit(c)) {
236                         lex_unget_unsave(lex, c);
237                         error_set(error, lex, "invalid escape");
238                         goto out;
239                     }
240                     c = lex_get_save(lex, error);
241                 }
242             }
243             else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
244                     c == 'f' || c == 'n' || c == 'r' || c == 't')
245                 c = lex_get_save(lex, error);
246             else {
247                 lex_unget_unsave(lex, c);
248                 error_set(error, lex, "invalid escape");
249                 goto out;
250             }
251         }
252         else
253             c = lex_get_save(lex, error);
254     }
255
256     /* the actual value is at most of the same length as the source
257        string, because:
258          - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
259          - a single \uXXXX escape (length 6) is converted to at most 3 bytes
260          - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
261            are converted to 4 bytes
262     */
263     lex->value.string = malloc(lex->saved_text.length + 1);
264     if(!lex->value.string) {
265         /* this is not very nice, since TOKEN_INVALID is returned */
266         goto out;
267     }
268
269     /* the target */
270     t = lex->value.string;
271
272     /* + 1 to skip the " */
273     p = strbuffer_value(&lex->saved_text) + 1;
274
275     while(*p != '"') {
276         if(*p == '\\') {
277             p++;
278             if(*p == 'u') {
279                 /* TODO */
280                 error_set(error, lex, "\\u escapes are not yet supported");
281                 free(lex->value.string);
282                 lex->value.string = NULL;
283                 goto out;
284             } else {
285                 switch(*p) {
286                     case '"': case '\\': case '/':
287                         *t = *p; break;
288                     case 'b': *t = '\b'; break;
289                     case 'f': *t = '\f'; break;
290                     case 'n': *t = '\n'; break;
291                     case 'r': *t = '\r'; break;
292                     case 't': *t = '\t'; break;
293                     default: assert(0);
294                 }
295             }
296         }
297         else
298             *t = *p;
299
300         t++;
301         p++;
302     }
303     *t = '\0';
304     lex->token = TOKEN_STRING;
305
306 out:
307     return;
308 }
309
310 static void lex_scan_number(lex_t *lex, char c, json_error_t *error)
311 {
312     const char *saved_text;
313     char *end;
314
315     lex->token = TOKEN_INVALID;
316
317     if(c == '-')
318         c = lex_get_save(lex, error);
319
320     if(c == '0') {
321         c = lex_get_save(lex, error);
322         if(isdigit(c)) {
323             lex_unget_unsave(lex, c);
324             goto out;
325         }
326     }
327     else /* c != '0' */ {
328         c = lex_get_save(lex, error);
329         while(isdigit(c))
330             c = lex_get_save(lex, error);
331     }
332
333     if(c != '.' && c != 'E' && c != 'e') {
334         lex_unget_unsave(lex, c);
335         lex->token = TOKEN_INTEGER;
336
337         saved_text = strbuffer_value(&lex->saved_text);
338         lex->value.integer = strtol(saved_text, &end, 10);
339         assert(end == saved_text + lex->saved_text.length);
340
341         return;
342     }
343
344     if(c == '.') {
345         c = lex_get(lex, error);
346         if(!isdigit(c))
347             goto out;
348         lex_save(lex, c);
349
350         c = lex_get_save(lex, error);
351         while(isdigit(c))
352             c = lex_get_save(lex, error);
353     }
354
355     if(c == 'E' || c == 'e') {
356         c = lex_get_save(lex, error);
357         if(c == '+' || c == '-')
358             c = lex_get_save(lex, error);
359
360         if(!isdigit(c)) {
361             lex_unget_unsave(lex, c);
362             goto out;
363         }
364
365         c = lex_get_save(lex, error);
366         while(isdigit(c))
367             c = lex_get_save(lex, error);
368     }
369
370     lex_unget_unsave(lex, c);
371     lex->token = TOKEN_REAL;
372
373     saved_text = strbuffer_value(&lex->saved_text);
374     lex->value.real = strtod(saved_text, &end);
375     assert(end == saved_text + lex->saved_text.length);
376
377 out:
378     return;
379 }
380
381 static int lex_scan(lex_t *lex, json_error_t *error)
382 {
383     char c;
384
385     strbuffer_clear(&lex->saved_text);
386
387     if(lex->token == TOKEN_STRING) {
388       free(lex->value.string);
389       lex->value.string = NULL;
390     }
391
392     c = lex_get(lex, error);
393     while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
394     {
395         if(c == '\n')
396             lex->line++;
397
398         c = lex_get(lex, error);
399     }
400
401     if(c == EOF) {
402         if(lex_eof(lex))
403             lex->token = TOKEN_EOF;
404         else
405             lex->token = TOKEN_INVALID;
406         goto out;
407     }
408
409     lex_save(lex, c);
410
411     if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
412         lex->token = c;
413
414     else if(c == '"')
415         lex_scan_string(lex, error);
416
417     else if(isdigit(c) || c == '-')
418         lex_scan_number(lex, c, error);
419
420     else if(isupper(c) || islower(c)) {
421         /* eat up the whole identifier for clearer error messages */
422         const char *saved_text;
423
424         c = lex_get_save(lex, error);
425         while(isupper(c) || islower(c))
426             c = lex_get_save(lex, error);
427         lex_unget_unsave(lex, c);
428
429         saved_text = strbuffer_value(&lex->saved_text);
430
431         if(strcmp(saved_text, "true") == 0)
432             lex->token = TOKEN_TRUE;
433         else if(strcmp(saved_text, "false") == 0)
434             lex->token = TOKEN_FALSE;
435         else if(strcmp(saved_text, "null") == 0)
436             lex->token = TOKEN_NULL;
437         else
438             lex->token = TOKEN_INVALID;
439     }
440
441     else
442         lex->token = TOKEN_INVALID;
443
444 out:
445     return lex->token;
446 }
447
448 static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data)
449 {
450     stream_init(&lex->stream, get, eof, data);
451     if(strbuffer_init(&lex->saved_text))
452         return -1;
453
454     lex->token = TOKEN_INVALID;
455     lex->line = 1;
456
457     return 0;
458 }
459
460 static void lex_close(lex_t *lex)
461 {
462     if(lex->token == TOKEN_STRING)
463         free(lex->value.string);
464 }
465
466
467 /*** parser ***/
468
469 static json_t *parse_value(lex_t *lex, json_error_t *error);
470
471 static json_t *parse_object(lex_t *lex, json_error_t *error)
472 {
473     json_t *object = json_object();
474     if(!object)
475         return NULL;
476
477     lex_scan(lex, error);
478     if(lex->token == '}')
479         return object;
480
481     while(1) {
482         char *key;
483         json_t *value;
484
485         if(lex->token != TOKEN_STRING) {
486             error_set(error, lex, "string or '}' expected");
487             goto error;
488         }
489
490         key = strdup(lex->value.string);
491         if(!key)
492             return NULL;
493
494         lex_scan(lex, error);
495         if(lex->token != ':') {
496             free(key);
497             error_set(error, lex, "':' expected");
498             goto error;
499         }
500
501         lex_scan(lex, error);
502         value = parse_value(lex, error);
503         if(!value) {
504             free(key);
505             goto error;
506         }
507
508         if(json_object_set_nocheck(object, key, value)) {
509             free(key);
510             json_decref(value);
511             goto error;
512         }
513
514         json_decref(value);
515         free(key);
516
517         lex_scan(lex, error);
518         if(lex->token != ',')
519             break;
520
521         lex_scan(lex, error);
522     }
523
524     if(lex->token != '}') {
525         error_set(error, lex, "'}' expected");
526         goto error;
527     }
528
529     return object;
530
531 error:
532     json_decref(object);
533     return NULL;
534 }
535
536 static json_t *parse_array(lex_t *lex, json_error_t *error)
537 {
538     json_t *array = json_array();
539     if(!array)
540         return NULL;
541
542     lex_scan(lex, error);
543     if(lex->token == ']')
544         return array;
545
546     while(lex->token) {
547         json_t *elem = parse_value(lex, error);
548         if(!elem)
549             goto error;
550
551         if(json_array_append(array, elem)) {
552             json_decref(elem);
553             goto error;
554         }
555         json_decref(elem);
556
557         lex_scan(lex, error);
558         if(lex->token != ',')
559             break;
560
561         lex_scan(lex, error);
562     }
563
564     if(lex->token != ']') {
565         error_set(error, lex, "']' expected");
566         goto error;
567     }
568
569     return array;
570
571 error:
572     json_decref(array);
573     return NULL;
574 }
575
576 static json_t *parse_value(lex_t *lex, json_error_t *error)
577 {
578     json_t *json;
579
580     switch(lex->token) {
581         case TOKEN_STRING: {
582             json = json_string_nocheck(lex->value.string);
583             break;
584         }
585
586         case TOKEN_INTEGER: {
587             json = json_integer(lex->value.integer);
588             break;
589         }
590
591         case TOKEN_REAL: {
592             json = json_real(lex->value.real);
593             break;
594         }
595
596         case TOKEN_TRUE:
597             json = json_true();
598             break;
599
600         case TOKEN_FALSE:
601             json = json_false();
602             break;
603
604         case TOKEN_NULL:
605             json = json_null();
606             break;
607
608         case '{':
609           json = parse_object(lex, error);
610             break;
611
612         case '[':
613             json = parse_array(lex, error);
614             break;
615
616         case TOKEN_INVALID:
617             error_set(error, lex, "invalid token");
618             return NULL;
619
620         default:
621             error_set(error, lex, "unexpected token");
622             return NULL;
623     }
624
625     if(!json)
626         return NULL;
627
628     return json;
629 }
630
631 json_t *parse_json(lex_t *lex, json_error_t *error)
632 {
633     error_init(error);
634
635     lex_scan(lex, error);
636     if(lex->token != '[' && lex->token != '{') {
637         error_set(error, lex, "'[' or '{' expected");
638         return NULL;
639     }
640
641     return parse_value(lex, error);
642 }
643
644 json_t *json_load(const char *path, json_error_t *error)
645 {
646     json_t *result;
647     FILE *fp;
648
649     fp = fopen(path, "r");
650     if(!fp)
651     {
652         error_set(error, NULL, "unable to open %s: %s",
653                   path, strerror(errno));
654         return NULL;
655     }
656
657     result = json_loadf(fp, error);
658
659     fclose(fp);
660     return result;
661 }
662
663 typedef struct
664 {
665     const char *data;
666     int pos;
667 } string_data_t;
668
669 static int string_get(void *data)
670 {
671     char c;
672     string_data_t *stream = (string_data_t *)data;
673     c = stream->data[stream->pos++];
674     if(c == '\0')
675         return EOF;
676     else
677         return c;
678 }
679
680 static int string_eof(void *data)
681 {
682     string_data_t *stream = (string_data_t *)data;
683     return (stream->data[stream->pos] == '\0');
684 }
685
686 json_t *json_loads(const char *string, json_error_t *error)
687 {
688     lex_t lex;
689     json_t *result;
690
691     string_data_t stream_data = {
692         .data = string,
693         .pos = 0
694     };
695
696     if(lex_init(&lex, string_get, string_eof, (void *)&stream_data))
697         return NULL;
698
699     result = parse_json(&lex, error);
700     if(!result)
701         goto out;
702
703     lex_scan(&lex, error);
704     if(lex.token != TOKEN_EOF) {
705         error_set(error, &lex, "end of file expected");
706         json_decref(result);
707         result = NULL;
708     }
709
710 out:
711     lex_close(&lex);
712     return result;
713 }
714
715 json_t *json_loadf(FILE *input, json_error_t *error)
716 {
717     lex_t lex;
718     json_t *result;
719
720     if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input))
721         return NULL;
722
723     result = parse_json(&lex, error);
724
725     lex_close(&lex);
726     return result;
727 }