Fix empty array dumping
[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 "strbuffer.h"
13
14
15 #define JSON_TOKEN_INVALID         -1
16 #define JSON_TOKEN_EOF              0
17 #define JSON_TOKEN_STRING         256
18 #define JSON_TOKEN_INTEGER        257
19 #define JSON_TOKEN_REAL           258
20 #define JSON_TOKEN_TRUE           259
21 #define JSON_TOKEN_FALSE          260
22 #define JSON_TOKEN_NULL           261
23
24 typedef struct {
25     const char *input;
26     const char *start;
27     int token;
28     int line, column;
29     union {
30         char *string;
31         int integer;
32         double real;
33     } value;
34 } json_lex;
35
36
37 /*** error reporting ***/
38
39 static void json_set_error(json_error_t *error, const json_lex *lex,
40                            const char *msg, ...)
41 {
42     va_list ap;
43     char text[JSON_ERROR_TEXT_LENGTH];
44
45     if(!error)
46         return;
47
48     va_start(ap, msg);
49     vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap);
50     va_end(ap);
51
52     if(lex)
53     {
54         error->line = lex->line;
55         if(*lex->start)
56         {
57             int n = (int)(lex->input - lex->start);
58             snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
59                      "%s near '%.*s'", text, n, lex->start);
60         }
61         else
62         {
63             snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
64                      "%s near end of file", text);
65         }
66     }
67     else
68     {
69         error->line = -1;
70         snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text);
71     }
72 }
73
74
75 /*** lexical analyzer ***/
76
77 static void json_scan_string(json_lex *lex)
78 {
79     /* skip the " */
80     const char *p = lex->input + 1;
81     char *t;
82
83     lex->token = JSON_TOKEN_INVALID;
84
85     while(*p != '"') {
86         if(*p == '\0') {
87             /* unterminated string literal */
88             goto out;
89         }
90
91         if(0 <= *p && *p <= 31) {
92             /* control character */
93             goto out;
94         }
95         else if(*p == '\\') {
96             p++;
97             if(*p == 'u') {
98                 p++;
99                 for(int i = 0; i < 4; i++, p++) {
100                     if(!isxdigit(*p))
101                         goto out;
102                 }
103             }
104             if(*p == '"' || *p == '\\' || *p == '/' || *p == 'b' ||
105                *p == 'f' || *p == 'n' || *p == 'r' || *p == 't')
106                 p++;
107             else
108                 goto out;
109         }
110         else
111             p++;
112     }
113
114     /* the actual value is at most of the same length as the source
115        string */
116     lex->value.string = malloc(p - lex->start);
117     if(!lex->value.string) {
118         /* this is not very nice, since TOKEN_INVALID is returned */
119         goto out;
120     }
121
122     /* the target */
123     t = lex->value.string;
124
125     p = lex->input + 1;
126     while(*p != '"') {
127         if(*p == '\\') {
128             p++;
129             if(*p == 'u') {
130                 /* TODO: \uXXXX not supported yet */
131                 free(lex->value.string);
132                 lex->value.string = NULL;
133                 goto out;
134             } else {
135                 switch(*p) {
136                     case '"': case '\\': case '/':
137                         *t = *p; break;
138                     case 'b': *t = '\b'; break;
139                     case 'f': *t = '\f'; break;
140                     case 'n': *t = '\n'; break;
141                     case 'r': *t = '\r'; break;
142                     case 't': *t = '\t'; break;
143                     default: assert(0);
144                 }
145             }
146         }
147         else
148             *t = *p;
149
150         t++;
151         p++;
152     }
153     /* skip the " */
154     p++;
155
156     *t = '\0';
157     lex->token = JSON_TOKEN_STRING;
158
159 out:
160     lex->input = p;
161 }
162
163 static void json_scan_number(json_lex *lex)
164 {
165     const char *p = lex->input;
166     char *end;
167
168     lex->token = JSON_TOKEN_INVALID;
169
170     if(*p == '-')
171         p++;
172
173     if(*p == '0')
174         p++;
175     else /* *p != '0' */ {
176         p++;
177         while(isdigit(*p))
178             p++;
179     }
180
181     if(*p != '.') {
182         lex->token = JSON_TOKEN_INTEGER;
183
184         lex->value.integer = strtol(lex->start, &end, 10);
185         assert(end == p);
186
187         lex->input = p;
188         return;
189     }
190     else /* *p == '.' */ {
191         p++;
192         if(!isdigit(*(p++)))
193             goto out;
194
195         while(isdigit(*p))
196             p++;
197     }
198
199     if(*p == 'E' || *p == 'e') {
200         p++;
201         if(*p == '+' || *p == '-')
202             p++;
203
204         if(!isdigit(*(p++)))
205             goto out;
206
207         while(isdigit(*p))
208             p++;
209     }
210
211     lex->token = JSON_TOKEN_REAL;
212
213     lex->value.real = strtod(lex->start, &end);
214     assert(end == p);
215
216 out:
217     lex->input = p;
218 }
219
220 static int json_lex_scan(json_lex *lex)
221 {
222     char c;
223
224     if(lex->token == JSON_TOKEN_STRING) {
225       free(lex->value.string);
226       lex->value.string = NULL;
227     }
228
229     while(isspace(*lex->input)) {
230         if(*lex->input == '\n')
231             lex->line++;
232
233         lex->input++;
234     }
235
236     lex->start = lex->input;
237     c = *lex->input;
238
239     if(c == '\0')
240         lex->token = JSON_TOKEN_EOF;
241
242     else if(c == '{' || c == '}' || c == '[' || c == ']' ||
243             c == ':' || c == ',') {
244         lex->token = c;
245         lex->input++;
246     }
247
248     else if(c == '"')
249         json_scan_string(lex);
250
251     else if(isdigit(c) || c == '-')
252         json_scan_number(lex);
253
254     else if(isalpha(c)) {
255         /* eat up the whole identifier for clearer error messages */
256         int len;
257
258         while(isalpha(*lex->input))
259             lex->input++;
260         len = lex->input - lex->start;
261
262         if(strncmp(lex->start, "true", len) == 0)
263             lex->token = JSON_TOKEN_TRUE;
264         else if(strncmp(lex->start, "false", len) == 0)
265             lex->token = JSON_TOKEN_FALSE;
266         else if(strncmp(lex->start, "null", len) == 0)
267             lex->token = JSON_TOKEN_NULL;
268         else
269             lex->token = JSON_TOKEN_INVALID;
270     }
271
272     else {
273         lex->token = JSON_TOKEN_INVALID;
274         lex->input++;
275     }
276
277     return lex->token;
278 }
279
280 static int json_lex_init(json_lex *lex, const char *input)
281 {
282     lex->input = input;
283     lex->token = JSON_TOKEN_INVALID;
284     lex->line = 1;
285
286     json_lex_scan(lex);
287     return 0;
288 }
289
290 static void json_lex_close(json_lex *lex)
291 {
292     if(lex->token == JSON_TOKEN_STRING)
293         free(lex->value.string);
294 }
295
296
297 /*** parser ***/
298
299 static json_t *json_parse(json_lex *lex, json_error_t *error);
300
301 static json_t *json_parse_object(json_lex *lex, json_error_t *error)
302 {
303     json_t *object = json_object();
304     if(!object)
305         return NULL;
306
307     json_lex_scan(lex);
308     if(lex->token == '}')
309         return object;
310
311     while(lex->token) {
312         char *key;
313         json_t *value;
314
315         if(lex->token != JSON_TOKEN_STRING) {
316             json_set_error(error, lex, "string expected");
317             goto error;
318         }
319
320         key = strdup(lex->value.string);
321         if(!key)
322             return NULL;
323
324         json_lex_scan(lex);
325         if(lex->token != ':') {
326             free(key);
327             json_set_error(error, lex, "':' expected");
328             goto error;
329         }
330
331         json_lex_scan(lex);
332
333         value = json_parse(lex, error);
334         if(!value) {
335             free(key);
336             goto error;
337         }
338
339         if(json_object_set(object, key, value)) {
340             free(key);
341             json_decref(value);
342             goto error;
343         }
344
345         json_decref(value);
346         free(key);
347
348         if(lex->token != ',')
349             break;
350
351         json_lex_scan(lex);
352     }
353
354     if(lex->token != '}') {
355         json_set_error(error, lex, "'}' expected");
356         goto error;
357     }
358
359     return object;
360
361 error:
362     json_decref(object);
363     return NULL;
364 }
365
366 static json_t *json_parse_array(json_lex *lex, json_error_t *error)
367 {
368     json_t *array = json_array();
369     if(!array)
370         return NULL;
371
372     json_lex_scan(lex);
373     if(lex->token == ']')
374         return array;
375
376     while(lex->token) {
377         json_t *elem = json_parse(lex, error);
378         if(!elem)
379             goto error;
380
381         if(json_array_append(array, elem)) {
382             json_decref(elem);
383             goto error;
384         }
385         json_decref(elem);
386
387         if(lex->token != ',')
388             break;
389
390         json_lex_scan(lex);
391     }
392
393
394     if(lex->token != ']') {
395         json_set_error(error, lex, "']' expected");
396         goto error;
397     }
398
399     return array;
400
401 error:
402     json_decref(array);
403     return NULL;
404 }
405
406 static json_t *json_parse(json_lex *lex, json_error_t *error)
407 {
408     json_t *json;
409
410     switch(lex->token) {
411         case JSON_TOKEN_STRING: {
412             json = json_string(lex->value.string);
413             break;
414         }
415
416         case JSON_TOKEN_INTEGER: {
417             json = json_integer(lex->value.integer);
418             break;
419         }
420
421         case JSON_TOKEN_REAL: {
422             json = json_real(lex->value.real);
423             break;
424         }
425
426         case JSON_TOKEN_TRUE:
427             json = json_true();
428             break;
429
430         case JSON_TOKEN_FALSE:
431             json = json_false();
432             break;
433
434         case JSON_TOKEN_NULL:
435             json = json_null();
436             break;
437
438         case '{':
439           json = json_parse_object(lex, error);
440             break;
441
442         case '[':
443             json = json_parse_array(lex, error);
444             break;
445
446         case JSON_TOKEN_INVALID:
447             json_set_error(error, lex, "invalid token");
448             return NULL;
449
450         default:
451             json_set_error(error, lex, "unexpected token");
452             return NULL;
453     }
454
455     if(!json)
456         return NULL;
457
458     json_lex_scan(lex);
459     return json;
460 }
461
462 json_t *json_load(const char *path, json_error_t *error)
463 {
464     json_t *result;
465     FILE *fp;
466
467     fp = fopen(path, "r");
468     if(!fp)
469     {
470         json_set_error(error, NULL, "unable to open %s: %s",
471                        path, strerror(errno));
472         return NULL;
473     }
474
475     result = json_loadf(fp, error);
476
477     fclose(fp);
478     return result;
479 }
480
481 json_t *json_loads(const char *string, json_error_t *error)
482 {
483     json_lex lex;
484     json_t *result = NULL;
485
486     if(json_lex_init(&lex, string))
487         return NULL;
488
489     if(lex.token != '[' && lex.token != '{') {
490         json_set_error(error, &lex, "'[' or '{' expected");
491         goto out;
492     }
493
494     result = json_parse(&lex, error);
495     if(!result)
496         goto out;
497
498     if(lex.token != JSON_TOKEN_EOF) {
499         json_set_error(error, &lex, "end of file expected");
500         json_decref(result);
501         result = NULL;
502     }
503
504 out:
505     json_lex_close(&lex);
506     return result;
507 }
508
509 #define BUFFER_SIZE 4096
510
511 json_t *json_loadf(FILE *input, json_error_t *error)
512 {
513     strbuffer_t strbuff;
514     char buffer[BUFFER_SIZE];
515     size_t length;
516     json_t *result = NULL;
517
518     if(strbuffer_init(&strbuff))
519       return NULL;
520
521     while(1)
522     {
523         length = fread(buffer, 1, BUFFER_SIZE, input);
524         if(length == 0)
525         {
526             if(ferror(input))
527             {
528                 json_set_error(error, NULL, "read error");
529                 goto out;
530             }
531             break;
532         }
533         if(strbuffer_append_bytes(&strbuff, buffer, length))
534             goto out;
535     }
536
537     result = json_loads(strbuffer_value(&strbuff), error);
538
539 out:
540     strbuffer_close(&strbuff);
541     return result;
542 }
543
544 json_t *json_loadfd(int fd, json_error_t *error)
545 {
546     strbuffer_t strbuff;
547     char buffer[BUFFER_SIZE];
548     ssize_t length;
549     json_t *result = NULL;
550
551     if(strbuffer_init(&strbuff))
552       return NULL;
553
554     while(1)
555     {
556         length = read(fd, buffer, BUFFER_SIZE);
557         if(length == -1)
558         {
559             json_set_error(error, NULL, "read error: %s", strerror(errno));
560             goto out;
561         }
562         else if(length == 0)
563             break;
564
565         if(strbuffer_append_bytes(&strbuff, buffer, length))
566         {
567             json_set_error(error, NULL, "error allocating memory");
568             goto out;
569         }
570     }
571
572     result = json_loads(strbuffer_value(&strbuff), error);
573
574 out:
575     strbuffer_close(&strbuff);
576     return result;
577 }