f9bcf7b09428eb70ad5740a4f0cbc823ed867e0e
[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_save_cached(lex_t *lex)
203 {
204     while(lex->stream.buffer[lex->stream.buffer_pos] != '\0')
205     {
206         lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
207         lex->stream.buffer_pos++;
208     }
209 }
210
211 static void lex_scan_string(lex_t *lex, json_error_t *error)
212 {
213     char c;
214     const char *p;
215     char *t;
216
217     lex->token = TOKEN_INVALID;
218
219     /* skip the " */
220     c = lex_get_save(lex, error);
221
222     while(c != '"') {
223         if(c == EOF) {
224             if(lex_eof(lex))
225                 error_set(error, lex, "premature end of input");
226             goto out;
227         }
228
229         else if(0 <= c && c <= 0x1F) {
230             /* control character */
231             lex_unget_unsave(lex, c);
232             if(c == '\n')
233                 error_set(error, lex, "unexpected newline", c);
234             else
235                 error_set(error, lex, "control character 0x%x", c);
236             goto out;
237         }
238
239         else if(c == '\\') {
240             c = lex_get_save(lex, error);
241             if(c == 'u') {
242                 c = lex_get_save(lex, error);
243                 for(int i = 0; i < 4; i++) {
244                     if(!isxdigit(c)) {
245                         lex_unget_unsave(lex, c);
246                         error_set(error, lex, "invalid escape");
247                         goto out;
248                     }
249                     c = lex_get_save(lex, error);
250                 }
251             }
252             else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
253                     c == 'f' || c == 'n' || c == 'r' || c == 't')
254                 c = lex_get_save(lex, error);
255             else {
256                 lex_unget_unsave(lex, c);
257                 error_set(error, lex, "invalid escape");
258                 goto out;
259             }
260         }
261         else
262             c = lex_get_save(lex, error);
263     }
264
265     /* the actual value is at most of the same length as the source
266        string, because:
267          - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
268          - a single \uXXXX escape (length 6) is converted to at most 3 bytes
269          - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
270            are converted to 4 bytes
271     */
272     lex->value.string = malloc(lex->saved_text.length + 1);
273     if(!lex->value.string) {
274         /* this is not very nice, since TOKEN_INVALID is returned */
275         goto out;
276     }
277
278     /* the target */
279     t = lex->value.string;
280
281     /* + 1 to skip the " */
282     p = strbuffer_value(&lex->saved_text) + 1;
283
284     while(*p != '"') {
285         if(*p == '\\') {
286             p++;
287             if(*p == 'u') {
288                 /* TODO */
289                 error_set(error, lex, "\\u escapes are not yet supported");
290                 free(lex->value.string);
291                 lex->value.string = NULL;
292                 goto out;
293             } else {
294                 switch(*p) {
295                     case '"': case '\\': case '/':
296                         *t = *p; break;
297                     case 'b': *t = '\b'; break;
298                     case 'f': *t = '\f'; break;
299                     case 'n': *t = '\n'; break;
300                     case 'r': *t = '\r'; break;
301                     case 't': *t = '\t'; break;
302                     default: assert(0);
303                 }
304             }
305         }
306         else
307             *t = *p;
308
309         t++;
310         p++;
311     }
312     *t = '\0';
313     lex->token = TOKEN_STRING;
314
315 out:
316     return;
317 }
318
319 static void lex_scan_number(lex_t *lex, char c, json_error_t *error)
320 {
321     const char *saved_text;
322     char *end;
323
324     lex->token = TOKEN_INVALID;
325
326     if(c == '-')
327         c = lex_get_save(lex, error);
328
329     if(c == '0') {
330         c = lex_get_save(lex, error);
331         if(isdigit(c)) {
332             lex_unget_unsave(lex, c);
333             goto out;
334         }
335     }
336     else /* c != '0' */ {
337         c = lex_get_save(lex, error);
338         while(isdigit(c))
339             c = lex_get_save(lex, error);
340     }
341
342     if(c != '.' && c != 'E' && c != 'e') {
343         lex_unget_unsave(lex, c);
344         lex->token = TOKEN_INTEGER;
345
346         saved_text = strbuffer_value(&lex->saved_text);
347         lex->value.integer = strtol(saved_text, &end, 10);
348         assert(end == saved_text + lex->saved_text.length);
349
350         return;
351     }
352
353     if(c == '.') {
354         c = lex_get(lex, error);
355         if(!isdigit(c))
356             goto out;
357         lex_save(lex, c);
358
359         c = lex_get_save(lex, error);
360         while(isdigit(c))
361             c = lex_get_save(lex, error);
362     }
363
364     if(c == 'E' || c == 'e') {
365         c = lex_get_save(lex, error);
366         if(c == '+' || c == '-')
367             c = lex_get_save(lex, error);
368
369         if(!isdigit(c)) {
370             lex_unget_unsave(lex, c);
371             goto out;
372         }
373
374         c = lex_get_save(lex, error);
375         while(isdigit(c))
376             c = lex_get_save(lex, error);
377     }
378
379     lex_unget_unsave(lex, c);
380     lex->token = TOKEN_REAL;
381
382     saved_text = strbuffer_value(&lex->saved_text);
383     lex->value.real = strtod(saved_text, &end);
384     assert(end == saved_text + lex->saved_text.length);
385
386 out:
387     return;
388 }
389
390 static int lex_scan(lex_t *lex, json_error_t *error)
391 {
392     char c;
393
394     strbuffer_clear(&lex->saved_text);
395
396     if(lex->token == TOKEN_STRING) {
397       free(lex->value.string);
398       lex->value.string = NULL;
399     }
400
401     c = lex_get(lex, error);
402     while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
403     {
404         if(c == '\n')
405             lex->line++;
406
407         c = lex_get(lex, error);
408     }
409
410     if(c == EOF) {
411         if(lex_eof(lex))
412             lex->token = TOKEN_EOF;
413         else
414             lex->token = TOKEN_INVALID;
415         goto out;
416     }
417
418     lex_save(lex, c);
419
420     if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
421         lex->token = c;
422
423     else if(c == '"')
424         lex_scan_string(lex, error);
425
426     else if(isdigit(c) || c == '-')
427         lex_scan_number(lex, c, error);
428
429     else if(isupper(c) || islower(c)) {
430         /* eat up the whole identifier for clearer error messages */
431         const char *saved_text;
432
433         c = lex_get_save(lex, error);
434         while(isupper(c) || islower(c))
435             c = lex_get_save(lex, error);
436         lex_unget_unsave(lex, c);
437
438         saved_text = strbuffer_value(&lex->saved_text);
439
440         if(strcmp(saved_text, "true") == 0)
441             lex->token = TOKEN_TRUE;
442         else if(strcmp(saved_text, "false") == 0)
443             lex->token = TOKEN_FALSE;
444         else if(strcmp(saved_text, "null") == 0)
445             lex->token = TOKEN_NULL;
446         else
447             lex->token = TOKEN_INVALID;
448     }
449
450     else {
451         /* save the rest of the input UTF-8 sequence to get an error
452            message of valid UTF-8 */
453         lex_save_cached(lex);
454         lex->token = TOKEN_INVALID;
455     }
456
457 out:
458     return lex->token;
459 }
460
461 static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data)
462 {
463     stream_init(&lex->stream, get, eof, data);
464     if(strbuffer_init(&lex->saved_text))
465         return -1;
466
467     lex->token = TOKEN_INVALID;
468     lex->line = 1;
469
470     return 0;
471 }
472
473 static void lex_close(lex_t *lex)
474 {
475     if(lex->token == TOKEN_STRING)
476         free(lex->value.string);
477 }
478
479
480 /*** parser ***/
481
482 static json_t *parse_value(lex_t *lex, json_error_t *error);
483
484 static json_t *parse_object(lex_t *lex, json_error_t *error)
485 {
486     json_t *object = json_object();
487     if(!object)
488         return NULL;
489
490     lex_scan(lex, error);
491     if(lex->token == '}')
492         return object;
493
494     while(1) {
495         char *key;
496         json_t *value;
497
498         if(lex->token != TOKEN_STRING) {
499             error_set(error, lex, "string or '}' expected");
500             goto error;
501         }
502
503         key = strdup(lex->value.string);
504         if(!key)
505             return NULL;
506
507         lex_scan(lex, error);
508         if(lex->token != ':') {
509             free(key);
510             error_set(error, lex, "':' expected");
511             goto error;
512         }
513
514         lex_scan(lex, error);
515         value = parse_value(lex, error);
516         if(!value) {
517             free(key);
518             goto error;
519         }
520
521         if(json_object_set_nocheck(object, key, value)) {
522             free(key);
523             json_decref(value);
524             goto error;
525         }
526
527         json_decref(value);
528         free(key);
529
530         lex_scan(lex, error);
531         if(lex->token != ',')
532             break;
533
534         lex_scan(lex, error);
535     }
536
537     if(lex->token != '}') {
538         error_set(error, lex, "'}' expected");
539         goto error;
540     }
541
542     return object;
543
544 error:
545     json_decref(object);
546     return NULL;
547 }
548
549 static json_t *parse_array(lex_t *lex, json_error_t *error)
550 {
551     json_t *array = json_array();
552     if(!array)
553         return NULL;
554
555     lex_scan(lex, error);
556     if(lex->token == ']')
557         return array;
558
559     while(lex->token) {
560         json_t *elem = parse_value(lex, error);
561         if(!elem)
562             goto error;
563
564         if(json_array_append(array, elem)) {
565             json_decref(elem);
566             goto error;
567         }
568         json_decref(elem);
569
570         lex_scan(lex, error);
571         if(lex->token != ',')
572             break;
573
574         lex_scan(lex, error);
575     }
576
577     if(lex->token != ']') {
578         error_set(error, lex, "']' expected");
579         goto error;
580     }
581
582     return array;
583
584 error:
585     json_decref(array);
586     return NULL;
587 }
588
589 static json_t *parse_value(lex_t *lex, json_error_t *error)
590 {
591     json_t *json;
592
593     switch(lex->token) {
594         case TOKEN_STRING: {
595             json = json_string_nocheck(lex->value.string);
596             break;
597         }
598
599         case TOKEN_INTEGER: {
600             json = json_integer(lex->value.integer);
601             break;
602         }
603
604         case TOKEN_REAL: {
605             json = json_real(lex->value.real);
606             break;
607         }
608
609         case TOKEN_TRUE:
610             json = json_true();
611             break;
612
613         case TOKEN_FALSE:
614             json = json_false();
615             break;
616
617         case TOKEN_NULL:
618             json = json_null();
619             break;
620
621         case '{':
622           json = parse_object(lex, error);
623             break;
624
625         case '[':
626             json = parse_array(lex, error);
627             break;
628
629         case TOKEN_INVALID:
630             error_set(error, lex, "invalid token");
631             return NULL;
632
633         default:
634             error_set(error, lex, "unexpected token");
635             return NULL;
636     }
637
638     if(!json)
639         return NULL;
640
641     return json;
642 }
643
644 json_t *parse_json(lex_t *lex, json_error_t *error)
645 {
646     error_init(error);
647
648     lex_scan(lex, error);
649     if(lex->token != '[' && lex->token != '{') {
650         error_set(error, lex, "'[' or '{' expected");
651         return NULL;
652     }
653
654     return parse_value(lex, error);
655 }
656
657 json_t *json_load(const char *path, json_error_t *error)
658 {
659     json_t *result;
660     FILE *fp;
661
662     fp = fopen(path, "r");
663     if(!fp)
664     {
665         error_set(error, NULL, "unable to open %s: %s",
666                   path, strerror(errno));
667         return NULL;
668     }
669
670     result = json_loadf(fp, error);
671
672     fclose(fp);
673     return result;
674 }
675
676 typedef struct
677 {
678     const char *data;
679     int pos;
680 } string_data_t;
681
682 static int string_get(void *data)
683 {
684     char c;
685     string_data_t *stream = (string_data_t *)data;
686     c = stream->data[stream->pos++];
687     if(c == '\0')
688         return EOF;
689     else
690         return c;
691 }
692
693 static int string_eof(void *data)
694 {
695     string_data_t *stream = (string_data_t *)data;
696     return (stream->data[stream->pos] == '\0');
697 }
698
699 json_t *json_loads(const char *string, json_error_t *error)
700 {
701     lex_t lex;
702     json_t *result;
703
704     string_data_t stream_data = {
705         .data = string,
706         .pos = 0
707     };
708
709     if(lex_init(&lex, string_get, string_eof, (void *)&stream_data))
710         return NULL;
711
712     result = parse_json(&lex, error);
713     if(!result)
714         goto out;
715
716     lex_scan(&lex, error);
717     if(lex.token != TOKEN_EOF) {
718         error_set(error, &lex, "end of file expected");
719         json_decref(result);
720         result = NULL;
721     }
722
723 out:
724     lex_close(&lex);
725     return result;
726 }
727
728 json_t *json_loadf(FILE *input, json_error_t *error)
729 {
730     lex_t lex;
731     json_t *result;
732
733     if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input))
734         return NULL;
735
736     result = parse_json(&lex, error);
737
738     lex_close(&lex);
739     return result;
740 }