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