aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c98
1 files changed, 63 insertions, 35 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 344cb43..bdfa7d4 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -39,6 +39,7 @@
39#include <assert.h> 39#include <assert.h>
40#include <string.h> 40#include <string.h>
41#include <math.h> 41#include <math.h>
42#include <limits.h>
42#include <lua.h> 43#include <lua.h>
43#include <lauxlib.h> 44#include <lauxlib.h>
44 45
@@ -61,7 +62,8 @@
61#define DEFAULT_SPARSE_CONVERT 0 62#define DEFAULT_SPARSE_CONVERT 0
62#define DEFAULT_SPARSE_RATIO 2 63#define DEFAULT_SPARSE_RATIO 2
63#define DEFAULT_SPARSE_SAFE 10 64#define DEFAULT_SPARSE_SAFE 10
64#define DEFAULT_MAX_DEPTH 20 65#define DEFAULT_ENCODE_MAX_DEPTH 20
66#define DEFAULT_DECODE_MAX_DEPTH 20
65#define DEFAULT_ENCODE_REFUSE_BADNUM 1 67#define DEFAULT_ENCODE_REFUSE_BADNUM 1
66#define DEFAULT_DECODE_REFUSE_BADNUM 0 68#define DEFAULT_DECODE_REFUSE_BADNUM 0
67#define DEFAULT_ENCODE_KEEP_BUFFER 1 69#define DEFAULT_ENCODE_KEEP_BUFFER 1
@@ -120,9 +122,11 @@ typedef struct {
120 int encode_sparse_safe; 122 int encode_sparse_safe;
121 int encode_max_depth; 123 int encode_max_depth;
122 int encode_refuse_badnum; 124 int encode_refuse_badnum;
123 int decode_refuse_badnum;
124 int encode_keep_buffer;
125 int encode_number_precision; 125 int encode_number_precision;
126 int encode_keep_buffer;
127
128 int decode_refuse_badnum;
129 int decode_max_depth;
126} json_config_t; 130} json_config_t;
127 131
128typedef struct { 132typedef struct {
@@ -130,6 +134,7 @@ typedef struct {
130 const char *ptr; 134 const char *ptr;
131 strbuf_t *tmp; /* Temporary storage for strings */ 135 strbuf_t *tmp; /* Temporary storage for strings */
132 json_config_t *cfg; 136 json_config_t *cfg;
137 int current_depth;
133} json_parse_t; 138} json_parse_t;
134 139
135typedef struct { 140typedef struct {
@@ -234,46 +239,50 @@ static int json_cfg_encode_sparse_array(lua_State *l)
234 return 3; 239 return 3;
235} 240}
236 241
237/* Configures the maximum number of nested arrays/objects allowed when 242/* Process integer options for configuration functions */
238 * encoding */ 243static int json_integer_option(lua_State *l, int *setting, int min, int max)
239static int json_cfg_encode_max_depth(lua_State *l)
240{ 244{
241 json_config_t *cfg; 245 char errmsg[64];
242 int depth; 246 int value;
243 247
244 json_verify_arg_count(l, 1); 248 json_verify_arg_count(l, 1);
245 cfg = json_fetch_config(l);
246 249
247 if (lua_gettop(l)) { 250 if (lua_gettop(l)) {
248 depth = luaL_checkinteger(l, 1); 251 value = luaL_checkinteger(l, 1);
249 luaL_argcheck(l, depth > 0, 1, "expected positive integer"); 252 snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max);
250 cfg->encode_max_depth = depth; 253 luaL_argcheck(l, min <= value && value <= max, 1, errmsg);
254 *setting = value;
251 } 255 }
252 256
253 lua_pushinteger(l, cfg->encode_max_depth); 257 lua_pushinteger(l, *setting);
254 258
255 return 1; 259 return 1;
256} 260}
257 261
258/* Configures number precision when converting doubles to text */ 262/* Configures the maximum number of nested arrays/objects allowed when
259static int json_cfg_encode_number_precision(lua_State *l) 263 * encoding */
264static int json_cfg_encode_max_depth(lua_State *l)
260{ 265{
261 json_config_t *cfg; 266 json_config_t *cfg = json_fetch_config(l);
262 int precision;
263 267
264 json_verify_arg_count(l, 1); 268 return json_integer_option(l, &cfg->encode_max_depth, 1, INT_MAX);
265 cfg = json_fetch_config(l); 269}
266 270
267 if (lua_gettop(l)) { 271/* Configures the maximum number of nested arrays/objects allowed when
268 precision = luaL_checkinteger(l, 1); 272 * encoding */
269 luaL_argcheck(l, 1 <= precision && precision <= 14, 1, 273static int json_cfg_decode_max_depth(lua_State *l)
270 "expected integer between 1 and 14"); 274{
271 cfg->encode_number_precision = precision; 275 json_config_t *cfg = json_fetch_config(l);
272 }
273 276
274 lua_pushinteger(l, cfg->encode_number_precision); 277 return json_integer_option(l, &cfg->decode_max_depth, 1, INT_MAX);
278}
275 279
276 return 1; 280/* Configures number precision when converting doubles to text */
281static int json_cfg_encode_number_precision(lua_State *l)
282{
283 json_config_t *cfg = json_fetch_config(l);
284
285 return json_integer_option(l, &cfg->encode_number_precision, 1, 14);
277} 286}
278 287
279/* Configures JSON encoding buffer persistence */ 288/* Configures JSON encoding buffer persistence */
@@ -387,7 +396,8 @@ static void json_create_config(lua_State *l)
387 cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; 396 cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
388 cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; 397 cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
389 cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; 398 cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
390 cfg->encode_max_depth = DEFAULT_MAX_DEPTH; 399 cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH;
400 cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH;
391 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; 401 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM;
392 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; 402 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM;
393 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; 403 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
@@ -1094,10 +1104,19 @@ static void json_throw_parse_error(lua_State *l, json_parse_t *json,
1094 exp, found, token->index + 1); 1104 exp, found, token->index + 1);
1095} 1105}
1096 1106
1097static void json_decode_checkstack(lua_State *l, json_parse_t *json, int n) 1107static inline void json_decode_ascend(json_parse_t *json)
1098{ 1108{
1099 if (lua_checkstack(l, n)) 1109 json->current_depth--;
1110}
1111
1112static void json_decode_descend(lua_State *l, json_parse_t *json, int slots)
1113{
1114 json->current_depth++;
1115
1116 if (json->current_depth <= json->cfg->decode_max_depth &&
1117 lua_checkstack(l, slots)) {
1100 return; 1118 return;
1119 }
1101 1120
1102 strbuf_free(json->tmp); 1121 strbuf_free(json->tmp);
1103 luaL_error(l, "Too many nested data structures"); 1122 luaL_error(l, "Too many nested data structures");
@@ -1109,7 +1128,7 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json)
1109 1128
1110 /* 3 slots required: 1129 /* 3 slots required:
1111 * .., table, key, value */ 1130 * .., table, key, value */
1112 json_decode_checkstack(l, json, 3); 1131 json_decode_descend(l, json, 3);
1113 1132
1114 lua_newtable(l); 1133 lua_newtable(l);
1115 1134
@@ -1117,6 +1136,7 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json)
1117 1136
1118 /* Handle empty objects */ 1137 /* Handle empty objects */
1119 if (token.type == T_OBJ_END) { 1138 if (token.type == T_OBJ_END) {
1139 json_decode_ascend(json);
1120 return; 1140 return;
1121 } 1141 }
1122 1142
@@ -1140,8 +1160,10 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json)
1140 1160
1141 json_next_token(json, &token); 1161 json_next_token(json, &token);
1142 1162
1143 if (token.type == T_OBJ_END) 1163 if (token.type == T_OBJ_END) {
1164 json_decode_ascend(json);
1144 return; 1165 return;
1166 }
1145 1167
1146 if (token.type != T_COMMA) 1168 if (token.type != T_COMMA)
1147 json_throw_parse_error(l, json, "comma or object end", &token); 1169 json_throw_parse_error(l, json, "comma or object end", &token);
@@ -1158,15 +1180,17 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json)
1158 1180
1159 /* 2 slots required: 1181 /* 2 slots required:
1160 * .., table, value */ 1182 * .., table, value */
1161 json_decode_checkstack(l, json, 2); 1183 json_decode_descend(l, json, 2);
1162 1184
1163 lua_newtable(l); 1185 lua_newtable(l);
1164 1186
1165 json_next_token(json, &token); 1187 json_next_token(json, &token);
1166 1188
1167 /* Handle empty arrays */ 1189 /* Handle empty arrays */
1168 if (token.type == T_ARR_END) 1190 if (token.type == T_ARR_END) {
1191 json_decode_ascend(json);
1169 return; 1192 return;
1193 }
1170 1194
1171 for (i = 1; ; i++) { 1195 for (i = 1; ; i++) {
1172 json_process_value(l, json, &token); 1196 json_process_value(l, json, &token);
@@ -1174,8 +1198,10 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json)
1174 1198
1175 json_next_token(json, &token); 1199 json_next_token(json, &token);
1176 1200
1177 if (token.type == T_ARR_END) 1201 if (token.type == T_ARR_END) {
1202 json_decode_ascend(json);
1178 return; 1203 return;
1204 }
1179 1205
1180 if (token.type != T_COMMA) 1206 if (token.type != T_COMMA)
1181 json_throw_parse_error(l, json, "comma or array end", &token); 1207 json_throw_parse_error(l, json, "comma or array end", &token);
@@ -1221,6 +1247,7 @@ static void lua_json_decode(lua_State *l, const char *json_text, int json_len)
1221 json_token_t token; 1247 json_token_t token;
1222 1248
1223 json.cfg = json_fetch_config(l); 1249 json.cfg = json_fetch_config(l);
1250 json.current_depth = 0;
1224 json.data = json_text; 1251 json.data = json_text;
1225 json.ptr = json.data; 1252 json.ptr = json.data;
1226 1253
@@ -1292,6 +1319,7 @@ static int lua_cjson_new(lua_State *l)
1292 { "decode", json_decode }, 1319 { "decode", json_decode },
1293 { "encode_sparse_array", json_cfg_encode_sparse_array }, 1320 { "encode_sparse_array", json_cfg_encode_sparse_array },
1294 { "encode_max_depth", json_cfg_encode_max_depth }, 1321 { "encode_max_depth", json_cfg_encode_max_depth },
1322 { "decode_max_depth", json_cfg_decode_max_depth },
1295 { "encode_number_precision", json_cfg_encode_number_precision }, 1323 { "encode_number_precision", json_cfg_encode_number_precision },
1296 { "encode_keep_buffer", json_cfg_encode_keep_buffer }, 1324 { "encode_keep_buffer", json_cfg_encode_keep_buffer },
1297 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, 1325 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers },