aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-05-01 16:29:11 +0930
committerMark Pulford <mark@kyne.com.au>2011-05-01 16:29:11 +0930
commita875deda45983379fabf07a4b60064d33dd70d57 (patch)
treeed7edc06b3e121d1b99bd0f4c063f7664954ac24
parentbc94292b70be41cecd2bd151b1fffcfa59480118 (diff)
downloadlua-cjson-a875deda45983379fabf07a4b60064d33dd70d57.tar.gz
lua-cjson-a875deda45983379fabf07a4b60064d33dd70d57.tar.bz2
lua-cjson-a875deda45983379fabf07a4b60064d33dd70d57.zip
Throw error on Inf/NaN by default when encoding
Add runtime configuration for generating Inf/NaN encoding errors through cjson.strict_numbers().
-rw-r--r--lua_cjson.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index e5e7d1c..e339d51 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -30,7 +30,6 @@
30 30
31#include "strbuf.h" 31#include "strbuf.h"
32 32
33
34#define CJSON_CONFIG_KEY "cjson_configdata" 33#define CJSON_CONFIG_KEY "cjson_configdata"
35#define DEFAULT_SPARSE_RATIO 2 34#define DEFAULT_SPARSE_RATIO 2
36#define DEFAULT_MAX_DEPTH 20 35#define DEFAULT_MAX_DEPTH 20
@@ -76,6 +75,7 @@ typedef struct {
76 int sparse_ratio; 75 int sparse_ratio;
77 int max_depth; 76 int max_depth;
78 int current_depth; 77 int current_depth;
78 int strict_numbers;
79} json_config_t; 79} json_config_t;
80 80
81typedef struct { 81typedef struct {
@@ -112,18 +112,26 @@ static json_config_t *json_fetch_config(lua_State *l)
112 return cfg; 112 return cfg;
113} 113}
114 114
115static int json_sparse_ratio(lua_State *l) 115/* Checks whether a config variable needs to be updated.
116 * Also return cfg pointer */
117static int cfg_update_requested(lua_State *l, json_config_t **cfg)
116{ 118{
117 json_config_t *cfg;
118 int sparse_ratio;
119 int args; 119 int args;
120 120
121 args = lua_gettop(l); 121 args = lua_gettop(l);
122 luaL_argcheck(l, args <= 1, 2, "found too many arguments"); 122 luaL_argcheck(l, args <= 1, 2, "found too many arguments");
123 123
124 cfg = json_fetch_config(l); 124 *cfg = json_fetch_config(l);
125
126 return args;
127}
128
129static int json_sparse_ratio(lua_State *l)
130{
131 json_config_t *cfg;
132 int sparse_ratio;
125 133
126 if (args == 1) { 134 if (cfg_update_requested(l, &cfg)) {
127 sparse_ratio = luaL_checkinteger(l, 1); 135 sparse_ratio = luaL_checkinteger(l, 1);
128 luaL_argcheck(l, sparse_ratio >= 0, 1, 136 luaL_argcheck(l, sparse_ratio >= 0, 1,
129 "expected zero or positive integer"); 137 "expected zero or positive integer");
@@ -139,14 +147,8 @@ static int json_max_depth(lua_State *l)
139{ 147{
140 json_config_t *cfg; 148 json_config_t *cfg;
141 int max_depth; 149 int max_depth;
142 int args;
143
144 args = lua_gettop(l);
145 luaL_argcheck(l, args <= 1, 2, "found too many arguments");
146 150
147 cfg = json_fetch_config(l); 151 if (cfg_update_requested(l, &cfg)) {
148
149 if (args == 1) {
150 max_depth = luaL_checkinteger(l, 1); 152 max_depth = luaL_checkinteger(l, 1);
151 luaL_argcheck(l, max_depth > 0, 1, "expected positive integer"); 153 luaL_argcheck(l, max_depth > 0, 1, "expected positive integer");
152 cfg->max_depth = max_depth; 154 cfg->max_depth = max_depth;
@@ -157,6 +159,20 @@ static int json_max_depth(lua_State *l)
157 return 1; 159 return 1;
158} 160}
159 161
162static int json_strict_numbers(lua_State *l)
163{
164 json_config_t *cfg;
165
166 if (cfg_update_requested(l, &cfg)) {
167 luaL_argcheck(l, lua_isboolean(l, 1), 1, "expected boolean");
168 cfg->strict_numbers = lua_toboolean(l, 1);
169 }
170
171 lua_pushboolean(l, cfg->strict_numbers);
172
173 return 1;
174}
175
160static void json_create_config(lua_State *l) 176static void json_create_config(lua_State *l)
161{ 177{
162 json_config_t *cfg; 178 json_config_t *cfg;
@@ -205,6 +221,7 @@ static void json_create_config(lua_State *l)
205 221
206 cfg->sparse_ratio = DEFAULT_SPARSE_RATIO; 222 cfg->sparse_ratio = DEFAULT_SPARSE_RATIO;
207 cfg->max_depth = DEFAULT_MAX_DEPTH; 223 cfg->max_depth = DEFAULT_MAX_DEPTH;
224 cfg->strict_numbers = 1;
208} 225}
209 226
210/* ===== ENCODING ===== */ 227/* ===== ENCODING ===== */
@@ -360,6 +377,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, strbuf_t *json,
360 cfg->current_depth--; 377 cfg->current_depth--;
361} 378}
362 379
380static void json_append_number(lua_State *l, strbuf_t *json, int index,
381 int strict)
382{
383 double num = lua_tonumber(l, index);
384
385 if (strict && (isinf(num) || isnan(num)))
386 json_encode_exception(l, json, index, "must not be NaN of Inf");
387
388 strbuf_append_fmt(json, LUA_NUMBER_FMT, num);
389}
390
363static void json_append_object(lua_State *l, json_config_t *cfg, 391static void json_append_object(lua_State *l, json_config_t *cfg,
364 strbuf_t *json) 392 strbuf_t *json)
365{ 393{
@@ -382,8 +410,12 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
382 /* table, key, value */ 410 /* table, key, value */
383 keytype = lua_type(l, -2); 411 keytype = lua_type(l, -2);
384 if (keytype == LUA_TNUMBER) { 412 if (keytype == LUA_TNUMBER) {
385 strbuf_append_fmt(json, "\"" LUA_NUMBER_FMT "\": ", 413 /* Can't just use json_append_string() below since it would
386 lua_tonumber(l, -2)); 414 * convert the value in the callers data structure, and it
415 * does not support strict numbers */
416 strbuf_append_char(json, '"');
417 json_append_number(l, json, -2, cfg->strict_numbers);
418 strbuf_append_string(json, "\": ");
387 } else if (keytype == LUA_TSTRING) { 419 } else if (keytype == LUA_TSTRING) {
388 json_append_string(l, json, -2); 420 json_append_string(l, json, -2);
389 strbuf_append_string(json, ": "); 421 strbuf_append_string(json, ": ");
@@ -414,7 +446,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg, strbuf_t *json)
414 json_append_string(l, json, -1); 446 json_append_string(l, json, -1);
415 break; 447 break;
416 case LUA_TNUMBER: 448 case LUA_TNUMBER:
417 strbuf_append_fmt(json, "%lf", lua_tonumber(l, -1)); 449 json_append_number(l, json, -1, cfg->strict_numbers);
418 break; 450 break;
419 case LUA_TBOOLEAN: 451 case LUA_TBOOLEAN:
420 if (lua_toboolean(l, -1)) 452 if (lua_toboolean(l, -1))
@@ -893,6 +925,7 @@ int luaopen_cjson(lua_State *l)
893 { "decode", json_decode }, 925 { "decode", json_decode },
894 { "sparse_ratio", json_sparse_ratio }, 926 { "sparse_ratio", json_sparse_ratio },
895 { "max_depth", json_max_depth }, 927 { "max_depth", json_max_depth },
928 { "strict_numbers", json_strict_numbers },
896 { NULL, NULL } 929 { NULL, NULL }
897 }; 930 };
898 931