aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c1344
1 files changed, 1344 insertions, 0 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
new file mode 100644
index 0000000..708e695
--- /dev/null
+++ b/lua_cjson.c
@@ -0,0 +1,1344 @@
1/* CJSON - JSON support for Lua
2 *
3 * Copyright (c) 2010-2011 Mark Pulford <mark@kyne.com.au>
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 <lua.h>
43#include <lauxlib.h>
44
45#include "strbuf.h"
46#include "fpconv.h"
47
48#ifndef CJSON_MODNAME
49#define CJSON_MODNAME "cjson"
50#endif
51
52#ifndef CJSON_VERSION
53#define CJSON_VERSION "1.0devel"
54#endif
55
56/* Workaround for Solaris platforms missing isinf() */
57#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
58#define isinf(x) (!isnan(x) && isnan((x) - (x)))
59#endif
60
61#define DEFAULT_SPARSE_CONVERT 0
62#define DEFAULT_SPARSE_RATIO 2
63#define DEFAULT_SPARSE_SAFE 10
64#define DEFAULT_MAX_DEPTH 20
65#define DEFAULT_ENCODE_REFUSE_BADNUM 1
66#define DEFAULT_DECODE_REFUSE_BADNUM 0
67#define DEFAULT_ENCODE_KEEP_BUFFER 1
68#define DEFAULT_ENCODE_NUMBER_PRECISION 14
69
70#ifdef DISABLE_INVALID_NUMBERS
71#undef DEFAULT_DECODE_REFUSE_BADNUM
72#define DEFAULT_DECODE_REFUSE_BADNUM 1
73#endif
74
75typedef enum {
76 T_OBJ_BEGIN,
77 T_OBJ_END,
78 T_ARR_BEGIN,
79 T_ARR_END,
80 T_STRING,
81 T_NUMBER,
82 T_BOOLEAN,
83 T_NULL,
84 T_COLON,
85 T_COMMA,
86 T_END,
87 T_WHITESPACE,
88 T_ERROR,
89 T_UNKNOWN
90} json_token_type_t;
91
92static const char *json_token_type_name[] = {
93 "T_OBJ_BEGIN",
94 "T_OBJ_END",
95 "T_ARR_BEGIN",
96 "T_ARR_END",
97 "T_STRING",
98 "T_NUMBER",
99 "T_BOOLEAN",
100 "T_NULL",
101 "T_COLON",
102 "T_COMMA",
103 "T_END",
104 "T_WHITESPACE",
105 "T_ERROR",
106 "T_UNKNOWN",
107 NULL
108};
109
110typedef struct {
111 json_token_type_t ch2token[256];
112 char escape2char[256]; /* Decoding */
113
114 /* encode_buf is only allocated and used when
115 * encode_keep_buffer is set */
116 strbuf_t encode_buf;
117
118 int encode_sparse_convert;
119 int encode_sparse_ratio;
120 int encode_sparse_safe;
121 int encode_max_depth;
122 int encode_refuse_badnum;
123 int decode_refuse_badnum;
124 int encode_keep_buffer;
125 int encode_number_precision;
126} json_config_t;
127
128typedef struct {
129 const char *data;
130 int index;
131 strbuf_t *tmp; /* Temporary storage for strings */
132 json_config_t *cfg;
133} json_parse_t;
134
135typedef struct {
136 json_token_type_t type;
137 int index;
138 union {
139 const char *string;
140 double number;
141 int boolean;
142 } value;
143 int string_len;
144} json_token_t;
145
146static const char *char2escape[256] = {
147 "\\u0000", "\\u0001", "\\u0002", "\\u0003",
148 "\\u0004", "\\u0005", "\\u0006", "\\u0007",
149 "\\b", "\\t", "\\n", "\\u000b",
150 "\\f", "\\r", "\\u000e", "\\u000f",
151 "\\u0010", "\\u0011", "\\u0012", "\\u0013",
152 "\\u0014", "\\u0015", "\\u0016", "\\u0017",
153 "\\u0018", "\\u0019", "\\u001a", "\\u001b",
154 "\\u001c", "\\u001d", "\\u001e", "\\u001f",
155 NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL,
156 NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/",
157 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
158 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
159 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
160 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
161 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
162 NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL,
163 NULL, 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, "\\u007f",
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, 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, NULL,
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};
184
185/* ===== CONFIGURATION ===== */
186
187static json_config_t *json_fetch_config(lua_State *l)
188{
189 json_config_t *cfg;
190
191 cfg = lua_touserdata(l, lua_upvalueindex(1));
192 if (!cfg)
193 luaL_error(l, "BUG: Unable to fetch CJSON configuration");
194
195 return cfg;
196}
197
198static void json_verify_arg_count(lua_State *l, int args)
199{
200 luaL_argcheck(l, lua_gettop(l) <= args, args + 1,
201 "found too many arguments");
202}
203
204/* Configures handling of extremely sparse arrays:
205 * convert: Convert extremely sparse arrays into objects? Otherwise error.
206 * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
207 * safe: Always use an array when the max index <= safe */
208static int json_cfg_encode_sparse_array(lua_State *l)
209{
210 json_config_t *cfg;
211 int val;
212
213 json_verify_arg_count(l, 3);
214 cfg = json_fetch_config(l);
215
216 switch (lua_gettop(l)) {
217 case 3:
218 val = luaL_checkinteger(l, 3);
219 luaL_argcheck(l, val >= 0, 3, "expected integer >= 0");
220 cfg->encode_sparse_safe = val;
221 case 2:
222 val = luaL_checkinteger(l, 2);
223 luaL_argcheck(l, val >= 0, 2, "expected integer >= 0");
224 cfg->encode_sparse_ratio = val;
225 case 1:
226 luaL_argcheck(l, lua_isboolean(l, 1), 1, "expected boolean");
227 cfg->encode_sparse_convert = lua_toboolean(l, 1);
228 }
229
230 lua_pushboolean(l, cfg->encode_sparse_convert);
231 lua_pushinteger(l, cfg->encode_sparse_ratio);
232 lua_pushinteger(l, cfg->encode_sparse_safe);
233
234 return 3;
235}
236
237/* Configures the maximum number of nested arrays/objects allowed when
238 * encoding */
239static int json_cfg_encode_max_depth(lua_State *l)
240{
241 json_config_t *cfg;
242 int depth;
243
244 json_verify_arg_count(l, 1);
245 cfg = json_fetch_config(l);
246
247 if (lua_gettop(l)) {
248 depth = luaL_checkinteger(l, 1);
249 luaL_argcheck(l, depth > 0, 1, "expected positive integer");
250 cfg->encode_max_depth = depth;
251 }
252
253 lua_pushinteger(l, cfg->encode_max_depth);
254
255 return 1;
256}
257
258/* Configures number precision when converting doubles to text */
259static int json_cfg_encode_number_precision(lua_State *l)
260{
261 json_config_t *cfg;
262 int precision;
263
264 json_verify_arg_count(l, 1);
265 cfg = json_fetch_config(l);
266
267 if (lua_gettop(l)) {
268 precision = luaL_checkinteger(l, 1);
269 luaL_argcheck(l, 1 <= precision && precision <= 14, 1,
270 "expected integer between 1 and 14");
271 cfg->encode_number_precision = precision;
272 }
273
274 lua_pushinteger(l, cfg->encode_number_precision);
275
276 return 1;
277}
278
279/* Configures JSON encoding buffer persistence */
280static int json_cfg_encode_keep_buffer(lua_State *l)
281{
282 json_config_t *cfg;
283 int old_value;
284
285 json_verify_arg_count(l, 1);
286 cfg = json_fetch_config(l);
287
288 old_value = cfg->encode_keep_buffer;
289
290 if (lua_gettop(l)) {
291 luaL_checktype(l, 1, LUA_TBOOLEAN);
292 cfg->encode_keep_buffer = lua_toboolean(l, 1);
293 }
294
295 /* Init / free the buffer if the setting has changed */
296 if (old_value ^ cfg->encode_keep_buffer) {
297 if (cfg->encode_keep_buffer)
298 strbuf_init(&cfg->encode_buf, 0);
299 else
300 strbuf_free(&cfg->encode_buf);
301 }
302
303 lua_pushboolean(l, cfg->encode_keep_buffer);
304
305 return 1;
306}
307
308/* On argument: decode enum and set config variables
309 * **options must point to a NULL terminated array of 4 enums
310 * Returns: current enum value */
311static void json_enum_option(lua_State *l, const char **options,
312 int *opt1, int *opt2)
313{
314 int setting;
315
316 if (lua_gettop(l)) {
317 if (lua_isboolean(l, 1))
318 setting = lua_toboolean(l, 1) * 3;
319 else
320 setting = luaL_checkoption(l, 1, NULL, options);
321
322 *opt1 = setting & 1 ? 1 : 0;
323 *opt2 = setting & 2 ? 1 : 0;
324 } else {
325 setting = *opt1 | (*opt2 << 1);
326 }
327
328 if (setting)
329 lua_pushstring(l, options[setting]);
330 else
331 lua_pushboolean(l, 0);
332}
333
334
335/* When enabled, rejects: NaN, Infinity, hexadecimal numbers */
336static int json_cfg_refuse_invalid_numbers(lua_State *l)
337{
338 static const char *options_enc_dec[] = { "none", "encode", "decode",
339 "both", NULL };
340 json_config_t *cfg;
341
342 json_verify_arg_count(l, 1);
343 cfg = json_fetch_config(l);
344
345 json_enum_option(l, options_enc_dec,
346 &cfg->encode_refuse_badnum,
347 &cfg->decode_refuse_badnum);
348
349#if DISABLE_INVALID_NUMBERS
350 /* Some non-POSIX platforms don't handle double <-> string translations
351 * for Infinity/NaN/hexadecimal properly. Throw an error if the
352 * user attempts to enable them. */
353 if (!cfg->encode_refuse_badnum || !cfg->decode_refuse_badnum) {
354 cfg->encode_refuse_badnum = cfg->decode_refuse_badnum = 1;
355 luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported.");
356 }
357#endif
358
359 return 1;
360}
361
362static int json_destroy_config(lua_State *l)
363{
364 json_config_t *cfg;
365
366 cfg = lua_touserdata(l, 1);
367 if (cfg)
368 strbuf_free(&cfg->encode_buf);
369 cfg = NULL;
370
371 return 0;
372}
373
374static void json_create_config(lua_State *l)
375{
376 json_config_t *cfg;
377 int i;
378
379 cfg = lua_newuserdata(l, sizeof(*cfg));
380
381 /* Create GC method to clean up strbuf */
382 lua_newtable(l);
383 lua_pushcfunction(l, json_destroy_config);
384 lua_setfield(l, -2, "__gc");
385 lua_setmetatable(l, -2);
386
387 cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
388 cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
389 cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
390 cfg->encode_max_depth = DEFAULT_MAX_DEPTH;
391 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM;
392 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM;
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
448static 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 */
463static 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 */
493static 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
536static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
537 int current_depth, strbuf_t *json)
538{
539 if (current_depth > cfg->encode_max_depth) {
540 if (!cfg->encode_keep_buffer)
541 strbuf_free(json);
542 luaL_error(l, "Cannot serialise, excessive nesting (%d)",
543 current_depth);
544 }
545}
546
547static void json_append_data(lua_State *l, json_config_t *cfg,
548 int current_depth, strbuf_t *json);
549
550/* json_append_array args:
551 * - lua_State
552 * - JSON strbuf
553 * - Size of passwd Lua array (top of stack) */
554static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
555 strbuf_t *json, int array_length)
556{
557 int comma, i;
558
559 strbuf_append_char(json, '[');
560
561 comma = 0;
562 for (i = 1; i <= array_length; i++) {
563 if (comma)
564 strbuf_append_char(json, ',');
565 else
566 comma = 1;
567
568 lua_rawgeti(l, -1, i);
569 json_append_data(l, cfg, current_depth, json);
570 lua_pop(l, 1);
571 }
572
573 strbuf_append_char(json, ']');
574}
575
576static void json_append_number(lua_State *l, json_config_t *cfg,
577 strbuf_t *json, int lindex)
578{
579 double num = lua_tonumber(l, lindex);
580 int len;
581
582 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num)))
583 json_encode_exception(l, cfg, json, lindex, "must not be NaN or Inf");
584
585 if (isnan(num)) {
586 /* Some platforms may print -nan, just hard code it */
587 strbuf_append_mem(json, "nan", 3);
588 } else {
589 strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE);
590 len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision);
591 strbuf_extend_length(json, len);
592 }
593}
594
595static void json_append_object(lua_State *l, json_config_t *cfg,
596 int current_depth, strbuf_t *json)
597{
598 int comma, keytype;
599
600 /* Object */
601 strbuf_append_char(json, '{');
602
603 lua_pushnil(l);
604 /* table, startkey */
605 comma = 0;
606 while (lua_next(l, -2) != 0) {
607 if (comma)
608 strbuf_append_char(json, ',');
609 else
610 comma = 1;
611
612 /* table, key, value */
613 keytype = lua_type(l, -2);
614 if (keytype == LUA_TNUMBER) {
615 strbuf_append_char(json, '"');
616 json_append_number(l, cfg, json, -2);
617 strbuf_append_mem(json, "\":", 2);
618 } else if (keytype == LUA_TSTRING) {
619 json_append_string(l, json, -2);
620 strbuf_append_char(json, ':');
621 } else {
622 json_encode_exception(l, cfg, json, -2,
623 "table key must be a number or string");
624 /* never returns */
625 }
626
627 /* table, key, value */
628 json_append_data(l, cfg, current_depth, json);
629 lua_pop(l, 1);
630 /* table, key */
631 }
632
633 strbuf_append_char(json, '}');
634}
635
636/* Serialise Lua data into JSON string. */
637static void json_append_data(lua_State *l, json_config_t *cfg,
638 int current_depth, strbuf_t *json)
639{
640 int len;
641
642 switch (lua_type(l, -1)) {
643 case LUA_TSTRING:
644 json_append_string(l, json, -1);
645 break;
646 case LUA_TNUMBER:
647 json_append_number(l, cfg, json, -1);
648 break;
649 case LUA_TBOOLEAN:
650 if (lua_toboolean(l, -1))
651 strbuf_append_mem(json, "true", 4);
652 else
653 strbuf_append_mem(json, "false", 5);
654 break;
655 case LUA_TTABLE:
656 len = lua_array_length(l, cfg, json);
657 current_depth++;
658 json_check_encode_depth(l, cfg, current_depth, json);
659 if (len > 0)
660 json_append_array(l, cfg, current_depth, json, len);
661 else
662 json_append_object(l, cfg, current_depth, json);
663 break;
664 case LUA_TNIL:
665 strbuf_append_mem(json, "null", 4);
666 break;
667 case LUA_TLIGHTUSERDATA:
668 if (lua_touserdata(l, -1) == NULL) {
669 strbuf_append_mem(json, "null", 4);
670 break;
671 }
672 default:
673 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
674 * and LUA_TLIGHTUSERDATA) cannot be serialised */
675 json_encode_exception(l, cfg, json, -1, "type not supported");
676 /* never returns */
677 }
678}
679
680static int json_encode(lua_State *l)
681{
682 json_config_t *cfg;
683 strbuf_t local_encode_buf;
684 strbuf_t *encode_buf;
685 char *json;
686 int len;
687
688 /* Can't use json_verify_arg_count() since we need to ensure
689 * there is only 1 argument */
690 luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
691
692 cfg = json_fetch_config(l);
693
694 if (!cfg->encode_keep_buffer) {
695 /* Use private buffer */
696 encode_buf = &local_encode_buf;
697 strbuf_init(encode_buf, 0);
698 } else {
699 /* Reuse existing buffer */
700 encode_buf = &cfg->encode_buf;
701 strbuf_reset(encode_buf);
702 }
703
704 json_append_data(l, cfg, 0, encode_buf);
705 json = strbuf_string(encode_buf, &len);
706
707 lua_pushlstring(l, json, len);
708
709 if (!cfg->encode_keep_buffer)
710 strbuf_free(encode_buf);
711
712 return 1;
713}
714
715/* ===== DECODING ===== */
716
717static void json_process_value(lua_State *l, json_parse_t *json,
718 json_token_t *token);
719
720static int hexdigit2int(char hex)
721{
722 if ('0' <= hex && hex <= '9')
723 return hex - '0';
724
725 /* Force lowercase */
726 hex |= 0x20;
727 if ('a' <= hex && hex <= 'f')
728 return 10 + hex - 'a';
729
730 return -1;
731}
732
733static int decode_hex4(const char *hex)
734{
735 int digit[4];
736 int i;
737
738 /* Convert ASCII hex digit to numeric digit
739 * Note: this returns an error for invalid hex digits, including
740 * NULL */
741 for (i = 0; i < 4; i++) {
742 digit[i] = hexdigit2int(hex[i]);
743 if (digit[i] < 0) {
744 return -1;
745 }
746 }
747
748 return (digit[0] << 12) +
749 (digit[1] << 8) +
750 (digit[2] << 4) +
751 digit[3];
752}
753
754/* Converts a Unicode codepoint to UTF-8.
755 * Returns UTF-8 string length, and up to 4 bytes in *utf8 */
756static int codepoint_to_utf8(char *utf8, int codepoint)
757{
758 /* 0xxxxxxx */
759 if (codepoint <= 0x7F) {
760 utf8[0] = codepoint;
761 return 1;
762 }
763
764 /* 110xxxxx 10xxxxxx */
765 if (codepoint <= 0x7FF) {
766 utf8[0] = (codepoint >> 6) | 0xC0;
767 utf8[1] = (codepoint & 0x3F) | 0x80;
768 return 2;
769 }
770
771 /* 1110xxxx 10xxxxxx 10xxxxxx */
772 if (codepoint <= 0xFFFF) {
773 utf8[0] = (codepoint >> 12) | 0xE0;
774 utf8[1] = ((codepoint >> 6) & 0x3F) | 0x80;
775 utf8[2] = (codepoint & 0x3F) | 0x80;
776 return 3;
777 }
778
779 /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
780 if (codepoint <= 0x1FFFFF) {
781 utf8[0] = (codepoint >> 18) | 0xF0;
782 utf8[1] = ((codepoint >> 12) & 0x3F) | 0x80;
783 utf8[2] = ((codepoint >> 6) & 0x3F) | 0x80;
784 utf8[3] = (codepoint & 0x3F) | 0x80;
785 return 4;
786 }
787
788 return 0;
789}
790
791
792/* Called when index pointing to beginning of UTF-16 code escape: \uXXXX
793 * \u is guaranteed to exist, but the remaining hex characters may be
794 * missing.
795 * Translate to UTF-8 and append to temporary token string.
796 * Must advance index to the next character to be processed.
797 * Returns: 0 success
798 * -1 error
799 */
800static int json_append_unicode_escape(json_parse_t *json)
801{
802 char utf8[4]; /* Surrogate pairs require 4 UTF-8 bytes */
803 int codepoint;
804 int surrogate_low;
805 int len;
806 int escape_len = 6;
807
808 /* Fetch UTF-16 code unit */
809 codepoint = decode_hex4(&json->data[json->index + 2]);
810 if (codepoint < 0)
811 return -1;
812
813 /* UTF-16 surrogate pairs take the following 2 byte form:
814 * 11011 x yyyyyyyyyy
815 * When x = 0: y is the high 10 bits of the codepoint
816 * x = 1: y is the low 10 bits of the codepoint
817 *
818 * Check for a surrogate pair (high or low) */
819 if ((codepoint & 0xF800) == 0xD800) {
820 /* Error if the 1st surrogate is not high */
821 if (codepoint & 0x400)
822 return -1;
823
824 /* Ensure the next code is a unicode escape */
825 if (json->data[json->index + escape_len] != '\\' ||
826 json->data[json->index + escape_len + 1] != 'u') {
827 return -1;
828 }
829
830 /* Fetch the next codepoint */
831 surrogate_low = decode_hex4(&json->data[json->index + 2 + escape_len]);
832 if (surrogate_low < 0)
833 return -1;
834
835 /* Error if the 2nd code is not a low surrogate */
836 if ((surrogate_low & 0xFC00) != 0xDC00)
837 return -1;
838
839 /* Calculate Unicode codepoint */
840 codepoint = (codepoint & 0x3FF) << 10;
841 surrogate_low &= 0x3FF;
842 codepoint = (codepoint | surrogate_low) + 0x10000;
843 escape_len = 12;
844 }
845
846 /* Convert codepoint to UTF-8 */
847 len = codepoint_to_utf8(utf8, codepoint);
848 if (!len)
849 return -1;
850
851 /* Append bytes and advance parse index */
852 strbuf_append_mem_unsafe(json->tmp, utf8, len);
853 json->index += escape_len;
854
855 return 0;
856}
857
858static void json_set_token_error(json_token_t *token, json_parse_t *json,
859 const char *errtype)
860{
861 token->type = T_ERROR;
862 token->index = json->index;
863 token->value.string = errtype;
864}
865
866static void json_next_string_token(json_parse_t *json, json_token_t *token)
867{
868 char *escape2char = json->cfg->escape2char;
869 char ch;
870
871 /* Caller must ensure a string is next */
872 assert(json->data[json->index] == '"');
873
874 /* Skip " */
875 json->index++;
876
877 /* json->tmp is the temporary strbuf used to accumulate the
878 * decoded string value.
879 * json->tmp is sized to handle JSON containing only a string value.
880 */
881 strbuf_reset(json->tmp);
882
883 while ((ch = json->data[json->index]) != '"') {
884 if (!ch) {
885 /* Premature end of the string */
886 json_set_token_error(token, json, "unexpected end of string");
887 return;
888 }
889
890 /* Handle escapes */
891 if (ch == '\\') {
892 /* Fetch escape character */
893 ch = json->data[json->index + 1];
894
895 /* Translate escape code and append to tmp string */
896 ch = escape2char[(unsigned char)ch];
897 if (ch == 'u') {
898 if (json_append_unicode_escape(json) == 0)
899 continue;
900
901 json_set_token_error(token, json,
902 "invalid unicode escape code");
903 return;
904 }
905 if (!ch) {
906 json_set_token_error(token, json, "invalid escape code");
907 return;
908 }
909
910 /* Skip '\' */
911 json->index++;
912 }
913 /* Append normal character or translated single character
914 * Unicode escapes are handled above */
915 strbuf_append_char_unsafe(json->tmp, ch);
916 json->index++;
917 }
918 json->index++; /* Eat final quote (") */
919
920 strbuf_ensure_null(json->tmp);
921
922 token->type = T_STRING;
923 token->value.string = strbuf_string(json->tmp, &token->string_len);
924}
925
926/* JSON numbers should take the following form:
927 * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)?
928 *
929 * json_next_number_token() uses strtod() which allows other forms:
930 * - numbers starting with '+'
931 * - NaN, -NaN, infinity, -infinity
932 * - hexadecimal numbers
933 * - numbers with leading zeros
934 *
935 * json_is_invalid_number() detects "numbers" which may pass strtod()'s
936 * error checking, but should not be allowed with strict JSON.
937 *
938 * json_is_invalid_number() may pass numbers which cause strtod()
939 * to generate an error.
940 */
941static int json_is_invalid_number(json_parse_t *json)
942{
943 int i = json->index;
944
945 /* Reject numbers starting with + */
946 if (json->data[i] == '+')
947 return 1;
948
949 /* Skip minus sign if it exists */
950 if (json->data[i] == '-')
951 i++;
952
953 /* Reject numbers starting with 0x, or leading zeros */
954 if (json->data[i] == '0') {
955 int ch2 = json->data[i + 1];
956
957 if ((ch2 | 0x20) == 'x' || /* Hex */
958 ('0' <= ch2 && ch2 <= '9')) /* Leading zero */
959 return 1;
960
961 return 0;
962 } else if (json->data[i] <= '9') {
963 return 0; /* Ordinary number */
964 }
965
966 /* Reject inf/nan */
967 if (!strncasecmp(&json->data[i], "inf", 3))
968 return 1;
969 if (!strncasecmp(&json->data[i], "nan", 3))
970 return 1;
971
972 /* Pass all other numbers which may still be invalid, but
973 * strtod() will catch them. */
974 return 0;
975}
976
977static void json_next_number_token(json_parse_t *json, json_token_t *token)
978{
979 const char *startptr;
980 char *endptr;
981
982 token->type = T_NUMBER;
983 startptr = &json->data[json->index];
984 token->value.number = fpconv_strtod(&json->data[json->index], &endptr);
985 if (startptr == endptr)
986 json_set_token_error(token, json, "invalid number");
987 else
988 json->index += endptr - startptr; /* Skip the processed number */
989
990 return;
991}
992
993/* Fills in the token struct.
994 * T_STRING will return a pointer to the json_parse_t temporary string
995 * T_ERROR will leave the json->index pointer at the error.
996 */
997static void json_next_token(json_parse_t *json, json_token_t *token)
998{
999 json_token_type_t *ch2token = json->cfg->ch2token;
1000 int ch;
1001
1002 /* Eat whitespace. FIXME: UGLY */
1003 token->type = ch2token[(unsigned char)json->data[json->index]];
1004 while (token->type == T_WHITESPACE)
1005 token->type = ch2token[(unsigned char)json->data[++json->index]];
1006
1007 token->index = json->index;
1008
1009 /* Don't advance the pointer for an error or the end */
1010 if (token->type == T_ERROR) {
1011 json_set_token_error(token, json, "invalid token");
1012 return;
1013 }
1014
1015 if (token->type == T_END) {
1016 return;
1017 }
1018
1019 /* Found a known single character token, advance index and return */
1020 if (token->type != T_UNKNOWN) {
1021 json->index++;
1022 return;
1023 }
1024
1025 /* Process characters which triggered T_UNKNOWN */
1026 ch = json->data[json->index];
1027
1028 /* Must use strncmp() to match the front of the JSON string.
1029 * JSON identifier must be lowercase.
1030 * When strict_numbers if disabled, either case is allowed for
1031 * Infinity/NaN (since we are no longer following the spec..) */
1032 if (ch == '"') {
1033 json_next_string_token(json, token);
1034 return;
1035 } else if (ch == '-' || ('0' <= ch && ch <= '9')) {
1036 if (json->cfg->decode_refuse_badnum && json_is_invalid_number(json)) {
1037 json_set_token_error(token, json, "invalid number");
1038 return;
1039 }
1040 json_next_number_token(json, token);
1041 return;
1042 } else if (!strncmp(&json->data[json->index], "true", 4)) {
1043 token->type = T_BOOLEAN;
1044 token->value.boolean = 1;
1045 json->index += 4;
1046 return;
1047 } else if (!strncmp(&json->data[json->index], "false", 5)) {
1048 token->type = T_BOOLEAN;
1049 token->value.boolean = 0;
1050 json->index += 5;
1051 return;
1052 } else if (!strncmp(&json->data[json->index], "null", 4)) {
1053 token->type = T_NULL;
1054 json->index += 4;
1055 return;
1056 } else if (!json->cfg->decode_refuse_badnum &&
1057 json_is_invalid_number(json)) {
1058 /* When refuse_badnum is disabled, only attempt to process
1059 * numbers we know are invalid JSON (Inf, NaN, hex)
1060 * This is required to generate an appropriate token error,
1061 * otherwise all bad tokens will register as "invalid number"
1062 */
1063 json_next_number_token(json, token);
1064 return;
1065 }
1066
1067 /* Token starts with t/f/n but isn't recognised above. */
1068 json_set_token_error(token, json, "invalid token");
1069}
1070
1071/* This function does not return.
1072 * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED.
1073 * The only supported exception is the temporary parser string
1074 * json->tmp struct.
1075 * json and token should exist on the stack somewhere.
1076 * luaL_error() will long_jmp and release the stack */
1077static void json_throw_parse_error(lua_State *l, json_parse_t *json,
1078 const char *exp, json_token_t *token)
1079{
1080 const char *found;
1081
1082 strbuf_free(json->tmp);
1083
1084 if (token->type == T_ERROR)
1085 found = token->value.string;
1086 else
1087 found = json_token_type_name[token->type];
1088
1089 /* Note: token->index is 0 based, display starting from 1 */
1090 luaL_error(l, "Expected %s but found %s at character %d",
1091 exp, found, token->index + 1);
1092}
1093
1094static void json_decode_checkstack(lua_State *l, json_parse_t *json, int n)
1095{
1096 if (lua_checkstack(l, n))
1097 return;
1098
1099 strbuf_free(json->tmp);
1100 luaL_error(l, "Too many nested data structures");
1101}
1102
1103static void json_parse_object_context(lua_State *l, json_parse_t *json)
1104{
1105 json_token_t token;
1106
1107 /* 3 slots required:
1108 * .., table, key, value */
1109 json_decode_checkstack(l, json, 3);
1110
1111 lua_newtable(l);
1112
1113 json_next_token(json, &token);
1114
1115 /* Handle empty objects */
1116 if (token.type == T_OBJ_END) {
1117 return;
1118 }
1119
1120 while (1) {
1121 if (token.type != T_STRING)
1122 json_throw_parse_error(l, json, "object key string", &token);
1123
1124 /* Push key */
1125 lua_pushlstring(l, token.value.string, token.string_len);
1126
1127 json_next_token(json, &token);
1128 if (token.type != T_COLON)
1129 json_throw_parse_error(l, json, "colon", &token);
1130
1131 /* Fetch value */
1132 json_next_token(json, &token);
1133 json_process_value(l, json, &token);
1134
1135 /* Set key = value */
1136 lua_rawset(l, -3);
1137
1138 json_next_token(json, &token);
1139
1140 if (token.type == T_OBJ_END)
1141 return;
1142
1143 if (token.type != T_COMMA)
1144 json_throw_parse_error(l, json, "comma or object end", &token);
1145
1146 json_next_token(json, &token);
1147 }
1148}
1149
1150/* Handle the array context */
1151static void json_parse_array_context(lua_State *l, json_parse_t *json)
1152{
1153 json_token_t token;
1154 int i;
1155
1156 /* 2 slots required:
1157 * .., table, value */
1158 json_decode_checkstack(l, json, 2);
1159
1160 lua_newtable(l);
1161
1162 json_next_token(json, &token);
1163
1164 /* Handle empty arrays */
1165 if (token.type == T_ARR_END)
1166 return;
1167
1168 for (i = 1; ; i++) {
1169 json_process_value(l, json, &token);
1170 lua_rawseti(l, -2, i); /* arr[i] = value */
1171
1172 json_next_token(json, &token);
1173
1174 if (token.type == T_ARR_END)
1175 return;
1176
1177 if (token.type != T_COMMA)
1178 json_throw_parse_error(l, json, "comma or array end", &token);
1179
1180 json_next_token(json, &token);
1181 }
1182}
1183
1184/* Handle the "value" context */
1185static void json_process_value(lua_State *l, json_parse_t *json,
1186 json_token_t *token)
1187{
1188 switch (token->type) {
1189 case T_STRING:
1190 lua_pushlstring(l, token->value.string, token->string_len);
1191 break;;
1192 case T_NUMBER:
1193 lua_pushnumber(l, token->value.number);
1194 break;;
1195 case T_BOOLEAN:
1196 lua_pushboolean(l, token->value.boolean);
1197 break;;
1198 case T_OBJ_BEGIN:
1199 json_parse_object_context(l, json);
1200 break;;
1201 case T_ARR_BEGIN:
1202 json_parse_array_context(l, json);
1203 break;;
1204 case T_NULL:
1205 /* In Lua, setting "t[k] = nil" will delete k from the table.
1206 * Hence a NULL pointer lightuserdata object is used instead */
1207 lua_pushlightuserdata(l, NULL);
1208 break;;
1209 default:
1210 json_throw_parse_error(l, json, "value", token);
1211 }
1212}
1213
1214/* json_text must be null terminated string */
1215static void lua_json_decode(lua_State *l, const char *json_text, int json_len)
1216{
1217 json_parse_t json;
1218 json_token_t token;
1219
1220 json.cfg = json_fetch_config(l);
1221 json.data = json_text;
1222 json.index = 0;
1223
1224 /* Ensure the temporary buffer can hold the entire string.
1225 * This means we no longer need to do length checks since the decoded
1226 * string must be smaller than the entire json string */
1227 json.tmp = strbuf_new(json_len);
1228
1229 json_next_token(&json, &token);
1230 json_process_value(l, &json, &token);
1231
1232 /* Ensure there is no more input left */
1233 json_next_token(&json, &token);
1234
1235 if (token.type != T_END)
1236 json_throw_parse_error(l, &json, "the end", &token);
1237
1238 strbuf_free(json.tmp);
1239}
1240
1241static int json_decode(lua_State *l)
1242{
1243 const char *json;
1244 size_t len;
1245
1246 json_verify_arg_count(l, 1);
1247
1248 json = luaL_checklstring(l, 1, &len);
1249
1250 /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
1251 *
1252 * CJSON can support any simple data type, hence only the first
1253 * character is guaranteed to be ASCII (at worst: '"'). This is
1254 * still enough to detect whether the wrong encoding is in use. */
1255 if (len >= 2 && (!json[0] || !json[1]))
1256 luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");
1257
1258 lua_json_decode(l, json, len);
1259
1260 return 1;
1261}
1262
1263/* ===== INITIALISATION ===== */
1264
1265#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
1266/* Compatibility for Lua 5.1.
1267 *
1268 * luaL_setfuncs() is used to create a module table where the functions have
1269 * json_config_t as their first upvalue. Code borrowed from Lua 5.2 source. */
1270static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
1271{
1272 int i;
1273
1274 luaL_checkstack(l, nup, "too many upvalues");
1275 for (; reg->name != NULL; reg++) { /* fill the table with given functions */
1276 for (i = 0; i < nup; i++) /* copy upvalues to the top */
1277 lua_pushvalue(l, -nup);
1278 lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
1279 lua_setfield(l, -(nup + 2), reg->name);
1280 }
1281 lua_pop(l, nup); /* remove upvalues */
1282}
1283#endif
1284
1285static int lua_cjson_new(lua_State *l)
1286{
1287 luaL_Reg reg[] = {
1288 { "encode", json_encode },
1289 { "decode", json_decode },
1290 { "encode_sparse_array", json_cfg_encode_sparse_array },
1291 { "encode_max_depth", json_cfg_encode_max_depth },
1292 { "encode_number_precision", json_cfg_encode_number_precision },
1293 { "encode_keep_buffer", json_cfg_encode_keep_buffer },
1294 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers },
1295 { "new", lua_cjson_new },
1296 { NULL, NULL }
1297 };
1298
1299 /* Initialise number conversions */
1300 fpconv_init();
1301
1302 /* cjson module table */
1303 lua_newtable(l);
1304
1305 /* Register functions with config data as upvalue */
1306 json_create_config(l);
1307 luaL_setfuncs(l, reg, 1);
1308
1309 /* Set cjson.null */
1310 lua_pushlightuserdata(l, NULL);
1311 lua_setfield(l, -2, "null");
1312
1313 /* Set module name / version fields */
1314 lua_pushliteral(l, CJSON_MODNAME);
1315 lua_setfield(l, -2, "_NAME");
1316 lua_pushliteral(l, CJSON_VERSION);
1317 lua_setfield(l, -2, "_VERSION");
1318 lua_pushliteral(l, CJSON_VERSION);
1319 lua_setfield(l, -2, "version");
1320
1321 return 1;
1322}
1323
1324int luaopen_cjson(lua_State *l)
1325{
1326 lua_cjson_new(l);
1327
1328#if !defined(DISABLE_CJSON_GLOBAL) && (!defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502)
1329 /* Register a global "cjson" table to maintain compatibility with earlier
1330 * versions of Lua CJSON which used luaL_register() under Lua 5.1.
1331 *
1332 * From Lua 5.2 onwards, Lua CJSON does not automatically register a global
1333 * table.
1334 */
1335 lua_pushvalue(l, -1);
1336 lua_setglobal(l, CJSON_MODNAME);
1337#endif
1338
1339 /* Return cjson table */
1340 return 1;
1341}
1342
1343/* vi:ai et sw=4 ts=4:
1344 */