mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 11:37:35 +00:00
Add json.org tests for DecodeJson (#473)
This commit is contained in:
parent
5fa77f1e8f
commit
c0b325bafa
39 changed files with 313 additions and 10 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')
|
||||
|
|
5
test/tool/net/samples/fail1.lua
Normal file
5
test/tool/net/samples/fail1.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail1.json
|
||||
assert(pcall(DecodeJson, [[
|
||||
"A JSON payload should be an object or array, not a string."
|
||||
]]))
|
5
test/tool/net/samples/fail10.lua
Normal file
5
test/tool/net/samples/fail10.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail10.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Extra value after close": true} "misplaced quoted value"
|
||||
]]))
|
5
test/tool/net/samples/fail11.lua
Normal file
5
test/tool/net/samples/fail11.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail11.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Illegal expression": 1 + 2}
|
||||
]]))
|
5
test/tool/net/samples/fail12.lua
Normal file
5
test/tool/net/samples/fail12.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail12.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Illegal invocation": alert()}
|
||||
]]))
|
5
test/tool/net/samples/fail13.lua
Normal file
5
test/tool/net/samples/fail13.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail13.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Numbers cannot have leading zeroes": 013}
|
||||
]]))
|
5
test/tool/net/samples/fail14.lua
Normal file
5
test/tool/net/samples/fail14.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail14.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Numbers cannot be hex": 0x14}
|
||||
]]))
|
5
test/tool/net/samples/fail15.lua
Normal file
5
test/tool/net/samples/fail15.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail15.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Illegal backslash escape: \x15"]
|
||||
]]))
|
5
test/tool/net/samples/fail16.lua
Normal file
5
test/tool/net/samples/fail16.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail16.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ \naked]
|
||||
]]))
|
5
test/tool/net/samples/fail17.lua
Normal file
5
test/tool/net/samples/fail17.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail17.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Illegal backslash escape: \017"]
|
||||
]]))
|
5
test/tool/net/samples/fail18.lua
Normal file
5
test/tool/net/samples/fail18.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail18.json
|
||||
assert(pcall(DecodeJson, [[
|
||||
[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ "Too deep"] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]
|
||||
]]))
|
5
test/tool/net/samples/fail19.lua
Normal file
5
test/tool/net/samples/fail19.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail19.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Missing colon" null}
|
||||
]]))
|
5
test/tool/net/samples/fail2.lua
Normal file
5
test/tool/net/samples/fail2.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail2.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Unclosed array"
|
||||
]]))
|
5
test/tool/net/samples/fail20.lua
Normal file
5
test/tool/net/samples/fail20.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail20.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Double colon":: null}
|
||||
]]))
|
5
test/tool/net/samples/fail21.lua
Normal file
5
test/tool/net/samples/fail21.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail21.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Comma instead of colon", null}
|
||||
]]))
|
5
test/tool/net/samples/fail22.lua
Normal file
5
test/tool/net/samples/fail22.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail22.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Colon instead of comma": false]
|
||||
]]))
|
5
test/tool/net/samples/fail23.lua
Normal file
5
test/tool/net/samples/fail23.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail23.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Bad value", truth]
|
||||
]]))
|
5
test/tool/net/samples/fail24.lua
Normal file
5
test/tool/net/samples/fail24.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail24.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ 'single quote']
|
||||
]]))
|
5
test/tool/net/samples/fail25.lua
Normal file
5
test/tool/net/samples/fail25.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail25.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ " tab character in string "]
|
||||
]]))
|
5
test/tool/net/samples/fail26.lua
Normal file
5
test/tool/net/samples/fail26.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail26.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "tab\ character\ in\ string\ "]
|
||||
]]))
|
6
test/tool/net/samples/fail27.lua
Normal file
6
test/tool/net/samples/fail27.lua
Normal file
|
@ -0,0 +1,6 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail27.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "line
|
||||
break"]
|
||||
]]))
|
6
test/tool/net/samples/fail28.lua
Normal file
6
test/tool/net/samples/fail28.lua
Normal file
|
@ -0,0 +1,6 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail28.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "line\
|
||||
break"]
|
||||
]]))
|
5
test/tool/net/samples/fail29.lua
Normal file
5
test/tool/net/samples/fail29.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail29.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ 0e]
|
||||
]]))
|
5
test/tool/net/samples/fail3.lua
Normal file
5
test/tool/net/samples/fail3.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail3.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{unquoted_key: "keys must be quoted"}
|
||||
]]))
|
5
test/tool/net/samples/fail30.lua
Normal file
5
test/tool/net/samples/fail30.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail30.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ 0e+]
|
||||
]]))
|
5
test/tool/net/samples/fail31.lua
Normal file
5
test/tool/net/samples/fail31.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail31.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ 0e+-1]
|
||||
]]))
|
5
test/tool/net/samples/fail32.lua
Normal file
5
test/tool/net/samples/fail32.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail32.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Comma instead if closing brace": true,
|
||||
]]))
|
5
test/tool/net/samples/fail33.lua
Normal file
5
test/tool/net/samples/fail33.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail33.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "mismatch"}
|
||||
]]))
|
5
test/tool/net/samples/fail4.lua
Normal file
5
test/tool/net/samples/fail4.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail4.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "extra comma",]
|
||||
]]))
|
5
test/tool/net/samples/fail5.lua
Normal file
5
test/tool/net/samples/fail5.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail5.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "double extra comma",,]
|
||||
]]))
|
5
test/tool/net/samples/fail6.lua
Normal file
5
test/tool/net/samples/fail6.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail6.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ , "<-- missing value"]
|
||||
]]))
|
5
test/tool/net/samples/fail7.lua
Normal file
5
test/tool/net/samples/fail7.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail7.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Comma after the close"] ,
|
||||
]]))
|
5
test/tool/net/samples/fail8.lua
Normal file
5
test/tool/net/samples/fail8.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail8.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
[ "Extra close"] ]
|
||||
]]))
|
5
test/tool/net/samples/fail9.lua
Normal file
5
test/tool/net/samples/fail9.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: fail9.json
|
||||
assert(false == pcall(DecodeJson, [[
|
||||
{"Extra comma": true,}
|
||||
]]))
|
62
test/tool/net/samples/pass1.lua
Normal file
62
test/tool/net/samples/pass1.lua
Normal file
|
@ -0,0 +1,62 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: pass1.json
|
||||
assert(pcall(DecodeJson, [[
|
||||
[
|
||||
"JSON Test Pattern pass1",
|
||||
{"object with 1 member":[ "array with 1 element"] },
|
||||
{},
|
||||
[ ] ,
|
||||
-42,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
{
|
||||
"integer": 1234567890,
|
||||
"real": -9876.543210,
|
||||
"e": 0.123456789e-12,
|
||||
"E": 1.234567890E+34,
|
||||
"": 23456789012E66,
|
||||
"zero": 0,
|
||||
"one": 1,
|
||||
"space": " ",
|
||||
"quote": "\"",
|
||||
"backslash": "\\",
|
||||
"controls": "\b\f\n\r\t",
|
||||
"slash": "/ & \/",
|
||||
"alpha": "abcdefghijklmnopqrstuvwyz",
|
||||
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
||||
"digit": "0123456789",
|
||||
"0123456789": "digit",
|
||||
"special": "`1~!@#$%^&*()_+-={':[ ,] }|;.</>?",
|
||||
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
||||
"true": true,
|
||||
"false": false,
|
||||
"null": null,
|
||||
"array":[ ] ,
|
||||
"object":{ },
|
||||
"address": "50 St. James Street",
|
||||
"url": "http://www.JSON.org/",
|
||||
"comment": "// /* <!-- --",
|
||||
"# -- --> */": " ",
|
||||
" s p a c e d " :[ 1,2 , 3
|
||||
|
||||
,
|
||||
|
||||
4 , 5 , 6 ,7 ] ,"compact":[ 1,2,3,4,5,6,7] ,
|
||||
"jsontext": "{\"object with 1 member\":[ \"array with 1 element\"] }",
|
||||
"quotes": "" \u0022 %22 0x22 034 "",
|
||||
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[ ] {}|;:',./<>?"
|
||||
: "A key can be any string"
|
||||
},
|
||||
0.5 ,98.6
|
||||
,
|
||||
99.44
|
||||
,
|
||||
|
||||
1066,
|
||||
1e1,
|
||||
0.1e1,
|
||||
1e-1,
|
||||
1e00,2e+00,2e-00
|
||||
,"rosebud"]
|
||||
]]))
|
5
test/tool/net/samples/pass2.lua
Normal file
5
test/tool/net/samples/pass2.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: pass2.json
|
||||
assert(pcall(DecodeJson, [[
|
||||
[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ "Not too deep"] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]
|
||||
]]))
|
11
test/tool/net/samples/pass3.lua
Normal file
11
test/tool/net/samples/pass3.lua
Normal file
|
@ -0,0 +1,11 @@
|
|||
-- https://www.json.org/JSON_checker/test.zip
|
||||
-- JSON parsing sample test case: pass3.json
|
||||
assert(pcall(DecodeJson, [[
|
||||
{
|
||||
"JSON Test Pattern pass3": {
|
||||
"The outermost value": "must be an object or array.",
|
||||
"In this test": "It is an object."
|
||||
}
|
||||
}
|
||||
|
||||
]]))
|
|
@ -6,9 +6,30 @@ PKGS += TEST_TOOL_NET
|
|||
TEST_TOOL_NET = $(TOOL_NET_A_DEPS) $(TOOL_NET_A)
|
||||
TEST_TOOL_NET_A = o/$(MODE)/test/tool/net/net.a
|
||||
TEST_TOOL_NET_FILES := $(wildcard test/tool/net/*)
|
||||
TEST_TOOL_NET_JSONORG := $(wildcard test/tool/net/samples/*)
|
||||
|
||||
TEST_TOOL_NET_JSONORG_STRICT = \
|
||||
test/tool/net/samples/fail10.lua \
|
||||
test/tool/net/samples/fail19.lua \
|
||||
test/tool/net/samples/fail20.lua \
|
||||
test/tool/net/samples/fail21.lua \
|
||||
test/tool/net/samples/fail25.lua \
|
||||
test/tool/net/samples/fail26.lua \
|
||||
test/tool/net/samples/fail27.lua \
|
||||
test/tool/net/samples/fail28.lua \
|
||||
test/tool/net/samples/fail4.lua \
|
||||
test/tool/net/samples/fail5.lua \
|
||||
test/tool/net/samples/fail6.lua \
|
||||
test/tool/net/samples/fail7.lua \
|
||||
test/tool/net/samples/fail8.lua \
|
||||
test/tool/net/samples/fail9.lua
|
||||
|
||||
TEST_TOOL_NET_JSONORG_LUA = $(filter-out $(TEST_TOOL_NET_JSONORG_STRICT),$(filter %.lua,$(TEST_TOOL_NET_JSONORG)))
|
||||
TEST_TOOL_NET_SRCS = $(filter %.c,$(TEST_TOOL_NET_FILES))
|
||||
TEST_TOOL_NET_SRCS_TEST = $(filter %_test.c,$(TEST_TOOL_NET_SRCS))
|
||||
TEST_TOOL_NET_LUAS_TEST = $(filter %_test.lua,$(TEST_TOOL_NET_FILES))
|
||||
TEST_TOOL_NET_LUAS_TEST = \
|
||||
$(filter %_test.lua,$(TEST_TOOL_NET_FILES)) \
|
||||
$(TEST_TOOL_NET_JSONORG_LUA)
|
||||
TEST_TOOL_NET_HDRS = $(filter %.h,$(TEST_TOOL_NET_FILES))
|
||||
TEST_TOOL_NET_COMS = $(TEST_TOOL_NET_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
|
|
|
@ -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…
Reference in a new issue