aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua_cjson.c58
-rw-r--r--manual.txt34
-rwxr-xr-xtests/test.lua14
3 files changed, 94 insertions, 12 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 498c686..afa5266 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -1310,6 +1310,35 @@ static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
1310} 1310}
1311#endif 1311#endif
1312 1312
1313/* Call target function in protected mode with all supplied args.
1314 * Assumes target function only returns a single non-nil value.
1315 * Convert and return thrown errors as: nil, "error message" */
1316static int json_protect_conversion(lua_State *l)
1317{
1318 int err;
1319
1320 /* Deliberately throw an error for invalid arguments */
1321 luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
1322
1323 /* pcall() the function stored as upvalue(1) */
1324 lua_pushvalue(l, lua_upvalueindex(1));
1325 lua_insert(l, 1);
1326 err = lua_pcall(l, 1, 1, 0);
1327 if (!err)
1328 return 1;
1329
1330 if (err == LUA_ERRRUN) {
1331 lua_pushnil(l);
1332 lua_insert(l, -2);
1333 return 2;
1334 }
1335
1336 /* Since we are not using a custom error handler, the only remaining
1337 * errors are memory related */
1338 return luaL_error(l, "Memory allocation error in CJSON protected call");
1339}
1340
1341/* Return cjson module table */
1313static int lua_cjson_new(lua_State *l) 1342static int lua_cjson_new(lua_State *l)
1314{ 1343{
1315 luaL_Reg reg[] = { 1344 luaL_Reg reg[] = {
@@ -1349,6 +1378,27 @@ static int lua_cjson_new(lua_State *l)
1349 return 1; 1378 return 1;
1350} 1379}
1351 1380
1381/* Return cjson.safe module table */
1382static int lua_cjson_safe_new(lua_State *l)
1383{
1384 const char *func[] = { "decode", "encode", NULL };
1385 int i;
1386
1387 lua_cjson_new(l);
1388
1389 /* Fix new() method */
1390 lua_pushcfunction(l, lua_cjson_safe_new);
1391 lua_setfield(l, -2, "new");
1392
1393 for (i = 0; func[i]; i++) {
1394 lua_getfield(l, -1, func[i]);
1395 lua_pushcclosure(l, json_protect_conversion, 1);
1396 lua_setfield(l, -2, func[i]);
1397 }
1398
1399 return 1;
1400}
1401
1352int luaopen_cjson(lua_State *l) 1402int luaopen_cjson(lua_State *l)
1353{ 1403{
1354 lua_cjson_new(l); 1404 lua_cjson_new(l);
@@ -1363,5 +1413,13 @@ int luaopen_cjson(lua_State *l)
1363 return 1; 1413 return 1;
1364} 1414}
1365 1415
1416int luaopen_cjson_safe(lua_State *l)
1417{
1418 lua_cjson_safe_new(l);
1419
1420 /* Return cjson.safe table */
1421 return 1;
1422}
1423
1366/* vi:ai et sw=4 ts=4: 1424/* vi:ai et sw=4 ts=4:
1367 */ 1425 */
diff --git a/manual.txt b/manual.txt
index 9833c58..afd9528 100644
--- a/manual.txt
+++ b/manual.txt
@@ -173,6 +173,7 @@ Synopsis
173-- Module instantiation 173-- Module instantiation
174local cjson = require "cjson" 174local cjson = require "cjson"
175local cjson2 = cjson.new() 175local cjson2 = cjson.new()
176local cjson_safe = require "cjson.safe"
176 177
177-- Translate Lua value to/from JSON 178-- Translate Lua value to/from JSON
178text = cjson.encode(value) 179text = cjson.encode(value)
@@ -195,11 +196,20 @@ Module Instantiation
195------------ 196------------
196local cjson = require "cjson" 197local cjson = require "cjson"
197local cjson2 = cjson.new() 198local cjson2 = cjson.new()
199local cjson_safe = require "cjson.safe"
198------------ 200------------
199 201
200Import Lua CJSON via the Lua +require+ function. Lua CJSON does not 202Import Lua CJSON via the Lua +require+ function. Lua CJSON does not
201register a global module table with the default 203register a global module table.
202<<build_options,build options>>. 204
205The +cjson+ module will throw an error during JSON conversion if any
206invalid data is encountered. Refer to <<cjson_encode,+cjson.encode+>>
207and <<cjson_decode,+cjson.decode+>> for details.
208
209The +cjson.safe+ module behaves identically to the +cjson+ module,
210except when errors are encountered during JSON conversion. On error, the
211+cjson_safe.encode+ and +cjson_safe.decode+ functions will return
212+nil+ followed by the error message.
203 213
204+cjson.new+ can be used to instantiate an independent copy of the Lua 214+cjson.new+ can be used to instantiate an independent copy of the Lua
205CJSON module. The new module has a separate persistent encoding buffer, 215CJSON module. The new module has a separate persistent encoding buffer,
@@ -276,8 +286,8 @@ setting = cjson.decode_invalid_numbers([setting])
276-- "setting" must be a boolean. Default: true. 286-- "setting" must be a boolean. Default: true.
277------------ 287------------
278 288
279Lua CJSON may throw an error when trying to decode numbers not supported 289Lua CJSON may generate an error when trying to decode numbers not
280by the JSON specification. _Invalid numbers_ are defined as: 290supported by the JSON specification. _Invalid numbers_ are defined as:
281 291
282- infinity 292- infinity
283- not-a-number (NaN) 293- not-a-number (NaN)
@@ -303,13 +313,13 @@ depth = cjson.decode_max_depth([depth])
303-- "depth" must be a positive integer. Default: 1000. 313-- "depth" must be a positive integer. Default: 1000.
304------------ 314------------
305 315
306Lua CJSON will throw an error when parsing deeply nested JSON once the 316Lua CJSON will generate an error when parsing deeply nested JSON once
307maximum array/object depth has been exceeded. This check prevents 317the maximum array/object depth has been exceeded. This check prevents
308unnecessarily complicated JSON from slowing down the application, or 318unnecessarily complicated JSON from slowing down the application, or
309crashing the application due to lack of process stack space. 319crashing the application due to lack of process stack space.
310 320
311An error may be thrown before the depth limit is hit if Lua is unable to 321An error may be generated before the depth limit is hit if Lua is unable
312allocate more objects on the Lua stack. 322to allocate more objects on the Lua stack.
313 323
314By default, Lua CJSON will reject JSON with arrays and/or objects nested 324By default, Lua CJSON will reject JSON with arrays and/or objects nested
315more than 1000 levels deep. 325more than 1000 levels deep.
@@ -424,7 +434,7 @@ setting = cjson.encode_invalid_numbers([setting])
424-- "setting" must a boolean or "null". Default: false. 434-- "setting" must a boolean or "null". Default: false.
425------------ 435------------
426 436
427Lua CJSON may throw an error when encoding floating point numbers not 437Lua CJSON may generate an error when encoding floating point numbers not
428supported by the JSON specification (_invalid numbers_): 438supported by the JSON specification (_invalid numbers_):
429 439
430- infinity 440- infinity
@@ -476,11 +486,11 @@ depth = cjson.encode_max_depth([depth])
476-- "depth" must be a positive integer. Default: 1000. 486-- "depth" must be a positive integer. Default: 1000.
477------------ 487------------
478 488
479Once the maximum table depth has been exceeded Lua CJSON will throw an 489Once the maximum table depth has been exceeded Lua CJSON will generate
480error. This prevents a deeply nested or recursive data structure from 490an error. This prevents a deeply nested or recursive data structure from
481crashing the application. 491crashing the application.
482 492
483By default, Lua CJSON will throw an error when trying to encode data 493By default, Lua CJSON will generate an error when trying to encode data
484structures with more than 1000 nested tables. 494structures with more than 1000 nested tables.
485 495
486The current setting is always returned, and is only updated when an 496The current setting is always returned, and is only updated when an
diff --git a/tests/test.lua b/tests/test.lua
index ac6419a..96b47ff 100755
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -7,6 +7,7 @@
7-- Note: The output of this script is easier to read with "less -S" 7-- Note: The output of this script is easier to read with "less -S"
8 8
9local json = require "cjson" 9local json = require "cjson"
10local json_safe = require "cjson.safe"
10local util = require "cjson.util" 11local util = require "cjson.util"
11 12
12local function gen_raw_octets() 13local function gen_raw_octets()
@@ -386,6 +387,19 @@ local cjson_tests = {
386 { "Check encode_sparse_array()", 387 { "Check encode_sparse_array()",
387 function (...) return json.encode_sparse_array(...) end, { }, 388 function (...) return json.encode_sparse_array(...) end, { },
388 true, { false, 2, 10 } }, 389 true, { false, 2, 10 } },
390
391 { "Encode (safe) simple value",
392 json_safe.encode, { true },
393 true, { "true" } },
394 { "Encode (safe) argument validation [throw error]",
395 json_safe.encode, { "arg1", "arg2" },
396 false, { "bad argument #1 to '?' (expected 1 argument)" } },
397 { "Decode (safe) error generation",
398 json_safe.decode, { "Oops" },
399 true, { nil, "Expected value but found invalid token at character 1" } },
400 { "Decode (safe) error generation after new()",
401 function(...) return json_safe.new().decode(...) end, { "Oops" },
402 true, { nil, "Expected value but found invalid token at character 1" } },
389} 403}
390 404
391print(("==> Testing Lua CJSON version %s\n"):format(json._VERSION)) 405print(("==> Testing Lua CJSON version %s\n"):format(json._VERSION))