1 | /* Lua CJSON - JSON support for Lua |
2 | * |
3 | * Copyright (c) 2010-2012 Mark Pulford <[email protected]> |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining |
6 | * a copy of this software and associated documentation files (the |
7 | * "Software"), to deal in the Software without restriction, including |
8 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * distribute, sublicense, and/or sell copies of the Software, and to |
10 | * permit persons to whom the Software is furnished to do so, subject to |
11 | * the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
19 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
20 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
23 | */ |
24 | |
25 | /* Caveats: |
26 | * - JSON "null" values are represented as lightuserdata since Lua |
27 | * tables cannot contain "nil". Compare with cjson.null. |
28 | * - Invalid UTF-8 characters are not detected and will be passed |
29 | * untouched. If required, UTF-8 error checking should be done |
30 | * outside this library. |
31 | * - Javascript comments are not part of the JSON spec, and are not |
32 | * currently supported. |
33 | * |
34 | * Note: Decoding is slower than encoding. Lua spends significant |
35 | * time (30%) managing tables when parsing JSON since it is |
36 | * difficult to know object/array sizes ahead of time. |
37 | */ |
38 | |
39 | #include <assert.h> |
40 | #include <string.h> |
41 | #include <math.h> |
42 | #include <limits.h> |
43 | #include "lua.h" |
44 | #include "lauxlib.h" |
45 | |
46 | #include "strbuf.h" |
47 | #include "fpconv.h" |
48 | |
49 | #include "../../../src/solarisfixes.h" |
50 | |
51 | #ifndef CJSON_MODNAME |
52 | #define CJSON_MODNAME "cjson" |
53 | #endif |
54 | |
55 | #ifndef CJSON_VERSION |
56 | #define CJSON_VERSION "2.1.0" |
57 | #endif |
58 | |
59 | /* Workaround for Solaris platforms missing isinf() */ |
60 | #if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF)) |
61 | #define isinf(x) (!isnan(x) && isnan((x) - (x))) |
62 | #endif |
63 | |
64 | #define DEFAULT_SPARSE_CONVERT 0 |
65 | #define DEFAULT_SPARSE_RATIO 2 |
66 | #define DEFAULT_SPARSE_SAFE 10 |
67 | #define DEFAULT_ENCODE_MAX_DEPTH 1000 |
68 | #define DEFAULT_DECODE_MAX_DEPTH 1000 |
69 | #define DEFAULT_ENCODE_INVALID_NUMBERS 0 |
70 | #define DEFAULT_DECODE_INVALID_NUMBERS 1 |
71 | #define DEFAULT_ENCODE_KEEP_BUFFER 1 |
72 | #define DEFAULT_ENCODE_NUMBER_PRECISION 14 |
73 | |
74 | #ifdef DISABLE_INVALID_NUMBERS |
75 | #undef DEFAULT_DECODE_INVALID_NUMBERS |
76 | #define DEFAULT_DECODE_INVALID_NUMBERS 0 |
77 | #endif |
78 | |
79 | typedef enum { |
80 | T_OBJ_BEGIN, |
81 | T_OBJ_END, |
82 | T_ARR_BEGIN, |
83 | T_ARR_END, |
84 | T_STRING, |
85 | T_NUMBER, |
86 | T_BOOLEAN, |
87 | T_NULL, |
88 | T_COLON, |
89 | T_COMMA, |
90 | T_END, |
91 | T_WHITESPACE, |
92 | T_ERROR, |
93 | T_UNKNOWN |
94 | } json_token_type_t; |
95 | |
96 | static const char *json_token_type_name[] = { |
97 | "T_OBJ_BEGIN" , |
98 | "T_OBJ_END" , |
99 | "T_ARR_BEGIN" , |
100 | "T_ARR_END" , |
101 | "T_STRING" , |
102 | "T_NUMBER" , |
103 | "T_BOOLEAN" , |
104 | "T_NULL" , |
105 | "T_COLON" , |
106 | "T_COMMA" , |
107 | "T_END" , |
108 | "T_WHITESPACE" , |
109 | "T_ERROR" , |
110 | "T_UNKNOWN" , |
111 | NULL |
112 | }; |
113 | |
114 | typedef struct { |
115 | json_token_type_t ch2token[256]; |
116 | char escape2char[256]; /* Decoding */ |
117 | |
118 | /* encode_buf is only allocated and used when |
119 | * encode_keep_buffer is set */ |
120 | strbuf_t encode_buf; |
121 | |
122 | int encode_sparse_convert; |
123 | int encode_sparse_ratio; |
124 | int encode_sparse_safe; |
125 | int encode_max_depth; |
126 | int encode_invalid_numbers; /* 2 => Encode as "null" */ |
127 | int encode_number_precision; |
128 | int encode_keep_buffer; |
129 | |
130 | int decode_invalid_numbers; |
131 | int decode_max_depth; |
132 | } json_config_t; |
133 | |
134 | typedef struct { |
135 | const char *data; |
136 | const char *ptr; |
137 | strbuf_t *tmp; /* Temporary storage for strings */ |
138 | json_config_t *cfg; |
139 | int current_depth; |
140 | } json_parse_t; |
141 | |
142 | typedef struct { |
143 | json_token_type_t type; |
144 | int index; |
145 | union { |
146 | const char *string; |
147 | double number; |
148 | int boolean; |
149 | } value; |
150 | int string_len; |
151 | } json_token_t; |
152 | |
153 | static const char *char2escape[256] = { |
154 | "\\u0000" , "\\u0001" , "\\u0002" , "\\u0003" , |
155 | "\\u0004" , "\\u0005" , "\\u0006" , "\\u0007" , |
156 | "\\b" , "\\t" , "\\n" , "\\u000b" , |
157 | "\\f" , "\\r" , "\\u000e" , "\\u000f" , |
158 | "\\u0010" , "\\u0011" , "\\u0012" , "\\u0013" , |
159 | "\\u0014" , "\\u0015" , "\\u0016" , "\\u0017" , |
160 | "\\u0018" , "\\u0019" , "\\u001a" , "\\u001b" , |
161 | "\\u001c" , "\\u001d" , "\\u001e" , "\\u001f" , |
162 | NULL, NULL, "\\\"" , NULL, NULL, NULL, NULL, NULL, |
163 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/" , |
164 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
165 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
166 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
167 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
168 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
169 | NULL, NULL, NULL, NULL, "\\\\" , NULL, NULL, NULL, |
170 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
171 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
172 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
173 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f" , |
174 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
175 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
176 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
177 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
178 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
179 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
180 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
181 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
182 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
183 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
184 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
185 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
186 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
187 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
188 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
189 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
190 | }; |
191 | |
192 | /* ===== CONFIGURATION ===== */ |
193 | |
194 | static json_config_t *json_fetch_config(lua_State *l) |
195 | { |
196 | json_config_t *cfg; |
197 | |
198 | cfg = lua_touserdata(l, lua_upvalueindex(1)); |
199 | if (!cfg) |
200 | luaL_error(l, "BUG: Unable to fetch CJSON configuration" ); |
201 | |
202 | return cfg; |
203 | } |
204 | |
205 | /* Ensure the correct number of arguments have been provided. |
206 | * Pad with nil to allow other functions to simply check arg[i] |
207 | * to find whether an argument was provided */ |
208 | static json_config_t *json_arg_init(lua_State *l, int args) |
209 | { |
210 | luaL_argcheck(l, lua_gettop(l) <= args, args + 1, |
211 | "found too many arguments" ); |
212 | |
213 | while (lua_gettop(l) < args) |
214 | lua_pushnil(l); |
215 | |
216 | return json_fetch_config(l); |
217 | } |
218 | |
219 | /* Process integer options for configuration functions */ |
220 | static int json_integer_option(lua_State *l, int optindex, int *setting, |
221 | int min, int max) |
222 | { |
223 | char errmsg[64]; |
224 | int value; |
225 | |
226 | if (!lua_isnil(l, optindex)) { |
227 | value = luaL_checkinteger(l, optindex); |
228 | snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d" , min, max); |
229 | luaL_argcheck(l, min <= value && value <= max, 1, errmsg); |
230 | *setting = value; |
231 | } |
232 | |
233 | lua_pushinteger(l, *setting); |
234 | |
235 | return 1; |
236 | } |
237 | |
238 | /* Process enumerated arguments for a configuration function */ |
239 | static int json_enum_option(lua_State *l, int optindex, int *setting, |
240 | const char **options, int bool_true) |
241 | { |
242 | static const char *bool_options[] = { "off" , "on" , NULL }; |
243 | |
244 | if (!options) { |
245 | options = bool_options; |
246 | bool_true = 1; |
247 | } |
248 | |
249 | if (!lua_isnil(l, optindex)) { |
250 | if (bool_true && lua_isboolean(l, optindex)) |
251 | *setting = lua_toboolean(l, optindex) * bool_true; |
252 | else |
253 | *setting = luaL_checkoption(l, optindex, NULL, options); |
254 | } |
255 | |
256 | if (bool_true && (*setting == 0 || *setting == bool_true)) |
257 | lua_pushboolean(l, *setting); |
258 | else |
259 | lua_pushstring(l, options[*setting]); |
260 | |
261 | return 1; |
262 | } |
263 | |
264 | /* Configures handling of extremely sparse arrays: |
265 | * convert: Convert extremely sparse arrays into objects? Otherwise error. |
266 | * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio |
267 | * safe: Always use an array when the max index <= safe */ |
268 | static int json_cfg_encode_sparse_array(lua_State *l) |
269 | { |
270 | json_config_t *cfg = json_arg_init(l, 3); |
271 | |
272 | json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1); |
273 | json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX); |
274 | json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX); |
275 | |
276 | return 3; |
277 | } |
278 | |
279 | /* Configures the maximum number of nested arrays/objects allowed when |
280 | * encoding */ |
281 | static int json_cfg_encode_max_depth(lua_State *l) |
282 | { |
283 | json_config_t *cfg = json_arg_init(l, 1); |
284 | |
285 | return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX); |
286 | } |
287 | |
288 | /* Configures the maximum number of nested arrays/objects allowed when |
289 | * encoding */ |
290 | static int json_cfg_decode_max_depth(lua_State *l) |
291 | { |
292 | json_config_t *cfg = json_arg_init(l, 1); |
293 | |
294 | return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX); |
295 | } |
296 | |
297 | /* Configures number precision when converting doubles to text */ |
298 | static int json_cfg_encode_number_precision(lua_State *l) |
299 | { |
300 | json_config_t *cfg = json_arg_init(l, 1); |
301 | |
302 | return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 14); |
303 | } |
304 | |
305 | /* Configures JSON encoding buffer persistence */ |
306 | static int json_cfg_encode_keep_buffer(lua_State *l) |
307 | { |
308 | json_config_t *cfg = json_arg_init(l, 1); |
309 | int old_value; |
310 | |
311 | old_value = cfg->encode_keep_buffer; |
312 | |
313 | json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1); |
314 | |
315 | /* Init / free the buffer if the setting has changed */ |
316 | if (old_value ^ cfg->encode_keep_buffer) { |
317 | if (cfg->encode_keep_buffer) |
318 | strbuf_init(&cfg->encode_buf, 0); |
319 | else |
320 | strbuf_free(&cfg->encode_buf); |
321 | } |
322 | |
323 | return 1; |
324 | } |
325 | |
326 | #if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) |
327 | void json_verify_invalid_number_setting(lua_State *l, int *setting) |
328 | { |
329 | if (*setting == 1) { |
330 | *setting = 0; |
331 | luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported." ); |
332 | } |
333 | } |
334 | #else |
335 | #define json_verify_invalid_number_setting(l, s) do { } while(0) |
336 | #endif |
337 | |
338 | static int json_cfg_encode_invalid_numbers(lua_State *l) |
339 | { |
340 | static const char *options[] = { "off" , "on" , "null" , NULL }; |
341 | json_config_t *cfg = json_arg_init(l, 1); |
342 | |
343 | json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1); |
344 | |
345 | json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers); |
346 | |
347 | return 1; |
348 | } |
349 | |
350 | static int json_cfg_decode_invalid_numbers(lua_State *l) |
351 | { |
352 | json_config_t *cfg = json_arg_init(l, 1); |
353 | |
354 | json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1); |
355 | |
356 | json_verify_invalid_number_setting(l, &cfg->encode_invalid_numbers); |
357 | |
358 | return 1; |
359 | } |
360 | |
361 | static int json_destroy_config(lua_State *l) |
362 | { |
363 | json_config_t *cfg; |
364 | |
365 | cfg = lua_touserdata(l, 1); |
366 | if (cfg) |
367 | strbuf_free(&cfg->encode_buf); |
368 | cfg = NULL; |
369 | |
370 | return 0; |
371 | } |
372 | |
373 | static void json_create_config(lua_State *l) |
374 | { |
375 | json_config_t *cfg; |
376 | int i; |
377 | |
378 | cfg = lua_newuserdata(l, sizeof(*cfg)); |
379 | |
380 | /* Create GC method to clean up strbuf */ |
381 | lua_newtable(l); |
382 | lua_pushcfunction(l, json_destroy_config); |
383 | lua_setfield(l, -2, "__gc" ); |
384 | lua_setmetatable(l, -2); |
385 | |
386 | cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; |
387 | cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; |
388 | cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; |
389 | cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH; |
390 | cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH; |
391 | cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS; |
392 | cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS; |
393 | cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; |
394 | cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; |
395 | |
396 | #if DEFAULT_ENCODE_KEEP_BUFFER > 0 |
397 | strbuf_init(&cfg->encode_buf, 0); |
398 | #endif |
399 | |
400 | /* Decoding init */ |
401 | |
402 | /* Tag all characters as an error */ |
403 | for (i = 0; i < 256; i++) |
404 | cfg->ch2token[i] = T_ERROR; |
405 | |
406 | /* Set tokens that require no further processing */ |
407 | cfg->ch2token['{'] = T_OBJ_BEGIN; |
408 | cfg->ch2token['}'] = T_OBJ_END; |
409 | cfg->ch2token['['] = T_ARR_BEGIN; |
410 | cfg->ch2token[']'] = T_ARR_END; |
411 | cfg->ch2token[','] = T_COMMA; |
412 | cfg->ch2token[':'] = T_COLON; |
413 | cfg->ch2token['\0'] = T_END; |
414 | cfg->ch2token[' '] = T_WHITESPACE; |
415 | cfg->ch2token['\t'] = T_WHITESPACE; |
416 | cfg->ch2token['\n'] = T_WHITESPACE; |
417 | cfg->ch2token['\r'] = T_WHITESPACE; |
418 | |
419 | /* Update characters that require further processing */ |
420 | cfg->ch2token['f'] = T_UNKNOWN; /* false? */ |
421 | cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */ |
422 | cfg->ch2token['I'] = T_UNKNOWN; |
423 | cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */ |
424 | cfg->ch2token['N'] = T_UNKNOWN; |
425 | cfg->ch2token['t'] = T_UNKNOWN; /* true? */ |
426 | cfg->ch2token['"'] = T_UNKNOWN; /* string? */ |
427 | cfg->ch2token['+'] = T_UNKNOWN; /* number? */ |
428 | cfg->ch2token['-'] = T_UNKNOWN; |
429 | for (i = 0; i < 10; i++) |
430 | cfg->ch2token['0' + i] = T_UNKNOWN; |
431 | |
432 | /* Lookup table for parsing escape characters */ |
433 | for (i = 0; i < 256; i++) |
434 | cfg->escape2char[i] = 0; /* String error */ |
435 | cfg->escape2char['"'] = '"'; |
436 | cfg->escape2char['\\'] = '\\'; |
437 | cfg->escape2char['/'] = '/'; |
438 | cfg->escape2char['b'] = '\b'; |
439 | cfg->escape2char['t'] = '\t'; |
440 | cfg->escape2char['n'] = '\n'; |
441 | cfg->escape2char['f'] = '\f'; |
442 | cfg->escape2char['r'] = '\r'; |
443 | cfg->escape2char['u'] = 'u'; /* Unicode parsing required */ |
444 | } |
445 | |
446 | /* ===== ENCODING ===== */ |
447 | |
448 | static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex, |
449 | const char *reason) |
450 | { |
451 | if (!cfg->encode_keep_buffer) |
452 | strbuf_free(json); |
453 | luaL_error(l, "Cannot serialise %s: %s" , |
454 | lua_typename(l, lua_type(l, lindex)), reason); |
455 | } |
456 | |
457 | /* json_append_string args: |
458 | * - lua_State |
459 | * - JSON strbuf |
460 | * - String (Lua stack index) |
461 | * |
462 | * Returns nothing. Doesn't remove string from Lua stack */ |
463 | static void json_append_string(lua_State *l, strbuf_t *json, int lindex) |
464 | { |
465 | const char *escstr; |
466 | int i; |
467 | const char *str; |
468 | size_t len; |
469 | |
470 | str = lua_tolstring(l, lindex, &len); |
471 | |
472 | /* Worst case is len * 6 (all unicode escapes). |
473 | * This buffer is reused constantly for small strings |
474 | * If there are any excess pages, they won't be hit anyway. |
475 | * This gains ~5% speedup. */ |
476 | strbuf_ensure_empty_length(json, len * 6 + 2); |
477 | |
478 | strbuf_append_char_unsafe(json, '\"'); |
479 | for (i = 0; i < len; i++) { |
480 | escstr = char2escape[(unsigned char)str[i]]; |
481 | if (escstr) |
482 | strbuf_append_string(json, escstr); |
483 | else |
484 | strbuf_append_char_unsafe(json, str[i]); |
485 | } |
486 | strbuf_append_char_unsafe(json, '\"'); |
487 | } |
488 | |
489 | /* Find the size of the array on the top of the Lua stack |
490 | * -1 object (not a pure array) |
491 | * >=0 elements in array |
492 | */ |
493 | static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json) |
494 | { |
495 | double k; |
496 | int max; |
497 | int items; |
498 | |
499 | max = 0; |
500 | items = 0; |
501 | |
502 | lua_pushnil(l); |
503 | /* table, startkey */ |
504 | while (lua_next(l, -2) != 0) { |
505 | /* table, key, value */ |
506 | if (lua_type(l, -2) == LUA_TNUMBER && |
507 | (k = lua_tonumber(l, -2))) { |
508 | /* Integer >= 1 ? */ |
509 | if (floor(k) == k && k >= 1) { |
510 | if (k > max) |
511 | max = k; |
512 | items++; |
513 | lua_pop(l, 1); |
514 | continue; |
515 | } |
516 | } |
517 | |
518 | /* Must not be an array (non integer key) */ |
519 | lua_pop(l, 2); |
520 | return -1; |
521 | } |
522 | |
523 | /* Encode excessively sparse arrays as objects (if enabled) */ |
524 | if (cfg->encode_sparse_ratio > 0 && |
525 | max > items * cfg->encode_sparse_ratio && |
526 | max > cfg->encode_sparse_safe) { |
527 | if (!cfg->encode_sparse_convert) |
528 | json_encode_exception(l, cfg, json, -1, "excessively sparse array" ); |
529 | |
530 | return -1; |
531 | } |
532 | |
533 | return max; |
534 | } |
535 | |
536 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, |
537 | int current_depth, strbuf_t *json) |
538 | { |
539 | /* Ensure there are enough slots free to traverse a table (key, |
540 | * value) and push a string for a potential error message. |
541 | * |
542 | * Unlike "decode", the key and value are still on the stack when |
543 | * lua_checkstack() is called. Hence an extra slot for luaL_error() |
544 | * below is required just in case the next check to lua_checkstack() |
545 | * fails. |
546 | * |
547 | * While this won't cause a crash due to the EXTRA_STACK reserve |
548 | * slots, it would still be an improper use of the API. */ |
549 | if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3)) |
550 | return; |
551 | |
552 | if (!cfg->encode_keep_buffer) |
553 | strbuf_free(json); |
554 | |
555 | luaL_error(l, "Cannot serialise, excessive nesting (%d)" , |
556 | current_depth); |
557 | } |
558 | |
559 | static void json_append_data(lua_State *l, json_config_t *cfg, |
560 | int current_depth, strbuf_t *json); |
561 | |
562 | /* json_append_array args: |
563 | * - lua_State |
564 | * - JSON strbuf |
565 | * - Size of passwd Lua array (top of stack) */ |
566 | static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth, |
567 | strbuf_t *json, int array_length) |
568 | { |
569 | int comma, i; |
570 | |
571 | strbuf_append_char(json, '['); |
572 | |
573 | comma = 0; |
574 | for (i = 1; i <= array_length; i++) { |
575 | if (comma) |
576 | strbuf_append_char(json, ','); |
577 | else |
578 | comma = 1; |
579 | |
580 | lua_rawgeti(l, -1, i); |
581 | json_append_data(l, cfg, current_depth, json); |
582 | lua_pop(l, 1); |
583 | } |
584 | |
585 | strbuf_append_char(json, ']'); |
586 | } |
587 | |
588 | static void json_append_number(lua_State *l, json_config_t *cfg, |
589 | strbuf_t *json, int lindex) |
590 | { |
591 | double num = lua_tonumber(l, lindex); |
592 | int len; |
593 | |
594 | if (cfg->encode_invalid_numbers == 0) { |
595 | /* Prevent encoding invalid numbers */ |
596 | if (isinf(num) || isnan(num)) |
597 | json_encode_exception(l, cfg, json, lindex, "must not be NaN or Inf" ); |
598 | } else if (cfg->encode_invalid_numbers == 1) { |
599 | /* Encode invalid numbers, but handle "nan" separately |
600 | * since some platforms may encode as "-nan". */ |
601 | if (isnan(num)) { |
602 | strbuf_append_mem(json, "nan" , 3); |
603 | return; |
604 | } |
605 | } else { |
606 | /* Encode invalid numbers as "null" */ |
607 | if (isinf(num) || isnan(num)) { |
608 | strbuf_append_mem(json, "null" , 4); |
609 | return; |
610 | } |
611 | } |
612 | |
613 | strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); |
614 | len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision); |
615 | strbuf_extend_length(json, len); |
616 | } |
617 | |
618 | static void json_append_object(lua_State *l, json_config_t *cfg, |
619 | int current_depth, strbuf_t *json) |
620 | { |
621 | int comma, keytype; |
622 | |
623 | /* Object */ |
624 | strbuf_append_char(json, '{'); |
625 | |
626 | lua_pushnil(l); |
627 | /* table, startkey */ |
628 | comma = 0; |
629 | while (lua_next(l, -2) != 0) { |
630 | if (comma) |
631 | strbuf_append_char(json, ','); |
632 | else |
633 | comma = 1; |
634 | |
635 | /* table, key, value */ |
636 | keytype = lua_type(l, -2); |
637 | if (keytype == LUA_TNUMBER) { |
638 | strbuf_append_char(json, '"'); |
639 | json_append_number(l, cfg, json, -2); |
640 | strbuf_append_mem(json, "\":" , 2); |
641 | } else if (keytype == LUA_TSTRING) { |
642 | json_append_string(l, json, -2); |
643 | strbuf_append_char(json, ':'); |
644 | } else { |
645 | json_encode_exception(l, cfg, json, -2, |
646 | "table key must be a number or string" ); |
647 | /* never returns */ |
648 | } |
649 | |
650 | /* table, key, value */ |
651 | json_append_data(l, cfg, current_depth, json); |
652 | lua_pop(l, 1); |
653 | /* table, key */ |
654 | } |
655 | |
656 | strbuf_append_char(json, '}'); |
657 | } |
658 | |
659 | /* Serialise Lua data into JSON string. */ |
660 | static void json_append_data(lua_State *l, json_config_t *cfg, |
661 | int current_depth, strbuf_t *json) |
662 | { |
663 | int len; |
664 | |
665 | switch (lua_type(l, -1)) { |
666 | case LUA_TSTRING: |
667 | json_append_string(l, json, -1); |
668 | break; |
669 | case LUA_TNUMBER: |
670 | json_append_number(l, cfg, json, -1); |
671 | break; |
672 | case LUA_TBOOLEAN: |
673 | if (lua_toboolean(l, -1)) |
674 | strbuf_append_mem(json, "true" , 4); |
675 | else |
676 | strbuf_append_mem(json, "false" , 5); |
677 | break; |
678 | case LUA_TTABLE: |
679 | current_depth++; |
680 | json_check_encode_depth(l, cfg, current_depth, json); |
681 | len = lua_array_length(l, cfg, json); |
682 | if (len > 0) |
683 | json_append_array(l, cfg, current_depth, json, len); |
684 | else |
685 | json_append_object(l, cfg, current_depth, json); |
686 | break; |
687 | case LUA_TNIL: |
688 | strbuf_append_mem(json, "null" , 4); |
689 | break; |
690 | case LUA_TLIGHTUSERDATA: |
691 | if (lua_touserdata(l, -1) == NULL) { |
692 | strbuf_append_mem(json, "null" , 4); |
693 | break; |
694 | } |
695 | default: |
696 | /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, |
697 | * and LUA_TLIGHTUSERDATA) cannot be serialised */ |
698 | json_encode_exception(l, cfg, json, -1, "type not supported" ); |
699 | /* never returns */ |
700 | } |
701 | } |
702 | |
703 | static int json_encode(lua_State *l) |
704 | { |
705 | json_config_t *cfg = json_fetch_config(l); |
706 | strbuf_t local_encode_buf; |
707 | strbuf_t *encode_buf; |
708 | char *json; |
709 | int len; |
710 | |
711 | luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument" ); |
712 | |
713 | if (!cfg->encode_keep_buffer) { |
714 | /* Use private buffer */ |
715 | encode_buf = &local_encode_buf; |
716 | strbuf_init(encode_buf, 0); |
717 | } else { |
718 | /* Reuse existing buffer */ |
719 | encode_buf = &cfg->encode_buf; |
720 | strbuf_reset(encode_buf); |
721 | } |
722 | |
723 | json_append_data(l, cfg, 0, encode_buf); |
724 | json = strbuf_string(encode_buf, &len); |
725 | |
726 | lua_pushlstring(l, json, len); |
727 | |
728 | if (!cfg->encode_keep_buffer) |
729 | strbuf_free(encode_buf); |
730 | |
731 | return 1; |
732 | } |
733 | |
734 | /* ===== DECODING ===== */ |
735 | |
736 | static void json_process_value(lua_State *l, json_parse_t *json, |
737 | json_token_t *token); |
738 | |
739 | static int hexdigit2int(char hex) |
740 | { |
741 | if ('0' <= hex && hex <= '9') |
742 | return hex - '0'; |
743 | |
744 | /* Force lowercase */ |
745 | hex |= 0x20; |
746 | if ('a' <= hex && hex <= 'f') |
747 | return 10 + hex - 'a'; |
748 | |
749 | return -1; |
750 | } |
751 | |
752 | static int decode_hex4(const char *hex) |
753 | { |
754 | int digit[4]; |
755 | int i; |
756 | |
757 | /* Convert ASCII hex digit to numeric digit |
758 | * Note: this returns an error for invalid hex digits, including |
759 | * NULL */ |
760 | for (i = 0; i < 4; i++) { |
761 | digit[i] = hexdigit2int(hex[i]); |
762 | if (digit[i] < 0) { |
763 | return -1; |
764 | } |
765 | } |
766 | |
767 | return (digit[0] << 12) + |
768 | (digit[1] << 8) + |
769 | (digit[2] << 4) + |
770 | digit[3]; |
771 | } |
772 | |
773 | /* Converts a Unicode codepoint to UTF-8. |
774 | * Returns UTF-8 string length, and up to 4 bytes in *utf8 */ |
775 | static int codepoint_to_utf8(char *utf8, int codepoint) |
776 | { |
777 | /* 0xxxxxxx */ |
778 | if (codepoint <= 0x7F) { |
779 | utf8[0] = codepoint; |
780 | return 1; |
781 | } |
782 | |
783 | /* 110xxxxx 10xxxxxx */ |
784 | if (codepoint <= 0x7FF) { |
785 | utf8[0] = (codepoint >> 6) | 0xC0; |
786 | utf8[1] = (codepoint & 0x3F) | 0x80; |
787 | return 2; |
788 | } |
789 | |
790 | /* 1110xxxx 10xxxxxx 10xxxxxx */ |
791 | if (codepoint <= 0xFFFF) { |
792 | utf8[0] = (codepoint >> 12) | 0xE0; |
793 | utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80; |
794 | utf8[2] = (codepoint & 0x3F) | 0x80; |
795 | return 3; |
796 | } |
797 | |
798 | /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ |
799 | if (codepoint <= 0x1FFFFF) { |
800 | utf8[0] = (codepoint >> 18) | 0xF0; |
801 | utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80; |
802 | utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80; |
803 | utf8[3] = (codepoint & 0x3F) | 0x80; |
804 | return 4; |
805 | } |
806 | |
807 | return 0; |
808 | } |
809 | |
810 | |
811 | /* Called when index pointing to beginning of UTF-16 code escape: \uXXXX |
812 | * \u is guaranteed to exist, but the remaining hex characters may be |
813 | * missing. |
814 | * Translate to UTF-8 and append to temporary token string. |
815 | * Must advance index to the next character to be processed. |
816 | * Returns: 0 success |
817 | * -1 error |
818 | */ |
819 | static int json_append_unicode_escape(json_parse_t *json) |
820 | { |
821 | char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */ |
822 | int codepoint; |
823 | int surrogate_low; |
824 | int len; |
825 | int escape_len = 6; |
826 | |
827 | /* Fetch UTF-16 code unit */ |
828 | codepoint = decode_hex4(json->ptr + 2); |
829 | if (codepoint < 0) |
830 | return -1; |
831 | |
832 | /* UTF-16 surrogate pairs take the following 2 byte form: |
833 | * 11011 x yyyyyyyyyy |
834 | * When x = 0: y is the high 10 bits of the codepoint |
835 | * x = 1: y is the low 10 bits of the codepoint |
836 | * |
837 | * Check for a surrogate pair (high or low) */ |
838 | if ((codepoint & 0xF800) == 0xD800) { |
839 | /* Error if the 1st surrogate is not high */ |
840 | if (codepoint & 0x400) |
841 | return -1; |
842 | |
843 | /* Ensure the next code is a unicode escape */ |
844 | if (*(json->ptr + escape_len) != '\\' || |
845 | *(json->ptr + escape_len + 1) != 'u') { |
846 | return -1; |
847 | } |
848 | |
849 | /* Fetch the next codepoint */ |
850 | surrogate_low = decode_hex4(json->ptr + 2 + escape_len); |
851 | if (surrogate_low < 0) |
852 | return -1; |
853 | |
854 | /* Error if the 2nd code is not a low surrogate */ |
855 | if ((surrogate_low & 0xFC00) != 0xDC00) |
856 | return -1; |
857 | |
858 | /* Calculate Unicode codepoint */ |
859 | codepoint = (codepoint & 0x3FF) << 10; |
860 | surrogate_low &= 0x3FF; |
861 | codepoint = (codepoint | surrogate_low) + 0x10000; |
862 | escape_len = 12; |
863 | } |
864 | |
865 | /* Convert codepoint to UTF-8 */ |
866 | len = codepoint_to_utf8(utf8, codepoint); |
867 | if (!len) |
868 | return -1; |
869 | |
870 | /* Append bytes and advance parse index */ |
871 | strbuf_append_mem_unsafe(json->tmp, utf8, len); |
872 | json->ptr += escape_len; |
873 | |
874 | return 0; |
875 | } |
876 | |
877 | static void json_set_token_error(json_token_t *token, json_parse_t *json, |
878 | const char *errtype) |
879 | { |
880 | token->type = T_ERROR; |
881 | token->index = json->ptr - json->data; |
882 | token->value.string = errtype; |
883 | } |
884 | |
885 | static void json_next_string_token(json_parse_t *json, json_token_t *token) |
886 | { |
887 | char *escape2char = json->cfg->escape2char; |
888 | char ch; |
889 | |
890 | /* Caller must ensure a string is next */ |
891 | assert(*json->ptr == '"'); |
892 | |
893 | /* Skip " */ |
894 | json->ptr++; |
895 | |
896 | /* json->tmp is the temporary strbuf used to accumulate the |
897 | * decoded string value. |
898 | * json->tmp is sized to handle JSON containing only a string value. |
899 | */ |
900 | strbuf_reset(json->tmp); |
901 | |
902 | while ((ch = *json->ptr) != '"') { |
903 | if (!ch) { |
904 | /* Premature end of the string */ |
905 | json_set_token_error(token, json, "unexpected end of string" ); |
906 | return; |
907 | } |
908 | |
909 | /* Handle escapes */ |
910 | if (ch == '\\') { |
911 | /* Fetch escape character */ |
912 | ch = *(json->ptr + 1); |
913 | |
914 | /* Translate escape code and append to tmp string */ |
915 | ch = escape2char[(unsigned char)ch]; |
916 | if (ch == 'u') { |
917 | if (json_append_unicode_escape(json) == 0) |
918 | continue; |
919 | |
920 | json_set_token_error(token, json, |
921 | "invalid unicode escape code" ); |
922 | return; |
923 | } |
924 | if (!ch) { |
925 | json_set_token_error(token, json, "invalid escape code" ); |
926 | return; |
927 | } |
928 | |
929 | /* Skip '\' */ |
930 | json->ptr++; |
931 | } |
932 | /* Append normal character or translated single character |
933 | * Unicode escapes are handled above */ |
934 | strbuf_append_char_unsafe(json->tmp, ch); |
935 | json->ptr++; |
936 | } |
937 | json->ptr++; /* Eat final quote (") */ |
938 | |
939 | strbuf_ensure_null(json->tmp); |
940 | |
941 | token->type = T_STRING; |
942 | token->value.string = strbuf_string(json->tmp, &token->string_len); |
943 | } |
944 | |
945 | /* JSON numbers should take the following form: |
946 | * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)? |
947 | * |
948 | * json_next_number_token() uses strtod() which allows other forms: |
949 | * - numbers starting with '+' |
950 | * - NaN, -NaN, infinity, -infinity |
951 | * - hexadecimal numbers |
952 | * - numbers with leading zeros |
953 | * |
954 | * json_is_invalid_number() detects "numbers" which may pass strtod()'s |
955 | * error checking, but should not be allowed with strict JSON. |
956 | * |
957 | * json_is_invalid_number() may pass numbers which cause strtod() |
958 | * to generate an error. |
959 | */ |
960 | static int json_is_invalid_number(json_parse_t *json) |
961 | { |
962 | const char *p = json->ptr; |
963 | |
964 | /* Reject numbers starting with + */ |
965 | if (*p == '+') |
966 | return 1; |
967 | |
968 | /* Skip minus sign if it exists */ |
969 | if (*p == '-') |
970 | p++; |
971 | |
972 | /* Reject numbers starting with 0x, or leading zeros */ |
973 | if (*p == '0') { |
974 | int ch2 = *(p + 1); |
975 | |
976 | if ((ch2 | 0x20) == 'x' || /* Hex */ |
977 | ('0' <= ch2 && ch2 <= '9')) /* Leading zero */ |
978 | return 1; |
979 | |
980 | return 0; |
981 | } else if (*p <= '9') { |
982 | return 0; /* Ordinary number */ |
983 | } |
984 | |
985 | /* Reject inf/nan */ |
986 | if (!strncasecmp(p, "inf" , 3)) |
987 | return 1; |
988 | if (!strncasecmp(p, "nan" , 3)) |
989 | return 1; |
990 | |
991 | /* Pass all other numbers which may still be invalid, but |
992 | * strtod() will catch them. */ |
993 | return 0; |
994 | } |
995 | |
996 | static void json_next_number_token(json_parse_t *json, json_token_t *token) |
997 | { |
998 | char *endptr; |
999 | |
1000 | token->type = T_NUMBER; |
1001 | token->value.number = fpconv_strtod(json->ptr, &endptr); |
1002 | if (json->ptr == endptr) |
1003 | json_set_token_error(token, json, "invalid number" ); |
1004 | else |
1005 | json->ptr = endptr; /* Skip the processed number */ |
1006 | |
1007 | return; |
1008 | } |
1009 | |
1010 | /* Fills in the token struct. |
1011 | * T_STRING will return a pointer to the json_parse_t temporary string |
1012 | * T_ERROR will leave the json->ptr pointer at the error. |
1013 | */ |
1014 | static void json_next_token(json_parse_t *json, json_token_t *token) |
1015 | { |
1016 | const json_token_type_t *ch2token = json->cfg->ch2token; |
1017 | int ch; |
1018 | |
1019 | /* Eat whitespace. */ |
1020 | while (1) { |
1021 | ch = (unsigned char)*(json->ptr); |
1022 | token->type = ch2token[ch]; |
1023 | if (token->type != T_WHITESPACE) |
1024 | break; |
1025 | json->ptr++; |
1026 | } |
1027 | |
1028 | /* Store location of new token. Required when throwing errors |
1029 | * for unexpected tokens (syntax errors). */ |
1030 | token->index = json->ptr - json->data; |
1031 | |
1032 | /* Don't advance the pointer for an error or the end */ |
1033 | if (token->type == T_ERROR) { |
1034 | json_set_token_error(token, json, "invalid token" ); |
1035 | return; |
1036 | } |
1037 | |
1038 | if (token->type == T_END) { |
1039 | return; |
1040 | } |
1041 | |
1042 | /* Found a known single character token, advance index and return */ |
1043 | if (token->type != T_UNKNOWN) { |
1044 | json->ptr++; |
1045 | return; |
1046 | } |
1047 | |
1048 | /* Process characters which triggered T_UNKNOWN |
1049 | * |
1050 | * Must use strncmp() to match the front of the JSON string. |
1051 | * JSON identifier must be lowercase. |
1052 | * When strict_numbers if disabled, either case is allowed for |
1053 | * Infinity/NaN (since we are no longer following the spec..) */ |
1054 | if (ch == '"') { |
1055 | json_next_string_token(json, token); |
1056 | return; |
1057 | } else if (ch == '-' || ('0' <= ch && ch <= '9')) { |
1058 | if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) { |
1059 | json_set_token_error(token, json, "invalid number" ); |
1060 | return; |
1061 | } |
1062 | json_next_number_token(json, token); |
1063 | return; |
1064 | } else if (!strncmp(json->ptr, "true" , 4)) { |
1065 | token->type = T_BOOLEAN; |
1066 | token->value.boolean = 1; |
1067 | json->ptr += 4; |
1068 | return; |
1069 | } else if (!strncmp(json->ptr, "false" , 5)) { |
1070 | token->type = T_BOOLEAN; |
1071 | token->value.boolean = 0; |
1072 | json->ptr += 5; |
1073 | return; |
1074 | } else if (!strncmp(json->ptr, "null" , 4)) { |
1075 | token->type = T_NULL; |
1076 | json->ptr += 4; |
1077 | return; |
1078 | } else if (json->cfg->decode_invalid_numbers && |
1079 | json_is_invalid_number(json)) { |
1080 | /* When decode_invalid_numbers is enabled, only attempt to process |
1081 | * numbers we know are invalid JSON (Inf, NaN, hex) |
1082 | * This is required to generate an appropriate token error, |
1083 | * otherwise all bad tokens will register as "invalid number" |
1084 | */ |
1085 | json_next_number_token(json, token); |
1086 | return; |
1087 | } |
1088 | |
1089 | /* Token starts with t/f/n but isn't recognised above. */ |
1090 | json_set_token_error(token, json, "invalid token" ); |
1091 | } |
1092 | |
1093 | /* This function does not return. |
1094 | * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED. |
1095 | * The only supported exception is the temporary parser string |
1096 | * json->tmp struct. |
1097 | * json and token should exist on the stack somewhere. |
1098 | * luaL_error() will long_jmp and release the stack */ |
1099 | static void json_throw_parse_error(lua_State *l, json_parse_t *json, |
1100 | const char *exp, json_token_t *token) |
1101 | { |
1102 | const char *found; |
1103 | |
1104 | strbuf_free(json->tmp); |
1105 | |
1106 | if (token->type == T_ERROR) |
1107 | found = token->value.string; |
1108 | else |
1109 | found = json_token_type_name[token->type]; |
1110 | |
1111 | /* Note: token->index is 0 based, display starting from 1 */ |
1112 | luaL_error(l, "Expected %s but found %s at character %d" , |
1113 | exp, found, token->index + 1); |
1114 | } |
1115 | |
1116 | static inline void json_decode_ascend(json_parse_t *json) |
1117 | { |
1118 | json->current_depth--; |
1119 | } |
1120 | |
1121 | static void json_decode_descend(lua_State *l, json_parse_t *json, int slots) |
1122 | { |
1123 | json->current_depth++; |
1124 | |
1125 | if (json->current_depth <= json->cfg->decode_max_depth && |
1126 | lua_checkstack(l, slots)) { |
1127 | return; |
1128 | } |
1129 | |
1130 | strbuf_free(json->tmp); |
1131 | luaL_error(l, "Found too many nested data structures (%d) at character %d" , |
1132 | json->current_depth, json->ptr - json->data); |
1133 | } |
1134 | |
1135 | static void json_parse_object_context(lua_State *l, json_parse_t *json) |
1136 | { |
1137 | json_token_t token; |
1138 | |
1139 | /* 3 slots required: |
1140 | * .., table, key, value */ |
1141 | json_decode_descend(l, json, 3); |
1142 | |
1143 | lua_newtable(l); |
1144 | |
1145 | json_next_token(json, &token); |
1146 | |
1147 | /* Handle empty objects */ |
1148 | if (token.type == T_OBJ_END) { |
1149 | json_decode_ascend(json); |
1150 | return; |
1151 | } |
1152 | |
1153 | while (1) { |
1154 | if (token.type != T_STRING) |
1155 | json_throw_parse_error(l, json, "object key string" , &token); |
1156 | |
1157 | /* Push key */ |
1158 | lua_pushlstring(l, token.value.string, token.string_len); |
1159 | |
1160 | json_next_token(json, &token); |
1161 | if (token.type != T_COLON) |
1162 | json_throw_parse_error(l, json, "colon" , &token); |
1163 | |
1164 | /* Fetch value */ |
1165 | json_next_token(json, &token); |
1166 | json_process_value(l, json, &token); |
1167 | |
1168 | /* Set key = value */ |
1169 | lua_rawset(l, -3); |
1170 | |
1171 | json_next_token(json, &token); |
1172 | |
1173 | if (token.type == T_OBJ_END) { |
1174 | json_decode_ascend(json); |
1175 | return; |
1176 | } |
1177 | |
1178 | if (token.type != T_COMMA) |
1179 | json_throw_parse_error(l, json, "comma or object end" , &token); |
1180 | |
1181 | json_next_token(json, &token); |
1182 | } |
1183 | } |
1184 | |
1185 | /* Handle the array context */ |
1186 | static void json_parse_array_context(lua_State *l, json_parse_t *json) |
1187 | { |
1188 | json_token_t token; |
1189 | int i; |
1190 | |
1191 | /* 2 slots required: |
1192 | * .., table, value */ |
1193 | json_decode_descend(l, json, 2); |
1194 | |
1195 | lua_newtable(l); |
1196 | |
1197 | json_next_token(json, &token); |
1198 | |
1199 | /* Handle empty arrays */ |
1200 | if (token.type == T_ARR_END) { |
1201 | json_decode_ascend(json); |
1202 | return; |
1203 | } |
1204 | |
1205 | for (i = 1; ; i++) { |
1206 | json_process_value(l, json, &token); |
1207 | lua_rawseti(l, -2, i); /* arr[i] = value */ |
1208 | |
1209 | json_next_token(json, &token); |
1210 | |
1211 | if (token.type == T_ARR_END) { |
1212 | json_decode_ascend(json); |
1213 | return; |
1214 | } |
1215 | |
1216 | if (token.type != T_COMMA) |
1217 | json_throw_parse_error(l, json, "comma or array end" , &token); |
1218 | |
1219 | json_next_token(json, &token); |
1220 | } |
1221 | } |
1222 | |
1223 | /* Handle the "value" context */ |
1224 | static void json_process_value(lua_State *l, json_parse_t *json, |
1225 | json_token_t *token) |
1226 | { |
1227 | switch (token->type) { |
1228 | case T_STRING: |
1229 | lua_pushlstring(l, token->value.string, token->string_len); |
1230 | break;; |
1231 | case T_NUMBER: |
1232 | lua_pushnumber(l, token->value.number); |
1233 | break;; |
1234 | case T_BOOLEAN: |
1235 | lua_pushboolean(l, token->value.boolean); |
1236 | break;; |
1237 | case T_OBJ_BEGIN: |
1238 | json_parse_object_context(l, json); |
1239 | break;; |
1240 | case T_ARR_BEGIN: |
1241 | json_parse_array_context(l, json); |
1242 | break;; |
1243 | case T_NULL: |
1244 | /* In Lua, setting "t[k] = nil" will delete k from the table. |
1245 | * Hence a NULL pointer lightuserdata object is used instead */ |
1246 | lua_pushlightuserdata(l, NULL); |
1247 | break;; |
1248 | default: |
1249 | json_throw_parse_error(l, json, "value" , token); |
1250 | } |
1251 | } |
1252 | |
1253 | static int json_decode(lua_State *l) |
1254 | { |
1255 | json_parse_t json; |
1256 | json_token_t token; |
1257 | size_t json_len; |
1258 | |
1259 | luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument" ); |
1260 | |
1261 | json.cfg = json_fetch_config(l); |
1262 | json.data = luaL_checklstring(l, 1, &json_len); |
1263 | json.current_depth = 0; |
1264 | json.ptr = json.data; |
1265 | |
1266 | /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3) |
1267 | * |
1268 | * CJSON can support any simple data type, hence only the first |
1269 | * character is guaranteed to be ASCII (at worst: '"'). This is |
1270 | * still enough to detect whether the wrong encoding is in use. */ |
1271 | if (json_len >= 2 && (!json.data[0] || !json.data[1])) |
1272 | luaL_error(l, "JSON parser does not support UTF-16 or UTF-32" ); |
1273 | |
1274 | /* Ensure the temporary buffer can hold the entire string. |
1275 | * This means we no longer need to do length checks since the decoded |
1276 | * string must be smaller than the entire json string */ |
1277 | json.tmp = strbuf_new(json_len); |
1278 | |
1279 | json_next_token(&json, &token); |
1280 | json_process_value(l, &json, &token); |
1281 | |
1282 | /* Ensure there is no more input left */ |
1283 | json_next_token(&json, &token); |
1284 | |
1285 | if (token.type != T_END) |
1286 | json_throw_parse_error(l, &json, "the end" , &token); |
1287 | |
1288 | strbuf_free(json.tmp); |
1289 | |
1290 | return 1; |
1291 | } |
1292 | |
1293 | /* ===== INITIALISATION ===== */ |
1294 | |
1295 | #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 |
1296 | /* Compatibility for Lua 5.1. |
1297 | * |
1298 | * luaL_setfuncs() is used to create a module table where the functions have |
1299 | * json_config_t as their first upvalue. Code borrowed from Lua 5.2 source. */ |
1300 | static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup) |
1301 | { |
1302 | int i; |
1303 | |
1304 | luaL_checkstack(l, nup, "too many upvalues" ); |
1305 | for (; reg->name != NULL; reg++) { /* fill the table with given functions */ |
1306 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ |
1307 | lua_pushvalue(l, -nup); |
1308 | lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */ |
1309 | lua_setfield(l, -(nup + 2), reg->name); |
1310 | } |
1311 | lua_pop(l, nup); /* remove upvalues */ |
1312 | } |
1313 | #endif |
1314 | |
1315 | /* Call target function in protected mode with all supplied args. |
1316 | * Assumes target function only returns a single non-nil value. |
1317 | * Convert and return thrown errors as: nil, "error message" */ |
1318 | static int json_protect_conversion(lua_State *l) |
1319 | { |
1320 | int err; |
1321 | |
1322 | /* Deliberately throw an error for invalid arguments */ |
1323 | luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument" ); |
1324 | |
1325 | /* pcall() the function stored as upvalue(1) */ |
1326 | lua_pushvalue(l, lua_upvalueindex(1)); |
1327 | lua_insert(l, 1); |
1328 | err = lua_pcall(l, 1, 1, 0); |
1329 | if (!err) |
1330 | return 1; |
1331 | |
1332 | if (err == LUA_ERRRUN) { |
1333 | lua_pushnil(l); |
1334 | lua_insert(l, -2); |
1335 | return 2; |
1336 | } |
1337 | |
1338 | /* Since we are not using a custom error handler, the only remaining |
1339 | * errors are memory related */ |
1340 | return luaL_error(l, "Memory allocation error in CJSON protected call" ); |
1341 | } |
1342 | |
1343 | /* Return cjson module table */ |
1344 | static int lua_cjson_new(lua_State *l) |
1345 | { |
1346 | luaL_Reg reg[] = { |
1347 | { "encode" , json_encode }, |
1348 | { "decode" , json_decode }, |
1349 | { "encode_sparse_array" , json_cfg_encode_sparse_array }, |
1350 | { "encode_max_depth" , json_cfg_encode_max_depth }, |
1351 | { "decode_max_depth" , json_cfg_decode_max_depth }, |
1352 | { "encode_number_precision" , json_cfg_encode_number_precision }, |
1353 | { "encode_keep_buffer" , json_cfg_encode_keep_buffer }, |
1354 | { "encode_invalid_numbers" , json_cfg_encode_invalid_numbers }, |
1355 | { "decode_invalid_numbers" , json_cfg_decode_invalid_numbers }, |
1356 | { "new" , lua_cjson_new }, |
1357 | { NULL, NULL } |
1358 | }; |
1359 | |
1360 | /* Initialise number conversions */ |
1361 | fpconv_init(); |
1362 | |
1363 | /* cjson module table */ |
1364 | lua_newtable(l); |
1365 | |
1366 | /* Register functions with config data as upvalue */ |
1367 | json_create_config(l); |
1368 | luaL_setfuncs(l, reg, 1); |
1369 | |
1370 | /* Set cjson.null */ |
1371 | lua_pushlightuserdata(l, NULL); |
1372 | lua_setfield(l, -2, "null" ); |
1373 | |
1374 | /* Set module name / version fields */ |
1375 | lua_pushliteral(l, CJSON_MODNAME); |
1376 | lua_setfield(l, -2, "_NAME" ); |
1377 | lua_pushliteral(l, CJSON_VERSION); |
1378 | lua_setfield(l, -2, "_VERSION" ); |
1379 | |
1380 | return 1; |
1381 | } |
1382 | |
1383 | /* Return cjson.safe module table */ |
1384 | static int lua_cjson_safe_new(lua_State *l) |
1385 | { |
1386 | const char *func[] = { "decode" , "encode" , NULL }; |
1387 | int i; |
1388 | |
1389 | lua_cjson_new(l); |
1390 | |
1391 | /* Fix new() method */ |
1392 | lua_pushcfunction(l, lua_cjson_safe_new); |
1393 | lua_setfield(l, -2, "new" ); |
1394 | |
1395 | for (i = 0; func[i]; i++) { |
1396 | lua_getfield(l, -1, func[i]); |
1397 | lua_pushcclosure(l, json_protect_conversion, 1); |
1398 | lua_setfield(l, -2, func[i]); |
1399 | } |
1400 | |
1401 | return 1; |
1402 | } |
1403 | |
1404 | int luaopen_cjson(lua_State *l) |
1405 | { |
1406 | lua_cjson_new(l); |
1407 | |
1408 | #ifdef ENABLE_CJSON_GLOBAL |
1409 | /* Register a global "cjson" table. */ |
1410 | lua_pushvalue(l, -1); |
1411 | lua_setglobal(l, CJSON_MODNAME); |
1412 | #endif |
1413 | |
1414 | /* Return cjson table */ |
1415 | return 1; |
1416 | } |
1417 | |
1418 | int luaopen_cjson_safe(lua_State *l) |
1419 | { |
1420 | lua_cjson_safe_new(l); |
1421 | |
1422 | /* Return cjson.safe table */ |
1423 | return 1; |
1424 | } |
1425 | |
1426 | /* vi:ai et sw=4 ts=4: |
1427 | */ |
1428 | |