mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-11 12:20:28 +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[[ [1] ]]) == '{1}')
|
||||||
assert(EncodeLua(DecodeJson[[ 2.3 ]]) == '2.3')
|
assert(EncodeLua(DecodeJson[[ 2.3 ]]) == '2.3')
|
||||||
assert(EncodeLua(DecodeJson[[ [1,3,2] ]]) == '{1, 3, 2}')
|
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[[ {"foo": 2, "bar": 4} ]]) == '{bar=4, foo=2}')
|
||||||
assert(EncodeLua(DecodeJson[[ null ]]) == 'nil')
|
assert(EncodeLua(DecodeJson[[ null ]]) == 'nil')
|
||||||
assert(EncodeLua(DecodeJson[[ -123 ]]) == '-123')
|
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[[ 9.123e6 ]]) == '9123000.')
|
||||||
assert(EncodeLua(DecodeJson[[ [{"heh": [1,3,2]}] ]]) == '{{heh={1, 3, 2}}}')
|
assert(EncodeLua(DecodeJson[[ [{"heh": [1,3,2]}] ]]) == '{{heh={1, 3, 2}}}')
|
||||||
assert(EncodeLua(DecodeJson[[ 3.14159 ]]) == '3.14159')
|
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(EncodeLua(DecodeJson[[ 1e-12 ]]) == '1e-12')
|
||||||
|
|
||||||
assert(EncodeJson(DecodeJson[[ 1e-12 ]]) == '1e-12')
|
assert(EncodeJson(DecodeJson[[ 1e-12 ]]) == '1e-12')
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/likely.h"
|
#include "libc/bits/likely.h"
|
||||||
|
#include "libc/log/log.h"
|
||||||
#include "libc/str/tpenc.h"
|
#include "libc/str/tpenc.h"
|
||||||
#include "libc/str/utf16.h"
|
#include "libc/str/utf16.h"
|
||||||
#include "third_party/double-conversion/wrapper.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;
|
int A, B, C, D, c, d, i, u;
|
||||||
for (a = p, d = +1; p < e;) {
|
for (a = p, d = +1; p < e;) {
|
||||||
switch ((c = *p++ & 255)) {
|
switch ((c = *p++ & 255)) {
|
||||||
|
default:
|
||||||
|
luaL_error(L, "illegal character\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
|
||||||
case ' ': // spaces
|
case ' ': // spaces
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\t':
|
case '\t':
|
||||||
case ',': // separators
|
a = p;
|
||||||
case ':':
|
break;
|
||||||
default:
|
|
||||||
|
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;
|
a = p;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -54,21 +67,24 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
return (struct Rc){1, p + 3};
|
return (struct Rc){1, p + 3};
|
||||||
}
|
}
|
||||||
break;
|
luaL_error(L, "expecting null\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
|
||||||
case 't': // true
|
case 't': // true
|
||||||
if (p + 3 <= e && READ32LE(p - 1) == READ32LE("true")) {
|
if (p + 3 <= e && READ32LE(p - 1) == READ32LE("true")) {
|
||||||
lua_pushboolean(L, true);
|
lua_pushboolean(L, true);
|
||||||
return (struct Rc){1, p + 3};
|
return (struct Rc){1, p + 3};
|
||||||
}
|
}
|
||||||
break;
|
luaL_error(L, "expecting true\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
|
||||||
case 'f': // false
|
case 'f': // false
|
||||||
if (p + 4 <= e && READ32LE(p) == READ32LE("alse")) {
|
if (p + 4 <= e && READ32LE(p) == READ32LE("alse")) {
|
||||||
lua_pushboolean(L, false);
|
lua_pushboolean(L, false);
|
||||||
return (struct Rc){1, p + 4};
|
return (struct Rc){1, p + 4};
|
||||||
}
|
}
|
||||||
break;
|
luaL_error(L, "expecting false\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
|
||||||
case '-': // negative
|
case '-': // negative
|
||||||
d = -1;
|
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);
|
lua_rawseti(L, -2, i++ + 1);
|
||||||
}
|
}
|
||||||
} while (r.t);
|
} while (r.t);
|
||||||
|
if (*(p-1) != ']') {
|
||||||
|
luaL_error(L, "invalid list\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
}
|
||||||
return (struct Rc){1, p};
|
return (struct Rc){1, p};
|
||||||
|
|
||||||
case ']':
|
case ']':
|
||||||
|
@ -125,10 +145,18 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
||||||
r = Parse(L, p, e);
|
r = Parse(L, p, e);
|
||||||
p = r.p;
|
p = r.p;
|
||||||
if (r.t) {
|
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);
|
r = Parse(L, p, e);
|
||||||
p = r.p;
|
p = r.p;
|
||||||
if (!r.t) {
|
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);
|
lua_settable(L, -3);
|
||||||
++i;
|
++i;
|
||||||
|
@ -140,6 +168,10 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
||||||
lua_pushboolean(L, true);
|
lua_pushboolean(L, true);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
}
|
}
|
||||||
|
if (*(p-1) != '}') {
|
||||||
|
luaL_error(L, "invalid object\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
}
|
||||||
return (struct Rc){1, p};
|
return (struct Rc){1, p};
|
||||||
|
|
||||||
case '"': // string
|
case '"': // string
|
||||||
|
@ -153,6 +185,11 @@ static struct Rc Parse(struct lua_State *L, const char *p, const char *e) {
|
||||||
case '\\':
|
case '\\':
|
||||||
if (p < e) {
|
if (p < e) {
|
||||||
switch ((c = *p++ & 255)) {
|
switch ((c = *p++ & 255)) {
|
||||||
|
case '0':
|
||||||
|
case 'x':
|
||||||
|
luaL_error(L, "invalid escaped character\n");
|
||||||
|
return (struct Rc){-1, p};
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
case '/':
|
case '/':
|
||||||
case '\\':
|
case '\\':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue