webmcp
changeset 427:f0303fca9218
Decode some JSON numbers (those without decimal point or exponential notation) as Lua integers
author | jbe |
---|---|
date | Thu Jan 14 17:13:48 2016 +0100 (2016-01-14) |
parents | 9d15451c340a |
children | 52ebde158c92 |
files | libraries/json/json.c |
line diff
1.1 --- a/libraries/json/json.c Thu Jan 14 12:49:54 2016 +0100 1.2 +++ b/libraries/json/json.c Thu Jan 14 17:13:48 2016 +0100 1.3 @@ -544,17 +544,44 @@ 1.4 } 1.5 // process values whose type is is not deducible from a single character: 1.6 if ((c >= '0' && c <= '9') || c == '-' || c == '+') { 1.7 - // for numbers, 1.8 - // use strtod() call to parse a (double precision) floating point number: 1.9 + // try to parse number: 1.10 double numval; 1.11 char *endptr; 1.12 + size_t endpos; 1.13 + // use strtod() call to parse a (double precision) floating point number 1.14 + // and to determine length of number: 1.15 numval = strtod(str+pos, &endptr); 1.16 // catch parsing errors: 1.17 if (endptr == str+pos) goto json_import_syntax_error; 1.18 + // calculate end position of number: 1.19 + endpos = endptr - str; 1.20 +#if LUA_VERSION_NUM >= 503 1.21 + // try alternative integer interpretation: 1.22 + { 1.23 + lua_Integer intval = 0; 1.24 + size_t curpos; 1.25 + if (c >= '0' && c <= '9') intval = c - '0'; 1.26 + for (curpos=pos+1; curpos<endpos; curpos++) { 1.27 + lua_Integer d = str[curpos] - '0'; 1.28 + if (d < 0 || d > 9) break; 1.29 + if (c == '-') { 1.30 + // NOTE: rounding of negative integer division may be undefined 1.31 + if ( 1.32 + intval == LUA_MININTEGER || 1.33 + -intval > (-(LUA_MININTEGER+10) - d) / 10 + 1 1.34 + ) break; 1.35 + intval = 10 * intval - d; 1.36 + } else { 1.37 + if (intval > (LUA_MAXINTEGER - d) / 10) break; 1.38 + intval = 10 * intval + d; 1.39 + } 1.40 + } 1.41 + if (curpos == endpos) lua_pushinteger(L, intval); 1.42 + else lua_pushnumber(L, numval); 1.43 + } 1.44 +#endif 1.45 // consume characters that were parsed: 1.46 - pos += endptr - (str+pos); 1.47 - // push parsed (double precision) floating point number on Lua stack: 1.48 - lua_pushnumber(L, numval); 1.49 + pos = endpos; 1.50 } else if (!strncmp(str+pos, "true", 4)) { 1.51 // consume 4 input characters for "true": 1.52 pos += 4; 1.53 @@ -597,11 +624,11 @@ 1.54 case JSON_STATE_ARRAY_VALUE: 1.55 // get current array length: 1.56 arraylen = lua_rawlen(L, -3); 1.57 - // throw error if array would exceed INT_MAX elements: 1.58 - // TODO: Lua 5.3 may support more elements 1.59 - if (arraylen >= INT_MAX) { 1.60 + // throw error if array would exceed INT_MAX-1 elements: 1.61 + // NOTE: Lua 5.3 may support more elements, but C libraries may not 1.62 + if (arraylen > INT_MAX-1) { 1.63 lua_pushnil(L); 1.64 - lua_pushfstring(L, "Array exceeded length of %d elements", INT_MAX); 1.65 + lua_pushfstring(L, "Array exceeded length of %d elements", INT_MAX-1); 1.66 } 1.67 // store value in outer shadow table: 1.68 lua_rawseti(L, -3, arraylen + 1);