diff options
-rw-r--r-- | lua_cjson.c | 174 | ||||
-rw-r--r-- | manual.txt | 96 | ||||
-rwxr-xr-x | tests/test.lua | 21 |
3 files changed, 180 insertions, 111 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index bdfa7d4..1e9e91d 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -64,14 +64,14 @@ | |||
64 | #define DEFAULT_SPARSE_SAFE 10 | 64 | #define DEFAULT_SPARSE_SAFE 10 |
65 | #define DEFAULT_ENCODE_MAX_DEPTH 20 | 65 | #define DEFAULT_ENCODE_MAX_DEPTH 20 |
66 | #define DEFAULT_DECODE_MAX_DEPTH 20 | 66 | #define DEFAULT_DECODE_MAX_DEPTH 20 |
67 | #define DEFAULT_ENCODE_REFUSE_BADNUM 1 | 67 | #define DEFAULT_ENCODE_INVALID_NUMBERS 0 |
68 | #define DEFAULT_DECODE_REFUSE_BADNUM 0 | 68 | #define DEFAULT_DECODE_INVALID_NUMBERS 1 |
69 | #define DEFAULT_ENCODE_KEEP_BUFFER 1 | 69 | #define DEFAULT_ENCODE_KEEP_BUFFER 1 |
70 | #define DEFAULT_ENCODE_NUMBER_PRECISION 14 | 70 | #define DEFAULT_ENCODE_NUMBER_PRECISION 14 |
71 | 71 | ||
72 | #ifdef DISABLE_INVALID_NUMBERS | 72 | #ifdef DISABLE_INVALID_NUMBERS |
73 | #undef DEFAULT_DECODE_REFUSE_BADNUM | 73 | #undef DEFAULT_DECODE_INVALID_NUMBERS |
74 | #define DEFAULT_DECODE_REFUSE_BADNUM 1 | 74 | #define DEFAULT_DECODE_INVALID_NUMBERS 0 |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | typedef enum { | 77 | typedef enum { |
@@ -121,11 +121,11 @@ typedef struct { | |||
121 | int encode_sparse_ratio; | 121 | int encode_sparse_ratio; |
122 | int encode_sparse_safe; | 122 | int encode_sparse_safe; |
123 | int encode_max_depth; | 123 | int encode_max_depth; |
124 | int encode_refuse_badnum; | 124 | int encode_invalid_numbers; /* 2 => Encode as "null" */ |
125 | int encode_number_precision; | 125 | int encode_number_precision; |
126 | int encode_keep_buffer; | 126 | int encode_keep_buffer; |
127 | 127 | ||
128 | int decode_refuse_badnum; | 128 | int decode_invalid_numbers; |
129 | int decode_max_depth; | 129 | int decode_max_depth; |
130 | } json_config_t; | 130 | } json_config_t; |
131 | 131 | ||
@@ -259,6 +259,29 @@ static int json_integer_option(lua_State *l, int *setting, int min, int max) | |||
259 | return 1; | 259 | return 1; |
260 | } | 260 | } |
261 | 261 | ||
262 | /* Process enumerated arguments for a configuration function */ | ||
263 | static int json_enum_option(lua_State *l, int *setting, | ||
264 | const char **options, int bool_value) | ||
265 | { | ||
266 | static const char *bool_options[] = { "off", "on", NULL }; | ||
267 | |||
268 | if (!options) { | ||
269 | options = bool_options; | ||
270 | bool_value = 1; | ||
271 | } | ||
272 | |||
273 | if (lua_gettop(l)) { | ||
274 | if (lua_isboolean(l, 1)) | ||
275 | *setting = lua_toboolean(l, 1) * bool_value; | ||
276 | else | ||
277 | *setting = luaL_checkoption(l, 1, NULL, options); | ||
278 | } | ||
279 | |||
280 | lua_pushstring(l, options[*setting]); | ||
281 | |||
282 | return 1; | ||
283 | } | ||
284 | |||
262 | /* Configures the maximum number of nested arrays/objects allowed when | 285 | /* Configures the maximum number of nested arrays/objects allowed when |
263 | * encoding */ | 286 | * encoding */ |
264 | static int json_cfg_encode_max_depth(lua_State *l) | 287 | static int json_cfg_encode_max_depth(lua_State *l) |
@@ -288,18 +311,12 @@ static int json_cfg_encode_number_precision(lua_State *l) | |||
288 | /* Configures JSON encoding buffer persistence */ | 311 | /* Configures JSON encoding buffer persistence */ |
289 | static int json_cfg_encode_keep_buffer(lua_State *l) | 312 | static int json_cfg_encode_keep_buffer(lua_State *l) |
290 | { | 313 | { |
291 | json_config_t *cfg; | 314 | json_config_t *cfg = json_fetch_config(l); |
292 | int old_value; | 315 | int old_value; |
293 | 316 | ||
294 | json_verify_arg_count(l, 1); | ||
295 | cfg = json_fetch_config(l); | ||
296 | |||
297 | old_value = cfg->encode_keep_buffer; | 317 | old_value = cfg->encode_keep_buffer; |
298 | 318 | ||
299 | if (lua_gettop(l)) { | 319 | json_enum_option(l, &cfg->encode_keep_buffer, NULL, 1); |
300 | luaL_checktype(l, 1, LUA_TBOOLEAN); | ||
301 | cfg->encode_keep_buffer = lua_toboolean(l, 1); | ||
302 | } | ||
303 | 320 | ||
304 | /* Init / free the buffer if the setting has changed */ | 321 | /* Init / free the buffer if the setting has changed */ |
305 | if (old_value ^ cfg->encode_keep_buffer) { | 322 | if (old_value ^ cfg->encode_keep_buffer) { |
@@ -309,62 +326,76 @@ static int json_cfg_encode_keep_buffer(lua_State *l) | |||
309 | strbuf_free(&cfg->encode_buf); | 326 | strbuf_free(&cfg->encode_buf); |
310 | } | 327 | } |
311 | 328 | ||
312 | lua_pushboolean(l, cfg->encode_keep_buffer); | ||
313 | |||
314 | return 1; | 329 | return 1; |
315 | } | 330 | } |
316 | 331 | ||
317 | /* On argument: decode enum and set config variables | 332 | static int json_cfg_encode_invalid_numbers(lua_State *l) |
318 | * **options must point to a NULL terminated array of 4 enums | ||
319 | * Returns: current enum value */ | ||
320 | static void json_enum_option(lua_State *l, const char **options, | ||
321 | int *opt1, int *opt2) | ||
322 | { | 333 | { |
323 | int setting; | 334 | static const char *options[] = { "off", "on", "null", NULL }; |
335 | json_config_t *cfg = json_fetch_config(l); | ||
324 | 336 | ||
325 | if (lua_gettop(l)) { | 337 | json_enum_option(l, &cfg->encode_invalid_numbers, options, 1); |
326 | if (lua_isboolean(l, 1)) | ||
327 | setting = lua_toboolean(l, 1) * 3; | ||
328 | else | ||
329 | setting = luaL_checkoption(l, 1, NULL, options); | ||
330 | 338 | ||
331 | *opt1 = setting & 1 ? 1 : 0; | 339 | #if DISABLE_INVALID_NUMBERS |
332 | *opt2 = setting & 2 ? 1 : 0; | 340 | if (cfg->encode_invalid_numbers == 1) { |
333 | } else { | 341 | cfg->encode_invalid_numbers = 0; |
334 | setting = *opt1 | (*opt2 << 1); | 342 | luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported."); |
335 | } | 343 | } |
344 | #endif | ||
336 | 345 | ||
337 | if (setting) | 346 | return 1; |
338 | lua_pushstring(l, options[setting]); | ||
339 | else | ||
340 | lua_pushboolean(l, 0); | ||
341 | } | 347 | } |
342 | 348 | ||
349 | static int json_cfg_decode_invalid_numbers(lua_State *l) | ||
350 | { | ||
351 | json_config_t *cfg = json_fetch_config(l); | ||
352 | |||
353 | json_enum_option(l, &cfg->decode_invalid_numbers, NULL, 1); | ||
354 | |||
355 | #if DISABLE_INVALID_NUMBERS | ||
356 | if (cfg->decode_invalid_numbers) { | ||
357 | cfg->decode_invalid_numbers = 0; | ||
358 | luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported."); | ||
359 | } | ||
360 | #endif | ||
343 | 361 | ||
344 | /* When enabled, rejects: NaN, Infinity, hexadecimal numbers */ | 362 | return 1; |
363 | } | ||
364 | |||
365 | /* When enabled, rejects: NaN, Infinity, hexadecimal numbers. | ||
366 | * | ||
367 | * This function has been deprecated and may be removed in future. */ | ||
345 | static int json_cfg_refuse_invalid_numbers(lua_State *l) | 368 | static int json_cfg_refuse_invalid_numbers(lua_State *l) |
346 | { | 369 | { |
347 | static const char *options_enc_dec[] = { "none", "encode", "decode", | 370 | static const char *options[] = { "none", "encode", "decode", "both", NULL }; |
348 | "both", NULL }; | 371 | json_config_t *cfg = json_fetch_config(l); |
349 | json_config_t *cfg; | 372 | int have_arg, setting; |
350 | 373 | ||
351 | json_verify_arg_count(l, 1); | 374 | have_arg = lua_gettop(l); |
352 | cfg = json_fetch_config(l); | ||
353 | 375 | ||
354 | json_enum_option(l, options_enc_dec, | 376 | /* Map config variables to options list index */ |
355 | &cfg->encode_refuse_badnum, | 377 | setting = !cfg->encode_invalid_numbers + /* bit 0 */ |
356 | &cfg->decode_refuse_badnum); | 378 | (!cfg->decode_invalid_numbers << 1); /* bit 1 */ |
379 | |||
380 | json_enum_option(l, &setting, options, 3); | ||
381 | |||
382 | /* Map options list index to config variables | ||
383 | * | ||
384 | * Only update the config variables when an argument has been provided. | ||
385 | * Otherwise a "null" encoding setting may inadvertently be disabled. */ | ||
386 | if (have_arg) { | ||
387 | cfg->encode_invalid_numbers = !(setting & 1); | ||
388 | cfg->decode_invalid_numbers = !(setting & 2); | ||
357 | 389 | ||
358 | #if DISABLE_INVALID_NUMBERS | 390 | #if DISABLE_INVALID_NUMBERS |
359 | /* Some non-POSIX platforms don't handle double <-> string translations | 391 | if (cfg->encode_invalid_numbers || cfg->decode_invalid_numbers) { |
360 | * for Infinity/NaN/hexadecimal properly. Throw an error if the | 392 | cfg->encode_invalid_numbers = cfg->decode_invalid_numbers = 0; |
361 | * user attempts to enable them. */ | 393 | luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported."); |
362 | if (!cfg->encode_refuse_badnum || !cfg->decode_refuse_badnum) { | 394 | } |
363 | cfg->encode_refuse_badnum = cfg->decode_refuse_badnum = 1; | ||
364 | luaL_error(l, "Infinity, NaN, and/or hexadecimal numbers are not supported."); | ||
365 | } | ||
366 | #endif | 395 | #endif |
367 | 396 | ||
397 | } | ||
398 | |||
368 | return 1; | 399 | return 1; |
369 | } | 400 | } |
370 | 401 | ||
@@ -398,8 +429,8 @@ static void json_create_config(lua_State *l) | |||
398 | cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; | 429 | cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; |
399 | cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH; | 430 | cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH; |
400 | cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH; | 431 | cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH; |
401 | cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; | 432 | cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS; |
402 | cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; | 433 | cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS; |
403 | cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; | 434 | cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; |
404 | cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; | 435 | cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; |
405 | 436 | ||
@@ -589,17 +620,28 @@ static void json_append_number(lua_State *l, json_config_t *cfg, | |||
589 | double num = lua_tonumber(l, lindex); | 620 | double num = lua_tonumber(l, lindex); |
590 | int len; | 621 | int len; |
591 | 622 | ||
592 | if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num))) | 623 | if (cfg->encode_invalid_numbers == 0) { |
593 | json_encode_exception(l, cfg, json, lindex, "must not be NaN or Inf"); | 624 | /* Prevent encoding invalid numbers */ |
594 | 625 | if (isinf(num) || isnan(num)) | |
595 | if (isnan(num)) { | 626 | json_encode_exception(l, cfg, json, lindex, "must not be NaN or Inf"); |
596 | /* Some platforms may print -nan, just hard code it */ | 627 | } else if (cfg->encode_invalid_numbers == 1) { |
597 | strbuf_append_mem(json, "nan", 3); | 628 | /* Encode invalid numbers, but handle "nan" separately |
629 | * since some platforms may encode as "-nan". */ | ||
630 | if (isnan(num)) { | ||
631 | strbuf_append_mem(json, "nan", 3); | ||
632 | return; | ||
633 | } | ||
598 | } else { | 634 | } else { |
599 | strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); | 635 | /* Encode invalid numbers as "null" */ |
600 | len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision); | 636 | if (isinf(num) || isnan(num)) { |
601 | strbuf_extend_length(json, len); | 637 | strbuf_append_mem(json, "null", 4); |
638 | return; | ||
639 | } | ||
602 | } | 640 | } |
641 | |||
642 | strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); | ||
643 | len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision); | ||
644 | strbuf_extend_length(json, len); | ||
603 | } | 645 | } |
604 | 646 | ||
605 | static void json_append_object(lua_State *l, json_config_t *cfg, | 647 | static void json_append_object(lua_State *l, json_config_t *cfg, |
@@ -1046,7 +1088,7 @@ static void json_next_token(json_parse_t *json, json_token_t *token) | |||
1046 | json_next_string_token(json, token); | 1088 | json_next_string_token(json, token); |
1047 | return; | 1089 | return; |
1048 | } else if (ch == '-' || ('0' <= ch && ch <= '9')) { | 1090 | } else if (ch == '-' || ('0' <= ch && ch <= '9')) { |
1049 | if (json->cfg->decode_refuse_badnum && json_is_invalid_number(json)) { | 1091 | if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) { |
1050 | json_set_token_error(token, json, "invalid number"); | 1092 | json_set_token_error(token, json, "invalid number"); |
1051 | return; | 1093 | return; |
1052 | } | 1094 | } |
@@ -1066,9 +1108,9 @@ static void json_next_token(json_parse_t *json, json_token_t *token) | |||
1066 | token->type = T_NULL; | 1108 | token->type = T_NULL; |
1067 | json->ptr += 4; | 1109 | json->ptr += 4; |
1068 | return; | 1110 | return; |
1069 | } else if (!json->cfg->decode_refuse_badnum && | 1111 | } else if (json->cfg->decode_invalid_numbers && |
1070 | json_is_invalid_number(json)) { | 1112 | json_is_invalid_number(json)) { |
1071 | /* When refuse_badnum is disabled, only attempt to process | 1113 | /* When decode_invalid_numbers is enabled, only attempt to process |
1072 | * numbers we know are invalid JSON (Inf, NaN, hex) | 1114 | * numbers we know are invalid JSON (Inf, NaN, hex) |
1073 | * This is required to generate an appropriate token error, | 1115 | * This is required to generate an appropriate token error, |
1074 | * otherwise all bad tokens will register as "invalid number" | 1116 | * otherwise all bad tokens will register as "invalid number" |
@@ -1322,6 +1364,8 @@ static int lua_cjson_new(lua_State *l) | |||
1322 | { "decode_max_depth", json_cfg_decode_max_depth }, | 1364 | { "decode_max_depth", json_cfg_decode_max_depth }, |
1323 | { "encode_number_precision", json_cfg_encode_number_precision }, | 1365 | { "encode_number_precision", json_cfg_encode_number_precision }, |
1324 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, | 1366 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, |
1367 | { "encode_invalid_numbers", json_cfg_encode_invalid_numbers }, | ||
1368 | { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, | ||
1325 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, | 1369 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, |
1326 | { "new", lua_cjson_new }, | 1370 | { "new", lua_cjson_new }, |
1327 | { NULL, NULL } | 1371 | { NULL, NULL } |
@@ -117,8 +117,10 @@ USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing ++isinf++(3). | |||
117 | DISABLE_CJSON_GLOBAL:: Do not store module table in global "cjson" | 117 | DISABLE_CJSON_GLOBAL:: Do not store module table in global "cjson" |
118 | variable. Redundant from Lua 5.2 onwards. | 118 | variable. Redundant from Lua 5.2 onwards. |
119 | DISABLE_INVALID_NUMBERS:: Recommended on platforms where ++strtod++(3) / | 119 | DISABLE_INVALID_NUMBERS:: Recommended on platforms where ++strtod++(3) / |
120 | ++sprintf++(3) are not POSIX compliant (Eg, Windows MinGW). Restricts | 120 | ++sprintf++(3) are not POSIX compliant (Eg, Windows MinGW). Prevents |
121 | the +cjson.refuse_invalid_numbers+ runtime configuration to +true+. | 121 | +cjson.encode_invalid_numbers+ and +cjson.decode_invalid_numbers+ |
122 | from being enabled. However, +cjson.encode_invalid_numbers+ may be | ||
123 | set to +"null"+. | ||
122 | 124 | ||
123 | 125 | ||
124 | Built-in dtoa() support | 126 | Built-in dtoa() support |
@@ -154,11 +156,12 @@ text = cjson.encode(value) | |||
154 | value = cjson.decode(text) | 156 | value = cjson.decode(text) |
155 | 157 | ||
156 | -- Get and/or set Lua CJSON configuration | 158 | -- Get and/or set Lua CJSON configuration |
157 | setting = cjson.refuse_invalid_numbers([setting]) | 159 | setting = cjson.decode_invalid_numbers([setting]) |
160 | setting = cjson.encode_invalid_numbers([setting]) | ||
158 | depth = cjson.encode_max_depth([depth]) | 161 | depth = cjson.encode_max_depth([depth]) |
162 | depth = cjson.decode_max_depth([depth]) | ||
159 | convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) | 163 | convert, ratio, safe = cjson.encode_sparse_array([convert[, ratio[, safe]]]) |
160 | keep = cjson.encode_keep_buffer([keep]) | 164 | keep = cjson.encode_keep_buffer([keep]) |
161 | depth = cjson.decode_max_depth([depth]) | ||
162 | ------------ | 165 | ------------ |
163 | 166 | ||
164 | 167 | ||
@@ -226,7 +229,7 @@ can be compared with +cjson.null+ for convenience. | |||
226 | 229 | ||
227 | By default, numbers incompatible with the JSON specification (NaN, | 230 | By default, numbers incompatible with the JSON specification (NaN, |
228 | Infinity, Hexadecimal) can be decoded. This default can be changed | 231 | Infinity, Hexadecimal) can be decoded. This default can be changed |
229 | with +cjson.refuse_invalid_numbers+. | 232 | with +cjson.decode_invalid_numbers+. |
230 | 233 | ||
231 | .Example: Decoding | 234 | .Example: Decoding |
232 | [source,lua] | 235 | [source,lua] |
@@ -240,6 +243,30 @@ numeric key will be stored as a Lua +string+. Any code assuming type | |||
240 | +number+ may break. | 243 | +number+ may break. |
241 | 244 | ||
242 | 245 | ||
246 | [[decode_invalid_numbers]] | ||
247 | decode_invalid_numbers | ||
248 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
249 | |||
250 | [source,lua] | ||
251 | ------------ | ||
252 | setting = cjson.decode_invalid_numbers([setting]) | ||
253 | -- "setting" must be on of: | ||
254 | -- "off", "on", false, true | ||
255 | ------------ | ||
256 | |||
257 | Lua CJSON can throw an error when trying to parse numbers outside of | ||
258 | the JSON specification (_invalid numbers_): | ||
259 | |||
260 | - Infinity | ||
261 | - Not-a-number (NaN) | ||
262 | - Hexadecimal | ||
263 | |||
264 | By default Lua CJSON will decode _invalid numbers_. | ||
265 | |||
266 | This setting is only changed when an argument is provided. The current | ||
267 | setting is always returned. | ||
268 | |||
269 | |||
243 | [[decode_max_depth]] | 270 | [[decode_max_depth]] |
244 | decode_max_depth | 271 | decode_max_depth |
245 | ~~~~~~~~~~~~~~~~ | 272 | ~~~~~~~~~~~~~~~~ |
@@ -352,7 +379,7 @@ These defaults can be changed with: | |||
352 | 379 | ||
353 | - <<encode_max_depth,+cjson.encode_max_depth+>> | 380 | - <<encode_max_depth,+cjson.encode_max_depth+>> |
354 | - <<encode_sparse_array,+cjson.encode_sparse_array+>> | 381 | - <<encode_sparse_array,+cjson.encode_sparse_array+>> |
355 | - <<refuse_invalid_numbers,+cjson.refuse_invalid_numbers+>> | 382 | - <<encode_invalid_numbers,+cjson.encode_invalid_numbers+>> |
356 | 383 | ||
357 | .Example: Encoding | 384 | .Example: Encoding |
358 | [source,lua] | 385 | [source,lua] |
@@ -361,6 +388,30 @@ json_text = cjson.encode(value) | |||
361 | -- Returns: '[true,{"foo":"bar"}]' | 388 | -- Returns: '[true,{"foo":"bar"}]' |
362 | 389 | ||
363 | 390 | ||
391 | [[encode_invalid_numbers]] | ||
392 | encode_invalid_numbers | ||
393 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
394 | [source,lua] | ||
395 | ------------ | ||
396 | setting = cjson.encode_invalid_numbers([setting]) | ||
397 | -- "setting" must be on of: | ||
398 | -- "off", "on", "null", false, true | ||
399 | ------------ | ||
400 | |||
401 | By default, Lua CJSON will throw an error when trying to encode | ||
402 | numbers outside of the JSON specification (_invalid numbers_): | ||
403 | |||
404 | - Infinity | ||
405 | - Not-a-number (NaN) | ||
406 | |||
407 | When set to +"null"+, Lua CJSON will encode _invalid numbers_ as a | ||
408 | JSON +null+ value. This allows Infinity and NaN to be represented as | ||
409 | valid JSON. | ||
410 | |||
411 | This setting is only changed when an argument is provided. The current | ||
412 | setting is always returned. | ||
413 | |||
414 | |||
364 | encode_keep_buffer | 415 | encode_keep_buffer |
365 | ~~~~~~~~~~~~~~~~~~ | 416 | ~~~~~~~~~~~~~~~~~~ |
366 | 417 | ||
@@ -473,39 +524,6 @@ cjson.encode({ [1000] = "excessively sparse" }) | |||
473 | -- Returns: '{"1000":"excessively sparse"}' | 524 | -- Returns: '{"1000":"excessively sparse"}' |
474 | 525 | ||
475 | 526 | ||
476 | [[refuse_invalid_numbers]] | ||
477 | refuse_invalid_numbers | ||
478 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
479 | |||
480 | [source,lua] | ||
481 | ------------ | ||
482 | setting = cjson.refuse_invalid_numbers([setting]) | ||
483 | -- "setting" must be on of: | ||
484 | -- false, "encode", "decode", "both", true | ||
485 | ------------ | ||
486 | |||
487 | Lua CJSON can throw an error for numbers outside of the JSON | ||
488 | specification (_invalid numbers_): | ||
489 | |||
490 | - Infinity | ||
491 | - NaN | ||
492 | - Hexadecimal | ||
493 | |||
494 | By default Lua CJSON will decode _invalid numbers_, but will refuse to | ||
495 | encode them. | ||
496 | |||
497 | This setting is only changed when an argument is provided. The current | ||
498 | setting is always returned. | ||
499 | |||
500 | This setting can be configured separately for encoding and/or | ||
501 | decoding: | ||
502 | |||
503 | [horizontal] | ||
504 | Enabled:: An error will be generated if an _invalid number_ is found. | ||
505 | Disabled for encoding:: NaN and Infinity can be encoded. | ||
506 | Disabled for decoding:: All numbers supported by +strtod+(3) will be parsed. | ||
507 | |||
508 | |||
509 | API (Variables) | 527 | API (Variables) |
510 | --------------- | 528 | --------------- |
511 | 529 | ||
diff --git a/tests/test.lua b/tests/test.lua index 0434a38..a4ebafe 100755 --- a/tests/test.lua +++ b/tests/test.lua | |||
@@ -138,22 +138,28 @@ local encode_error_tests = { | |||
138 | { json.encode, { function () end }, | 138 | { json.encode, { function () end }, |
139 | false, { "Cannot serialise function: type not supported" } }, | 139 | false, { "Cannot serialise function: type not supported" } }, |
140 | function () | 140 | function () |
141 | json.refuse_invalid_numbers("encode") | 141 | json.encode_invalid_numbers(false) |
142 | return 'Setting refuse_invalid_numbers("encode")' | 142 | return 'Setting encode_invalid_numbers(false)' |
143 | end, | 143 | end, |
144 | { json.encode, { NaN }, | 144 | { json.encode, { NaN }, |
145 | false, { "Cannot serialise number: must not be NaN or Inf" } }, | 145 | false, { "Cannot serialise number: must not be NaN or Inf" } }, |
146 | { json.encode, { Inf }, | 146 | { json.encode, { Inf }, |
147 | false, { "Cannot serialise number: must not be NaN or Inf" } }, | 147 | false, { "Cannot serialise number: must not be NaN or Inf" } }, |
148 | function () | 148 | function () |
149 | json.refuse_invalid_numbers(false) | 149 | json.encode_invalid_numbers("null") |
150 | return 'Setting refuse_invalid_numbers(false).' | 150 | return 'Setting encode_invalid_numbers("null").' |
151 | end, | ||
152 | { json.encode, { NaN }, true, { "null" } }, | ||
153 | { json.encode, { Inf }, true, { "null" } }, | ||
154 | function () | ||
155 | json.encode_invalid_numbers(true) | ||
156 | return 'Setting encode_invalid_numbers(true).' | ||
151 | end, | 157 | end, |
152 | { json.encode, { NaN }, true, { "nan" } }, | 158 | { json.encode, { NaN }, true, { "nan" } }, |
153 | { json.encode, { Inf }, true, { "inf" } }, | 159 | { json.encode, { Inf }, true, { "inf" } }, |
154 | function () | 160 | function () |
155 | json.refuse_invalid_numbers("encode") | 161 | json.encode_invalid_numbers(false) |
156 | return 'Setting refuse_invalid_numbers("encode")' | 162 | return 'Setting encode_invalid_numbers(false)' |
157 | end, | 163 | end, |
158 | } | 164 | } |
159 | 165 | ||
@@ -233,7 +239,8 @@ util.run_test_group("encode error", encode_error_tests) | |||
233 | util.run_test_group("escape", escape_tests) | 239 | util.run_test_group("escape", escape_tests) |
234 | util.run_test_group("locale", locale_tests) | 240 | util.run_test_group("locale", locale_tests) |
235 | 241 | ||
236 | json.refuse_invalid_numbers(false) | 242 | json.encode_invalid_numbers(true) |
243 | json.decode_invalid_numbers(true) | ||
237 | json.encode_max_depth(20) | 244 | json.encode_max_depth(20) |
238 | for i = 1, #arg do | 245 | for i = 1, #arg do |
239 | util.run_test("decode cycle " .. arg[i], test_decode_cycle, { arg[i] }, | 246 | util.run_test("decode cycle " .. arg[i], test_decode_cycle, { arg[i] }, |