mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-10 03:40:29 +00:00
added some error modes
- now some of the failure test cases also pass - integers cannot be JSON object keys
This commit is contained in:
parent
ff64ded383
commit
6772ffe5c9
2 changed files with 46 additions and 9 deletions
|
@ -18,7 +18,7 @@ assert(EncodeLua(DecodeJson[[ 0 ]]) == '0' )
|
|||
assert(EncodeLua(DecodeJson[[ [1] ]]) == '{1}')
|
||||
assert(EncodeLua(DecodeJson[[ 2.3 ]]) == '2.3')
|
||||
assert(EncodeLua(DecodeJson[[ [1,3,2] ]]) == '{1, 3, 2}')
|
||||
assert(EncodeLua(DecodeJson[[ {1: 2, 3: 4} ]]) == '{[1]=2, [3]=4}')
|
||||
-- assert(EncodeLua(DecodeJson[[ {1: 2, 3: 4} ]]) == '{[1]=2, [3]=4}')
|
||||
assert(EncodeLua(DecodeJson[[ {"foo": 2, "bar": 4} ]]) == '{bar=4, foo=2}')
|
||||
assert(EncodeLua(DecodeJson[[ null ]]) == 'nil')
|
||||
assert(EncodeLua(DecodeJson[[ -123 ]]) == '-123')
|
||||
|
@ -28,7 +28,7 @@ assert(EncodeLua(DecodeJson[[ 1e-06 ]]) == '0.000001')
|
|||
assert(EncodeLua(DecodeJson[[ 9.123e6 ]]) == '9123000.')
|
||||
assert(EncodeLua(DecodeJson[[ [{"heh": [1,3,2]}] ]]) == '{{heh={1, 3, 2}}}')
|
||||
assert(EncodeLua(DecodeJson[[ 3.14159 ]]) == '3.14159')
|
||||
assert(EncodeLua(DecodeJson[[ {3=4} ]]) == '{[3]=4}')
|
||||
-- assert(EncodeLua(DecodeJson[[ {3=4} ]]) == '{[3]=4}')
|
||||
assert(EncodeLua(DecodeJson[[ 1e-12 ]]) == '1e-12')
|
||||
|
||||
assert(EncodeJson(DecodeJson[[ 1e-12 ]]) == '1e-12')
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
#include "libc/str/utf16.h"
|
||||
#include "third_party/double-conversion/wrapper.h"
|
||||
|
@ -38,14 +39,26 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
int A, B, C, D, c, d, i, u;
|
||||
for (a = p, d = +1; p < e;) {
|
||||
switch ((c = *p++ & 255)) {
|
||||
default:
|
||||
luaL_error(L, "illegal character\n");
|
||||
return (struct Rc){-1, p};
|
||||
|
||||
case ' ': // spaces
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case ',': // separators
|
||||
case ':':
|
||||
default:
|
||||
a = p;
|
||||
break;
|
||||
|
||||
case ',': // present in list and object
|
||||
a = p;
|
||||
break;
|
||||
|
||||
case ':': // present only in object after key
|
||||
if (LUA_TSTRING != lua_type(L, -1)) {
|
||||
luaL_error(L, "unexpected ':'\n");
|
||||
return (struct Rc){-1, p};
|
||||
}
|
||||
a = p;
|
||||
break;
|
||||
|
||||
|
@ -54,21 +67,24 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
lua_pushnil(L);
|
||||
return (struct Rc){1, p + 3};
|
||||
}
|
||||
break;
|
||||
luaL_error(L, "expecting null\n");
|
||||
return (struct Rc){-1, p};
|
||||
|
||||
case 't': // true
|
||||
if (p + 3 <= e && READ32LE(p - 1) == READ32LE("true")) {
|
||||
lua_pushboolean(L, true);
|
||||
return (struct Rc){1, p + 3};
|
||||
}
|
||||
break;
|
||||
luaL_error(L, "expecting true\n");
|
||||
return (struct Rc){-1, p};
|
||||
|
||||
case 'f': // false
|
||||
if (p + 4 <= e && READ32LE(p) == READ32LE("alse")) {
|
||||
lua_pushboolean(L, false);
|
||||
return (struct Rc){1, p + 4};
|
||||
}
|
||||
break;
|
||||
luaL_error(L, "expecting false\n");
|
||||
return (struct Rc){-1, p};
|
||||
|
||||
case '-': // negative
|
||||
d = -1;
|
||||
|
@ -112,6 +128,10 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
lua_rawseti(L, -2, i++ + 1);
|
||||
}
|
||||
} while (r.t);
|
||||
if (*(p-1) != ']') {
|
||||
luaL_error(L, "invalid list\n");
|
||||
return (struct Rc){-1, p};
|
||||
}
|
||||
return (struct Rc){1, p};
|
||||
|
||||
case ']':
|
||||
|
@ -125,10 +145,18 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
r = Parse(L, p, e);
|
||||
p = r.p;
|
||||
if (r.t) {
|
||||
if (LUA_TSTRING != lua_type(L, -1)) {
|
||||
/* json keys can only be strings */
|
||||
lua_settop(L, -2);
|
||||
break;
|
||||
}
|
||||
r = Parse(L, p, e);
|
||||
p = r.p;
|
||||
if (!r.t) {
|
||||
lua_pushnil(L);
|
||||
/* key provided but no value */
|
||||
lua_settop(L, -2);
|
||||
luaL_error(L, "key provided but no value\n");
|
||||
return (struct Rc){-1, p};
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
++i;
|
||||
|
@ -140,6 +168,10 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
lua_pushboolean(L, true);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
if (*(p-1) != '}') {
|
||||
luaL_error(L, "invalid object\n");
|
||||
return (struct Rc){-1, p};
|
||||
}
|
||||
return (struct Rc){1, p};
|
||||
|
||||
case '"': // string
|
||||
|
@ -153,6 +185,11 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
|||
case '\\':
|
||||
if (p < e) {
|
||||
switch ((c = *p++ & 255)) {
|
||||
case '0':
|
||||
case 'x':
|
||||
luaL_error(L, "invalid escaped character\n");
|
||||
return (struct Rc){-1, p};
|
||||
|
||||
case '"':
|
||||
case '/':
|
||||
case '\\':
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue