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