x.json2: fix nest level check (#10584)

pull/10600/head
Ned Palacios 2021-06-28 19:05:27 +08:00 committed by GitHub
parent cdb31119f3
commit 003f60fc1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 50 deletions

View File

@ -92,13 +92,9 @@ fn (mut p Parser) decode() ?Any {
}
fn (mut p Parser) decode_value() ?Any {
if p.n_level == 500 {
if p.n_level + 1 == 500 {
return error(p.emit_error('reached maximum nesting level of 500'))
}
if (p.tok.kind == .lsbr && p.n_tok.kind == .lcbr)
|| (p.p_tok.kind == p.tok.kind && p.tok.kind == .lsbr) {
p.n_level++
}
match p.tok.kind {
.lsbr {
return p.decode_array()
@ -150,6 +146,7 @@ fn (mut p Parser) decode_value() ?Any {
fn (mut p Parser) decode_array() ?Any {
mut items := []Any{}
p.next_with_err() ?
p.n_level++
for p.tok.kind != .rsbr {
item := p.decode_value() ?
items << item
@ -169,12 +166,14 @@ fn (mut p Parser) decode_array() ?Any {
}
}
p.next_with_err() ?
p.n_level--
return Any(items)
}
fn (mut p Parser) decode_object() ?Any {
mut fields := map[string]Any{}
p.next_with_err() ?
p.n_level++
for p.tok.kind != .rcbr {
is_key := p.tok.kind == .str_ && p.n_tok.kind == .colon
if !is_key {
@ -196,5 +195,6 @@ fn (mut p Parser) decode_object() ?Any {
}
}
p.next_with_err() ?
p.n_level--
return Any(fields)
}

View File

@ -1,80 +1,61 @@
import x.json2
module json2
fn test_raw_decode_string() {
str := json2.raw_decode('"Hello!"') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_string() ? {
str := raw_decode('"Hello!"') ?
assert str.str() == 'Hello!'
}
fn test_raw_decode_number() {
num := json2.raw_decode('123') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_number() ? {
num := raw_decode('123') ?
assert num.int() == 123
}
fn test_raw_decode_array() {
raw_arr := json2.raw_decode('["Foo", 1]') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_array() ? {
raw_arr := raw_decode('["Foo", 1]') ?
arr := raw_arr.arr()
assert arr[0].str() == 'Foo'
assert arr[1].int() == 1
}
fn test_raw_decode_bool() {
bol := json2.raw_decode('false') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_bool() ? {
bol := raw_decode('false') ?
assert bol.bool() == false
}
fn test_raw_decode_map() {
raw_mp := json2.raw_decode('{"name":"Bob","age":20}') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_map() ? {
raw_mp := raw_decode('{"name":"Bob","age":20}') ?
mp := raw_mp.as_map()
assert mp['name'].str() == 'Bob'
assert mp['age'].int() == 20
}
fn test_raw_decode_null() {
nul := json2.raw_decode('null') or {
assert false
json2.Any(json2.null)
}
assert nul is json2.Null
fn test_raw_decode_null() ? {
nul := raw_decode('null') ?
assert nul is Null
}
fn test_raw_decode_invalid() {
json2.raw_decode('1z') or {
fn test_raw_decode_invalid() ? {
raw_decode('1z') or {
assert err.msg == '[x.json2] invalid token `z` (0:17)'
return
}
assert false
}
fn test_raw_decode_string_with_dollarsign() {
str := json2.raw_decode(r'"Hello $world"') or {
assert false
json2.Any(json2.null)
}
fn test_raw_decode_string_with_dollarsign() ? {
str := raw_decode(r'"Hello $world"') ?
assert str.str() == r'Hello $world'
}
fn test_raw_decode_map_with_whitespaces() {
raw_mp := json2.raw_decode(' \n\t{"name":"Bob","age":20}\n\t') or {
eprintln(err.msg)
assert false
json2.Any(json2.null)
}
fn test_raw_decode_map_with_whitespaces() ? {
raw_mp := raw_decode(' \n\t{"name":"Bob","age":20}\n\t') ?
mp := raw_mp.as_map()
assert mp['name'].str() == 'Bob'
assert mp['age'].int() == 20
}
fn test_nested_array_object() ? {
mut parser := new_parser(r'[[[[[],[],[]]]],{"Test":{}},[[]]]', false)
decoded := parser.decode() ?
assert parser.n_level == 0
}