Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org> |
3 | | * |
4 | | * Jansson is free software; you can redistribute it and/or modify |
5 | | * it under the terms of the MIT license. See LICENSE for details. |
6 | | */ |
7 | | |
8 | | #ifndef _GNU_SOURCE |
9 | | #define _GNU_SOURCE |
10 | | #endif |
11 | | |
12 | | #include "jansson_private.h" |
13 | | |
14 | | #include <assert.h> |
15 | | #include <errno.h> |
16 | | #include <limits.h> |
17 | | #include <stdio.h> |
18 | | #include <stdlib.h> |
19 | | #include <string.h> |
20 | | #ifdef HAVE_UNISTD_H |
21 | | #include <unistd.h> |
22 | | #endif |
23 | | |
24 | | #include "jansson.h" |
25 | | #include "strbuffer.h" |
26 | | #include "utf.h" |
27 | | |
28 | 83.7M | #define STREAM_STATE_OK 0 |
29 | 246M | #define STREAM_STATE_EOF -1 |
30 | 163M | #define STREAM_STATE_ERROR -2 |
31 | | |
32 | 569k | #define TOKEN_INVALID -1 |
33 | 63.2k | #define TOKEN_EOF 0 |
34 | 2.36M | #define TOKEN_STRING 256 |
35 | 165k | #define TOKEN_INTEGER 257 |
36 | 54.8k | #define TOKEN_REAL 258 |
37 | 871 | #define TOKEN_TRUE 259 |
38 | 5 | #define TOKEN_FALSE 260 |
39 | 6 | #define TOKEN_NULL 261 |
40 | | |
41 | | /* Locale independent versions of isxxx() functions */ |
42 | 167k | #define l_isupper(c) ('A' <= (c) && (c) <= 'Z') |
43 | 259k | #define l_islower(c) ('a' <= (c) && (c) <= 'z') |
44 | 4.79k | #define l_isalpha(c) (l_isupper(c) || l_islower(c)) |
45 | 2.14M | #define l_isdigit(c) ('0' <= (c) && (c) <= '9') |
46 | | #define l_isxdigit(c) \ |
47 | 360k | (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f')) |
48 | | |
49 | | /* Read one byte from stream, convert to unsigned char, then int, and |
50 | | return. return EOF on end of file. This corresponds to the |
51 | | behaviour of fgetc(). */ |
52 | | typedef int (*get_func)(void *data); |
53 | | |
54 | | typedef struct { |
55 | | get_func get; |
56 | | void *data; |
57 | | char buffer[5]; |
58 | | size_t buffer_pos; |
59 | | int state; |
60 | | int line; |
61 | | int column, last_column; |
62 | | size_t position; |
63 | | } stream_t; |
64 | | |
65 | | typedef struct { |
66 | | stream_t stream; |
67 | | strbuffer_t saved_text; |
68 | | size_t flags; |
69 | | size_t depth; |
70 | | int token; |
71 | | union { |
72 | | struct { |
73 | | char *val; |
74 | | size_t len; |
75 | | } string; |
76 | | json_int_t integer; |
77 | | double real; |
78 | | } value; |
79 | | } lex_t; |
80 | | |
81 | 270 | #define stream_to_lex(stream) container_of(stream, lex_t, stream) |
82 | | |
83 | | /*** error reporting ***/ |
84 | | |
85 | | static void error_set(json_error_t *error, const lex_t *lex, enum json_error_code code, |
86 | 2.20k | const char *msg, ...) { |
87 | 2.20k | va_list ap; |
88 | 2.20k | char msg_text[JSON_ERROR_TEXT_LENGTH]; |
89 | 2.20k | char msg_with_context[JSON_ERROR_TEXT_LENGTH]; |
90 | | |
91 | 2.20k | int line = -1, col = -1; |
92 | 2.20k | size_t pos = 0; |
93 | 2.20k | const char *result = msg_text; |
94 | | |
95 | 2.20k | if (!error) |
96 | 306 | return; |
97 | | |
98 | 2.20k | va_start(ap, msg); |
99 | 1.90k | vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); |
100 | 1.90k | msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; |
101 | 1.90k | va_end(ap); |
102 | | |
103 | 1.90k | if (lex) { |
104 | 1.90k | const char *saved_text = strbuffer_value(&lex->saved_text); |
105 | | |
106 | 1.90k | line = lex->stream.line; |
107 | 1.90k | col = lex->stream.column; |
108 | 1.90k | pos = lex->stream.position; |
109 | | |
110 | 1.90k | if (saved_text && saved_text[0]) { |
111 | 1.58k | if (lex->saved_text.length <= 20) { |
112 | 1.40k | snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", |
113 | 1.40k | msg_text, saved_text); |
114 | 1.40k | msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; |
115 | 1.40k | result = msg_with_context; |
116 | 1.40k | } |
117 | 1.58k | } else { |
118 | 320 | if (code == json_error_invalid_syntax) { |
119 | | /* More specific error code for premature end of file. */ |
120 | 256 | code = json_error_premature_end_of_input; |
121 | 256 | } |
122 | 320 | if (lex->stream.state == STREAM_STATE_ERROR) { |
123 | | /* No context for UTF-8 decoding errors */ |
124 | 132 | result = msg_text; |
125 | 188 | } else { |
126 | 188 | snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", |
127 | 188 | msg_text); |
128 | 188 | msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; |
129 | 188 | result = msg_with_context; |
130 | 188 | } |
131 | 320 | } |
132 | 1.90k | } |
133 | | |
134 | 1.90k | jsonp_error_set(error, line, col, pos, code, "%s", result); |
135 | 1.90k | } |
136 | | |
137 | | /*** lexical analyzer ***/ |
138 | | |
139 | 33.0k | static void stream_init(stream_t *stream, get_func get, void *data) { |
140 | 33.0k | stream->get = get; |
141 | 33.0k | stream->data = data; |
142 | 33.0k | stream->buffer[0] = '\0'; |
143 | 33.0k | stream->buffer_pos = 0; |
144 | | |
145 | 33.0k | stream->state = STREAM_STATE_OK; |
146 | 33.0k | stream->line = 1; |
147 | 33.0k | stream->column = 0; |
148 | 33.0k | stream->position = 0; |
149 | 33.0k | } |
150 | | |
151 | 83.7M | static int stream_get(stream_t *stream, json_error_t *error) { |
152 | 83.7M | int c; |
153 | | |
154 | 83.7M | if (stream->state != STREAM_STATE_OK) |
155 | 44 | return stream->state; |
156 | | |
157 | 83.7M | if (!stream->buffer[stream->buffer_pos]) { |
158 | 81.5M | c = stream->get(stream->data); |
159 | 81.5M | if (c == EOF) { |
160 | 32.0k | stream->state = STREAM_STATE_EOF; |
161 | 32.0k | return STREAM_STATE_EOF; |
162 | 32.0k | } |
163 | | |
164 | 81.5M | stream->buffer[0] = c; |
165 | 81.5M | stream->buffer_pos = 0; |
166 | | |
167 | 81.5M | if (0x80 <= c && c <= 0xFF) { |
168 | | /* multi-byte UTF-8 sequence */ |
169 | 698k | size_t i, count; |
170 | | |
171 | 698k | count = utf8_check_first(c); |
172 | 698k | if (!count) |
173 | 130 | goto out; |
174 | | |
175 | 698k | assert(count >= 2); |
176 | | |
177 | 2.73M | for (i = 1; i < count; i++) |
178 | 2.03M | stream->buffer[i] = stream->get(stream->data); |
179 | | |
180 | 698k | if (!utf8_check_full(stream->buffer, count, NULL)) |
181 | 140 | goto out; |
182 | | |
183 | 698k | stream->buffer[count] = '\0'; |
184 | 698k | } else |
185 | 80.8M | stream->buffer[1] = '\0'; |
186 | 81.5M | } |
187 | | |
188 | 83.7M | c = stream->buffer[stream->buffer_pos++]; |
189 | | |
190 | 83.7M | stream->position++; |
191 | 83.7M | if (c == '\n') { |
192 | 2.17k | stream->line++; |
193 | 2.17k | stream->last_column = stream->column; |
194 | 2.17k | stream->column = 0; |
195 | 83.7M | } else if (utf8_check_first(c)) { |
196 | | /* track the Unicode character column, so increment only if |
197 | | this is the first character of a UTF-8 sequence */ |
198 | 81.6M | stream->column++; |
199 | 81.6M | } |
200 | | |
201 | 83.7M | return c; |
202 | | |
203 | 270 | out: |
204 | 270 | stream->state = STREAM_STATE_ERROR; |
205 | 270 | error_set(error, stream_to_lex(stream), json_error_invalid_utf8, |
206 | 270 | "unable to decode byte 0x%x", c); |
207 | 270 | return STREAM_STATE_ERROR; |
208 | 83.7M | } |
209 | | |
210 | 110k | static void stream_unget(stream_t *stream, int c) { |
211 | 110k | if (c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR) |
212 | 9 | return; |
213 | | |
214 | 110k | stream->position--; |
215 | 110k | if (c == '\n') { |
216 | 71 | stream->line--; |
217 | 71 | stream->column = stream->last_column; |
218 | 110k | } else if (utf8_check_first(c)) |
219 | 110k | stream->column--; |
220 | | |
221 | 110k | assert(stream->buffer_pos > 0); |
222 | 110k | stream->buffer_pos--; |
223 | 110k | assert(stream->buffer[stream->buffer_pos] == c); |
224 | 110k | } |
225 | | |
226 | 1.29M | static int lex_get(lex_t *lex, json_error_t *error) { |
227 | 1.29M | return stream_get(&lex->stream, error); |
228 | 1.29M | } |
229 | | |
230 | 83.6M | static void lex_save(lex_t *lex, int c) { strbuffer_append_byte(&lex->saved_text, c); } |
231 | | |
232 | 82.4M | static int lex_get_save(lex_t *lex, json_error_t *error) { |
233 | 82.4M | int c = stream_get(&lex->stream, error); |
234 | 82.4M | if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) |
235 | 82.4M | lex_save(lex, c); |
236 | 82.4M | return c; |
237 | 82.4M | } |
238 | | |
239 | 27 | static void lex_unget(lex_t *lex, int c) { stream_unget(&lex->stream, c); } |
240 | | |
241 | 111k | static void lex_unget_unsave(lex_t *lex, int c) { |
242 | 111k | if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { |
243 | | /* Since we treat warnings as errors, when assertions are turned |
244 | | * off the "d" variable would be set but never used. Which is |
245 | | * treated as an error by GCC. |
246 | | */ |
247 | 110k | #ifndef NDEBUG |
248 | 110k | char d; |
249 | 110k | #endif |
250 | 110k | stream_unget(&lex->stream, c); |
251 | 110k | #ifndef NDEBUG |
252 | 110k | d = |
253 | 110k | #endif |
254 | 110k | strbuffer_pop(&lex->saved_text); |
255 | 110k | assert(c == d); |
256 | 110k | } |
257 | 111k | } |
258 | | |
259 | 176 | static void lex_save_cached(lex_t *lex) { |
260 | 271 | while (lex->stream.buffer[lex->stream.buffer_pos] != '\0') { |
261 | 95 | lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); |
262 | 95 | lex->stream.buffer_pos++; |
263 | 95 | lex->stream.position++; |
264 | 95 | } |
265 | 176 | } |
266 | | |
267 | 425k | static void lex_free_string(lex_t *lex) { |
268 | 425k | jsonp_free(lex->value.string.val); |
269 | 425k | lex->value.string.val = NULL; |
270 | 425k | lex->value.string.len = 0; |
271 | 425k | } |
272 | | |
273 | | /* assumes that str points to 'u' plus at least 4 valid hex digits */ |
274 | 89.9k | static int32_t decode_unicode_escape(const char *str) { |
275 | 89.9k | int i; |
276 | 89.9k | int32_t value = 0; |
277 | | |
278 | 89.9k | assert(str[0] == 'u'); |
279 | | |
280 | 449k | for (i = 1; i <= 4; i++) { |
281 | 359k | char c = str[i]; |
282 | 359k | value <<= 4; |
283 | 359k | if (l_isdigit(c)) |
284 | 103k | value += c - '0'; |
285 | 256k | else if (l_islower(c)) |
286 | 99.0k | value += c - 'a' + 10; |
287 | 157k | else if (l_isupper(c)) |
288 | 157k | value += c - 'A' + 10; |
289 | 0 | else |
290 | 0 | return -1; |
291 | 359k | } |
292 | | |
293 | 89.9k | return value; |
294 | 89.9k | } |
295 | | |
296 | 425k | static void lex_scan_string(lex_t *lex, json_error_t *error) { |
297 | 425k | int c; |
298 | 425k | const char *p; |
299 | 425k | char *t; |
300 | 425k | int i; |
301 | | |
302 | 425k | lex->value.string.val = NULL; |
303 | 425k | lex->token = TOKEN_INVALID; |
304 | | |
305 | 425k | c = lex_get_save(lex, error); |
306 | | |
307 | 80.3M | while (c != '"') { |
308 | 79.9M | if (c == STREAM_STATE_ERROR) |
309 | 81 | goto out; |
310 | | |
311 | 79.9M | else if (c == STREAM_STATE_EOF) { |
312 | 105 | error_set(error, lex, json_error_premature_end_of_input, |
313 | 105 | "premature end of input"); |
314 | 105 | goto out; |
315 | 105 | } |
316 | | |
317 | 79.9M | else if (0 <= c && c <= 0x1F) { |
318 | | /* control character */ |
319 | 40 | lex_unget_unsave(lex, c); |
320 | 40 | if (c == '\n') |
321 | 5 | error_set(error, lex, json_error_invalid_syntax, "unexpected newline"); |
322 | 35 | else |
323 | 35 | error_set(error, lex, json_error_invalid_syntax, "control character 0x%x", |
324 | 35 | c); |
325 | 40 | goto out; |
326 | 40 | } |
327 | | |
328 | 79.9M | else if (c == '\\') { |
329 | 904k | c = lex_get_save(lex, error); |
330 | 904k | if (c == 'u') { |
331 | 90.2k | c = lex_get_save(lex, error); |
332 | 451k | for (i = 0; i < 4; i++) { |
333 | 360k | if (!l_isxdigit(c)) { |
334 | 63 | error_set(error, lex, json_error_invalid_syntax, |
335 | 63 | "invalid escape"); |
336 | 63 | goto out; |
337 | 63 | } |
338 | 360k | c = lex_get_save(lex, error); |
339 | 360k | } |
340 | 813k | } else if (c == '"' || c == '\\' || c == '/' || c == 'b' || c == 'f' || |
341 | 435k | c == 'n' || c == 'r' || c == 't') |
342 | 813k | c = lex_get_save(lex, error); |
343 | 70 | else { |
344 | 70 | error_set(error, lex, json_error_invalid_syntax, "invalid escape"); |
345 | 70 | goto out; |
346 | 70 | } |
347 | 904k | } else |
348 | 79.0M | c = lex_get_save(lex, error); |
349 | 79.9M | } |
350 | | |
351 | | /* the actual value is at most of the same length as the source |
352 | | string, because: |
353 | | - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte |
354 | | - a single \uXXXX escape (length 6) is converted to at most 3 bytes |
355 | | - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair |
356 | | are converted to 4 bytes |
357 | | */ |
358 | 425k | t = jsonp_malloc(lex->saved_text.length + 1); |
359 | 425k | if (!t) { |
360 | | /* this is not very nice, since TOKEN_INVALID is returned */ |
361 | 0 | goto out; |
362 | 0 | } |
363 | 425k | lex->value.string.val = t; |
364 | | |
365 | | /* + 1 to skip the " */ |
366 | 425k | p = strbuffer_value(&lex->saved_text) + 1; |
367 | | |
368 | 77.9M | while (*p != '"') { |
369 | 77.4M | if (*p == '\\') { |
370 | 869k | p++; |
371 | 869k | if (*p == 'u') { |
372 | 88.4k | size_t length; |
373 | 88.4k | int32_t value; |
374 | | |
375 | 88.4k | value = decode_unicode_escape(p); |
376 | 88.4k | if (value < 0) { |
377 | 0 | error_set(error, lex, json_error_invalid_syntax, |
378 | 0 | "invalid Unicode escape '%.6s'", p - 1); |
379 | 0 | goto out; |
380 | 0 | } |
381 | 88.4k | p += 5; |
382 | | |
383 | 88.4k | if (0xD800 <= value && value <= 0xDBFF) { |
384 | | /* surrogate pair */ |
385 | 1.53k | if (*p == '\\' && *(p + 1) == 'u') { |
386 | 1.51k | int32_t value2 = decode_unicode_escape(++p); |
387 | 1.51k | if (value2 < 0) { |
388 | 0 | error_set(error, lex, json_error_invalid_syntax, |
389 | 0 | "invalid Unicode escape '%.6s'", p - 1); |
390 | 0 | goto out; |
391 | 0 | } |
392 | 1.51k | p += 5; |
393 | | |
394 | 1.51k | if (0xDC00 <= value2 && value2 <= 0xDFFF) { |
395 | | /* valid second surrogate */ |
396 | 1.47k | value = |
397 | 1.47k | ((value - 0xD800) << 10) + (value2 - 0xDC00) + 0x10000; |
398 | 1.47k | } else { |
399 | | /* invalid second surrogate */ |
400 | 36 | error_set(error, lex, json_error_invalid_syntax, |
401 | 36 | "invalid Unicode '\\u%04X\\u%04X'", value, value2); |
402 | 36 | goto out; |
403 | 36 | } |
404 | 1.51k | } else { |
405 | | /* no second surrogate */ |
406 | 26 | error_set(error, lex, json_error_invalid_syntax, |
407 | 26 | "invalid Unicode '\\u%04X'", value); |
408 | 26 | goto out; |
409 | 26 | } |
410 | 86.8k | } else if (0xDC00 <= value && value <= 0xDFFF) { |
411 | 12 | error_set(error, lex, json_error_invalid_syntax, |
412 | 12 | "invalid Unicode '\\u%04X'", value); |
413 | 12 | goto out; |
414 | 12 | } |
415 | | |
416 | 88.3k | if (utf8_encode(value, t, &length)) |
417 | 88.3k | assert(0); |
418 | 88.3k | t += length; |
419 | 780k | } else { |
420 | 780k | switch (*p) { |
421 | 6.24k | case '"': |
422 | 346k | case '\\': |
423 | 353k | case '/': |
424 | 353k | *t = *p; |
425 | 353k | break; |
426 | 2.19k | case 'b': |
427 | 2.19k | *t = '\b'; |
428 | 2.19k | break; |
429 | 4.98k | case 'f': |
430 | 4.98k | *t = '\f'; |
431 | 4.98k | break; |
432 | 4.91k | case 'n': |
433 | 4.91k | *t = '\n'; |
434 | 4.91k | break; |
435 | 5.46k | case 'r': |
436 | 5.46k | *t = '\r'; |
437 | 5.46k | break; |
438 | 409k | case 't': |
439 | 409k | *t = '\t'; |
440 | 409k | break; |
441 | 0 | default: |
442 | 0 | assert(0); |
443 | 780k | } |
444 | 780k | t++; |
445 | 780k | p++; |
446 | 780k | } |
447 | 869k | } else |
448 | 76.6M | *(t++) = *(p++); |
449 | 77.4M | } |
450 | 425k | *t = '\0'; |
451 | 425k | lex->value.string.len = t - lex->value.string.val; |
452 | 425k | lex->token = TOKEN_STRING; |
453 | 425k | return; |
454 | | |
455 | 433 | out: |
456 | 433 | lex_free_string(lex); |
457 | 433 | } |
458 | | |
459 | | #ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ |
460 | | #if JSON_INTEGER_IS_LONG_LONG |
461 | | #ifdef _MSC_VER /* Microsoft Visual Studio */ |
462 | | #define json_strtoint _strtoi64 |
463 | | #else |
464 | 82.6k | #define json_strtoint strtoll |
465 | | #endif |
466 | | #else |
467 | | #define json_strtoint strtol |
468 | | #endif |
469 | | #endif |
470 | | |
471 | 110k | static int lex_scan_number(lex_t *lex, int c, json_error_t *error) { |
472 | 110k | const char *saved_text; |
473 | 110k | char *end; |
474 | 110k | double doubleval; |
475 | | |
476 | 110k | lex->token = TOKEN_INVALID; |
477 | | |
478 | 110k | if (c == '-') |
479 | 9.16k | c = lex_get_save(lex, error); |
480 | | |
481 | 110k | if (c == '0') { |
482 | 65.3k | c = lex_get_save(lex, error); |
483 | 65.3k | if (l_isdigit(c)) { |
484 | 10 | lex_unget_unsave(lex, c); |
485 | 10 | goto out; |
486 | 10 | } |
487 | 65.3k | } else if (l_isdigit(c)) { |
488 | 44.9k | do |
489 | 418k | c = lex_get_save(lex, error); |
490 | 418k | while (l_isdigit(c)); |
491 | 44.9k | } else { |
492 | 49 | lex_unget_unsave(lex, c); |
493 | 49 | goto out; |
494 | 49 | } |
495 | | |
496 | 110k | if (!(lex->flags & JSON_DECODE_INT_AS_REAL) && c != '.' && c != 'E' && c != 'e') { |
497 | 82.6k | json_int_t intval; |
498 | | |
499 | 82.6k | lex_unget_unsave(lex, c); |
500 | | |
501 | 82.6k | saved_text = strbuffer_value(&lex->saved_text); |
502 | | |
503 | 82.6k | errno = 0; |
504 | 82.6k | intval = json_strtoint(saved_text, &end, 10); |
505 | 82.6k | if (errno == ERANGE) { |
506 | 3 | if (intval < 0) |
507 | 1 | error_set(error, lex, json_error_numeric_overflow, |
508 | 1 | "too big negative integer"); |
509 | 2 | else |
510 | 2 | error_set(error, lex, json_error_numeric_overflow, "too big integer"); |
511 | 3 | goto out; |
512 | 3 | } |
513 | | |
514 | 82.6k | assert(end == saved_text + lex->saved_text.length); |
515 | | |
516 | 82.6k | lex->token = TOKEN_INTEGER; |
517 | 82.6k | lex->value.integer = intval; |
518 | 82.6k | return 0; |
519 | 82.6k | } |
520 | | |
521 | 27.5k | if (c == '.') { |
522 | 19.7k | c = lex_get(lex, error); |
523 | 19.7k | if (!l_isdigit(c)) { |
524 | 27 | lex_unget(lex, c); |
525 | 27 | goto out; |
526 | 27 | } |
527 | 19.7k | lex_save(lex, c); |
528 | | |
529 | 19.7k | do |
530 | 193k | c = lex_get_save(lex, error); |
531 | 193k | while (l_isdigit(c)); |
532 | 19.7k | } |
533 | | |
534 | 27.5k | if (c == 'E' || c == 'e') { |
535 | 21.3k | c = lex_get_save(lex, error); |
536 | 21.3k | if (c == '+' || c == '-') |
537 | 2.08k | c = lex_get_save(lex, error); |
538 | | |
539 | 21.3k | if (!l_isdigit(c)) { |
540 | 69 | lex_unget_unsave(lex, c); |
541 | 69 | goto out; |
542 | 69 | } |
543 | | |
544 | 21.3k | do |
545 | 73.2k | c = lex_get_save(lex, error); |
546 | 73.2k | while (l_isdigit(c)); |
547 | 21.3k | } |
548 | | |
549 | 27.4k | lex_unget_unsave(lex, c); |
550 | | |
551 | 27.4k | if (jsonp_strtod(&lex->saved_text, &doubleval)) { |
552 | 9 | error_set(error, lex, json_error_numeric_overflow, "real number overflow"); |
553 | 9 | goto out; |
554 | 9 | } |
555 | | |
556 | 27.4k | lex->token = TOKEN_REAL; |
557 | 27.4k | lex->value.real = doubleval; |
558 | 27.4k | return 0; |
559 | | |
560 | 167 | out: |
561 | 167 | return -1; |
562 | 27.4k | } |
563 | | |
564 | 1.23M | static int lex_scan(lex_t *lex, json_error_t *error) { |
565 | 1.23M | int c; |
566 | | |
567 | 1.23M | strbuffer_clear(&lex->saved_text); |
568 | | |
569 | 1.23M | if (lex->token == TOKEN_STRING) |
570 | 425k | lex_free_string(lex); |
571 | | |
572 | 1.23M | do |
573 | 1.27M | c = lex_get(lex, error); |
574 | 1.27M | while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); |
575 | | |
576 | 1.23M | if (c == STREAM_STATE_EOF) { |
577 | 31.7k | lex->token = TOKEN_EOF; |
578 | 31.7k | goto out; |
579 | 31.7k | } |
580 | | |
581 | 1.19M | if (c == STREAM_STATE_ERROR) { |
582 | 93 | lex->token = TOKEN_INVALID; |
583 | 93 | goto out; |
584 | 93 | } |
585 | | |
586 | 1.19M | lex_save(lex, c); |
587 | | |
588 | 1.19M | if (c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') |
589 | 661k | lex->token = c; |
590 | | |
591 | 536k | else if (c == '"') |
592 | 425k | lex_scan_string(lex, error); |
593 | | |
594 | 111k | else if (l_isdigit(c) || c == '-') { |
595 | 110k | if (lex_scan_number(lex, c, error)) |
596 | 167 | goto out; |
597 | 110k | } |
598 | | |
599 | 887 | else if (l_isalpha(c)) { |
600 | | /* eat up the whole identifier for clearer error messages */ |
601 | 711 | const char *saved_text; |
602 | | |
603 | 711 | do |
604 | 3.90k | c = lex_get_save(lex, error); |
605 | 3.90k | while (l_isalpha(c)); |
606 | 711 | lex_unget_unsave(lex, c); |
607 | | |
608 | 711 | saved_text = strbuffer_value(&lex->saved_text); |
609 | | |
610 | 711 | if (strcmp(saved_text, "true") == 0) |
611 | 436 | lex->token = TOKEN_TRUE; |
612 | 275 | else if (strcmp(saved_text, "false") == 0) |
613 | 3 | lex->token = TOKEN_FALSE; |
614 | 272 | else if (strcmp(saved_text, "null") == 0) |
615 | 5 | lex->token = TOKEN_NULL; |
616 | 267 | else |
617 | 267 | lex->token = TOKEN_INVALID; |
618 | 711 | } |
619 | | |
620 | 176 | else { |
621 | | /* save the rest of the input UTF-8 sequence to get an error |
622 | | message of valid UTF-8 */ |
623 | 176 | lex_save_cached(lex); |
624 | 176 | lex->token = TOKEN_INVALID; |
625 | 176 | } |
626 | | |
627 | 1.23M | out: |
628 | 1.23M | return lex->token; |
629 | 1.19M | } |
630 | | |
631 | 254k | static char *lex_steal_string(lex_t *lex, size_t *out_len) { |
632 | 254k | char *result = NULL; |
633 | 254k | if (lex->token == TOKEN_STRING) { |
634 | 254k | result = lex->value.string.val; |
635 | 254k | *out_len = lex->value.string.len; |
636 | 254k | lex->value.string.val = NULL; |
637 | 254k | lex->value.string.len = 0; |
638 | 254k | } |
639 | 254k | return result; |
640 | 254k | } |
641 | | |
642 | 33.0k | static int lex_init(lex_t *lex, get_func get, size_t flags, void *data) { |
643 | 33.0k | stream_init(&lex->stream, get, data); |
644 | 33.0k | if (strbuffer_init(&lex->saved_text)) |
645 | 0 | return -1; |
646 | | |
647 | 33.0k | lex->flags = flags; |
648 | 33.0k | lex->token = TOKEN_INVALID; |
649 | 33.0k | return 0; |
650 | 33.0k | } |
651 | | |
652 | 33.0k | static void lex_close(lex_t *lex) { |
653 | 33.0k | if (lex->token == TOKEN_STRING) |
654 | 12 | lex_free_string(lex); |
655 | 33.0k | strbuffer_close(&lex->saved_text); |
656 | 33.0k | } |
657 | | |
658 | | /*** parser ***/ |
659 | | |
660 | | static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error); |
661 | | |
662 | 33.2k | static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error) { |
663 | 33.2k | json_t *object = json_object(); |
664 | 33.2k | if (!object) |
665 | 0 | return NULL; |
666 | | |
667 | 33.2k | lex_scan(lex, error); |
668 | 33.2k | if (lex->token == '}') |
669 | 31 | return object; |
670 | | |
671 | 255k | while (1) { |
672 | 255k | char *key; |
673 | 255k | size_t len; |
674 | 255k | json_t *value; |
675 | | |
676 | 255k | if (lex->token != TOKEN_STRING) { |
677 | 838 | error_set(error, lex, json_error_invalid_syntax, "string or '}' expected"); |
678 | 838 | goto error; |
679 | 838 | } |
680 | | |
681 | 254k | key = lex_steal_string(lex, &len); |
682 | 254k | if (!key) |
683 | 0 | return NULL; |
684 | 254k | if (memchr(key, '\0', len)) { |
685 | 3 | jsonp_free(key); |
686 | 3 | error_set(error, lex, json_error_null_byte_in_key, |
687 | 3 | "NUL byte in object key not supported"); |
688 | 3 | goto error; |
689 | 3 | } |
690 | | |
691 | 254k | if (flags & JSON_REJECT_DUPLICATES) { |
692 | 0 | if (json_object_getn(object, key, len)) { |
693 | 0 | jsonp_free(key); |
694 | 0 | error_set(error, lex, json_error_duplicate_key, "duplicate object key"); |
695 | 0 | goto error; |
696 | 0 | } |
697 | 0 | } |
698 | | |
699 | 254k | lex_scan(lex, error); |
700 | 254k | if (lex->token != ':') { |
701 | 183 | jsonp_free(key); |
702 | 183 | error_set(error, lex, json_error_invalid_syntax, "':' expected"); |
703 | 183 | goto error; |
704 | 183 | } |
705 | | |
706 | 254k | lex_scan(lex, error); |
707 | 254k | value = parse_value(lex, flags, error); |
708 | 254k | if (!value) { |
709 | 559 | jsonp_free(key); |
710 | 559 | goto error; |
711 | 559 | } |
712 | | |
713 | 253k | if (json_object_setn_new_nocheck(object, key, len, value)) { |
714 | 0 | jsonp_free(key); |
715 | 0 | goto error; |
716 | 0 | } |
717 | | |
718 | 253k | jsonp_free(key); |
719 | | |
720 | 253k | lex_scan(lex, error); |
721 | 253k | if (lex->token != ',') |
722 | 31.6k | break; |
723 | | |
724 | 222k | lex_scan(lex, error); |
725 | 222k | } |
726 | | |
727 | 31.6k | if (lex->token != '}') { |
728 | 113 | error_set(error, lex, json_error_invalid_syntax, "'}' expected"); |
729 | 113 | goto error; |
730 | 113 | } |
731 | | |
732 | 31.5k | return object; |
733 | | |
734 | 1.69k | error: |
735 | 1.69k | json_decref(object); |
736 | 1.69k | return NULL; |
737 | 31.6k | } |
738 | | |
739 | 63.8k | static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error) { |
740 | 63.8k | json_t *array = json_array(); |
741 | 63.8k | if (!array) |
742 | 0 | return NULL; |
743 | | |
744 | 63.8k | lex_scan(lex, error); |
745 | 63.8k | if (lex->token == ']') |
746 | 518 | return array; |
747 | | |
748 | 91.2k | while (lex->token) { |
749 | 91.2k | json_t *elem = parse_value(lex, flags, error); |
750 | 91.2k | if (!elem) |
751 | 35.5k | goto error; |
752 | | |
753 | 55.6k | if (json_array_append_new(array, elem)) { |
754 | 0 | goto error; |
755 | 0 | } |
756 | | |
757 | 55.6k | lex_scan(lex, error); |
758 | 55.6k | if (lex->token != ',') |
759 | 27.7k | break; |
760 | | |
761 | 27.9k | lex_scan(lex, error); |
762 | 27.9k | } |
763 | | |
764 | 27.8k | if (lex->token != ']') { |
765 | 113 | error_set(error, lex, json_error_invalid_syntax, "']' expected"); |
766 | 113 | goto error; |
767 | 113 | } |
768 | | |
769 | 27.7k | return array; |
770 | | |
771 | 35.6k | error: |
772 | 35.6k | json_decref(array); |
773 | 35.6k | return NULL; |
774 | 27.8k | } |
775 | | |
776 | 378k | static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) { |
777 | 378k | json_t *json; |
778 | | |
779 | 378k | lex->depth++; |
780 | 378k | if (lex->depth > JSON_PARSER_MAX_DEPTH) { |
781 | 1 | error_set(error, lex, json_error_stack_overflow, "maximum parsing depth reached"); |
782 | 1 | return NULL; |
783 | 1 | } |
784 | | |
785 | 378k | switch (lex->token) { |
786 | 170k | case TOKEN_STRING: { |
787 | 170k | const char *value = lex->value.string.val; |
788 | 170k | size_t len = lex->value.string.len; |
789 | | |
790 | 170k | if (!(flags & JSON_ALLOW_NUL)) { |
791 | 170k | if (memchr(value, '\0', len)) { |
792 | 1 | error_set(error, lex, json_error_null_character, |
793 | 1 | "\\u0000 is not allowed without JSON_ALLOW_NUL"); |
794 | 1 | return NULL; |
795 | 1 | } |
796 | 170k | } |
797 | | |
798 | 170k | json = jsonp_stringn_nocheck_own(value, len); |
799 | 170k | lex->value.string.val = NULL; |
800 | 170k | lex->value.string.len = 0; |
801 | 170k | break; |
802 | 170k | } |
803 | | |
804 | 82.5k | case TOKEN_INTEGER: { |
805 | 82.5k | json = json_integer(lex->value.integer); |
806 | 82.5k | break; |
807 | 170k | } |
808 | | |
809 | 27.4k | case TOKEN_REAL: { |
810 | 27.4k | json = json_real(lex->value.real); |
811 | 27.4k | break; |
812 | 170k | } |
813 | | |
814 | 435 | case TOKEN_TRUE: |
815 | 435 | json = json_true(); |
816 | 435 | break; |
817 | | |
818 | 2 | case TOKEN_FALSE: |
819 | 2 | json = json_false(); |
820 | 2 | break; |
821 | | |
822 | 1 | case TOKEN_NULL: |
823 | 1 | json = json_null(); |
824 | 1 | break; |
825 | | |
826 | 33.2k | case '{': |
827 | 33.2k | json = parse_object(lex, flags, error); |
828 | 33.2k | break; |
829 | | |
830 | 63.8k | case '[': |
831 | 63.8k | json = parse_array(lex, flags, error); |
832 | 63.8k | break; |
833 | | |
834 | 121 | case TOKEN_INVALID: |
835 | 121 | error_set(error, lex, json_error_invalid_syntax, "invalid token"); |
836 | 121 | return NULL; |
837 | | |
838 | 21 | default: |
839 | 21 | error_set(error, lex, json_error_invalid_syntax, "unexpected token"); |
840 | 21 | return NULL; |
841 | 378k | } |
842 | | |
843 | 378k | if (!json) |
844 | 37.3k | return NULL; |
845 | | |
846 | 340k | lex->depth--; |
847 | 340k | return json; |
848 | 378k | } |
849 | | |
850 | 33.0k | static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) { |
851 | 33.0k | json_t *result; |
852 | | |
853 | 33.0k | lex->depth = 0; |
854 | | |
855 | 33.0k | lex_scan(lex, error); |
856 | 33.0k | if (!(flags & JSON_DECODE_ANY)) { |
857 | 33.0k | if (lex->token != '[' && lex->token != '{') { |
858 | 170 | error_set(error, lex, json_error_invalid_syntax, "'[' or '{' expected"); |
859 | 170 | return NULL; |
860 | 170 | } |
861 | 33.0k | } |
862 | | |
863 | 32.9k | result = parse_value(lex, flags, error); |
864 | 32.9k | if (!result) |
865 | 1.39k | return NULL; |
866 | | |
867 | 31.5k | if (!(flags & JSON_DISABLE_EOF_CHECK)) { |
868 | 31.5k | lex_scan(lex, error); |
869 | 31.5k | if (lex->token != TOKEN_EOF) { |
870 | 8 | error_set(error, lex, json_error_end_of_input_expected, |
871 | 8 | "end of file expected"); |
872 | 8 | json_decref(result); |
873 | 8 | return NULL; |
874 | 8 | } |
875 | 31.5k | } |
876 | | |
877 | 31.5k | if (error) { |
878 | | /* Save the position even though there was no error */ |
879 | 27.9k | error->position = (int)lex->stream.position; |
880 | 27.9k | } |
881 | | |
882 | 31.5k | return result; |
883 | 31.5k | } |
884 | | |
885 | | typedef struct { |
886 | | const char *data; |
887 | | size_t pos; |
888 | | } string_data_t; |
889 | | |
890 | 83.3M | static int string_get(void *data) { |
891 | 83.3M | char c; |
892 | 83.3M | string_data_t *stream = (string_data_t *)data; |
893 | 83.3M | c = stream->data[stream->pos]; |
894 | 83.3M | if (c == '\0') |
895 | 21.6k | return EOF; |
896 | 83.3M | else { |
897 | 83.3M | stream->pos++; |
898 | 83.3M | return (unsigned char)c; |
899 | 83.3M | } |
900 | 83.3M | } |
901 | | |
902 | 22.4k | json_t *json_loads(const char *string, size_t flags, json_error_t *error) { |
903 | 22.4k | lex_t lex; |
904 | 22.4k | json_t *result; |
905 | 22.4k | string_data_t stream_data; |
906 | | |
907 | 22.4k | jsonp_error_init(error, "<string>"); |
908 | | |
909 | 22.4k | if (string == NULL) { |
910 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
911 | 0 | return NULL; |
912 | 0 | } |
913 | | |
914 | 22.4k | stream_data.data = string; |
915 | 22.4k | stream_data.pos = 0; |
916 | | |
917 | 22.4k | if (lex_init(&lex, string_get, flags, (void *)&stream_data)) |
918 | 0 | return NULL; |
919 | | |
920 | 22.4k | result = parse_json(&lex, flags, error); |
921 | | |
922 | 22.4k | lex_close(&lex); |
923 | 22.4k | return result; |
924 | 22.4k | } |
925 | | |
926 | | typedef struct { |
927 | | const char *data; |
928 | | size_t len; |
929 | | size_t pos; |
930 | | } buffer_data_t; |
931 | | |
932 | 284k | static int buffer_get(void *data) { |
933 | 284k | char c; |
934 | 284k | buffer_data_t *stream = data; |
935 | 284k | if (stream->pos >= stream->len) |
936 | 10.5k | return EOF; |
937 | | |
938 | 273k | c = stream->data[stream->pos]; |
939 | 273k | stream->pos++; |
940 | 273k | return (unsigned char)c; |
941 | 284k | } |
942 | | |
943 | 10.6k | json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) { |
944 | 10.6k | lex_t lex; |
945 | 10.6k | json_t *result; |
946 | 10.6k | buffer_data_t stream_data; |
947 | | |
948 | 10.6k | jsonp_error_init(error, "<buffer>"); |
949 | | |
950 | 10.6k | if (buffer == NULL) { |
951 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
952 | 0 | return NULL; |
953 | 0 | } |
954 | | |
955 | 10.6k | stream_data.data = buffer; |
956 | 10.6k | stream_data.pos = 0; |
957 | 10.6k | stream_data.len = buflen; |
958 | | |
959 | 10.6k | if (lex_init(&lex, buffer_get, flags, (void *)&stream_data)) |
960 | 0 | return NULL; |
961 | | |
962 | 10.6k | result = parse_json(&lex, flags, error); |
963 | | |
964 | 10.6k | lex_close(&lex); |
965 | 10.6k | return result; |
966 | 10.6k | } |
967 | | |
968 | 0 | json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { |
969 | 0 | lex_t lex; |
970 | 0 | const char *source; |
971 | 0 | json_t *result; |
972 | |
|
973 | 0 | if (input == stdin) |
974 | 0 | source = "<stdin>"; |
975 | 0 | else |
976 | 0 | source = "<stream>"; |
977 | |
|
978 | 0 | jsonp_error_init(error, source); |
979 | |
|
980 | 0 | if (input == NULL) { |
981 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
982 | 0 | return NULL; |
983 | 0 | } |
984 | | |
985 | 0 | if (lex_init(&lex, (get_func)fgetc, flags, input)) |
986 | 0 | return NULL; |
987 | | |
988 | 0 | result = parse_json(&lex, flags, error); |
989 | |
|
990 | 0 | lex_close(&lex); |
991 | 0 | return result; |
992 | 0 | } |
993 | | |
994 | 0 | static int fd_get_func(int *fd) { |
995 | 0 | #ifdef HAVE_UNISTD_H |
996 | 0 | uint8_t c; |
997 | 0 | if (read(*fd, &c, 1) == 1) |
998 | 0 | return c; |
999 | 0 | #endif |
1000 | 0 | return EOF; |
1001 | 0 | } |
1002 | | |
1003 | 0 | json_t *json_loadfd(int input, size_t flags, json_error_t *error) { |
1004 | 0 | lex_t lex; |
1005 | 0 | const char *source; |
1006 | 0 | json_t *result; |
1007 | |
|
1008 | 0 | #ifdef HAVE_UNISTD_H |
1009 | 0 | if (input == STDIN_FILENO) |
1010 | 0 | source = "<stdin>"; |
1011 | 0 | else |
1012 | 0 | #endif |
1013 | 0 | source = "<stream>"; |
1014 | |
|
1015 | 0 | jsonp_error_init(error, source); |
1016 | |
|
1017 | 0 | if (input < 0) { |
1018 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
1019 | 0 | return NULL; |
1020 | 0 | } |
1021 | | |
1022 | 0 | if (lex_init(&lex, (get_func)fd_get_func, flags, &input)) |
1023 | 0 | return NULL; |
1024 | | |
1025 | 0 | result = parse_json(&lex, flags, error); |
1026 | |
|
1027 | 0 | lex_close(&lex); |
1028 | 0 | return result; |
1029 | 0 | } |
1030 | | |
1031 | 0 | json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { |
1032 | 0 | json_t *result; |
1033 | 0 | FILE *fp; |
1034 | |
|
1035 | 0 | jsonp_error_init(error, path); |
1036 | |
|
1037 | 0 | if (path == NULL) { |
1038 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
1039 | 0 | return NULL; |
1040 | 0 | } |
1041 | | |
1042 | 0 | fp = fopen(path, "rb"); |
1043 | 0 | if (!fp) { |
1044 | 0 | error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", path, |
1045 | 0 | strerror(errno)); |
1046 | 0 | return NULL; |
1047 | 0 | } |
1048 | | |
1049 | 0 | result = json_loadf(fp, flags, error); |
1050 | |
|
1051 | 0 | fclose(fp); |
1052 | 0 | return result; |
1053 | 0 | } |
1054 | | |
1055 | 0 | #define MAX_BUF_LEN 1024 |
1056 | | |
1057 | | typedef struct { |
1058 | | char data[MAX_BUF_LEN]; |
1059 | | size_t len; |
1060 | | size_t pos; |
1061 | | json_load_callback_t callback; |
1062 | | void *arg; |
1063 | | } callback_data_t; |
1064 | | |
1065 | 0 | static int callback_get(void *data) { |
1066 | 0 | char c; |
1067 | 0 | callback_data_t *stream = data; |
1068 | |
|
1069 | 0 | if (stream->pos >= stream->len) { |
1070 | 0 | stream->pos = 0; |
1071 | 0 | stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg); |
1072 | 0 | if (stream->len == 0 || stream->len == (size_t)-1) |
1073 | 0 | return EOF; |
1074 | 0 | } |
1075 | | |
1076 | 0 | c = stream->data[stream->pos]; |
1077 | 0 | stream->pos++; |
1078 | 0 | return (unsigned char)c; |
1079 | 0 | } |
1080 | | |
1081 | | json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, |
1082 | 0 | json_error_t *error) { |
1083 | 0 | lex_t lex; |
1084 | 0 | json_t *result; |
1085 | |
|
1086 | 0 | callback_data_t stream_data; |
1087 | |
|
1088 | 0 | memset(&stream_data, 0, sizeof(stream_data)); |
1089 | 0 | stream_data.callback = callback; |
1090 | 0 | stream_data.arg = arg; |
1091 | |
|
1092 | 0 | jsonp_error_init(error, "<callback>"); |
1093 | |
|
1094 | 0 | if (callback == NULL) { |
1095 | 0 | error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); |
1096 | 0 | return NULL; |
1097 | 0 | } |
1098 | | |
1099 | 0 | if (lex_init(&lex, (get_func)callback_get, flags, &stream_data)) |
1100 | 0 | return NULL; |
1101 | | |
1102 | 0 | result = parse_json(&lex, flags, error); |
1103 | |
|
1104 | 0 | lex_close(&lex); |
1105 | 0 | return result; |
1106 | 0 | } |