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