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 { 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')) 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 { match p.tok.kind {
.lsbr { .lsbr {
return p.decode_array() return p.decode_array()
@ -150,6 +146,7 @@ fn (mut p Parser) decode_value() ?Any {
fn (mut p Parser) decode_array() ?Any { fn (mut p Parser) decode_array() ?Any {
mut items := []Any{} mut items := []Any{}
p.next_with_err() ? p.next_with_err() ?
p.n_level++
for p.tok.kind != .rsbr { for p.tok.kind != .rsbr {
item := p.decode_value() ? item := p.decode_value() ?
items << item items << item
@ -169,12 +166,14 @@ fn (mut p Parser) decode_array() ?Any {
} }
} }
p.next_with_err() ? p.next_with_err() ?
p.n_level--
return Any(items) return Any(items)
} }
fn (mut p Parser) decode_object() ?Any { fn (mut p Parser) decode_object() ?Any {
mut fields := map[string]Any{} mut fields := map[string]Any{}
p.next_with_err() ? p.next_with_err() ?
p.n_level++
for p.tok.kind != .rcbr { for p.tok.kind != .rcbr {
is_key := p.tok.kind == .str_ && p.n_tok.kind == .colon is_key := p.tok.kind == .str_ && p.n_tok.kind == .colon
if !is_key { if !is_key {
@ -196,5 +195,6 @@ fn (mut p Parser) decode_object() ?Any {
} }
} }
p.next_with_err() ? p.next_with_err() ?
p.n_level--
return Any(fields) return Any(fields)
} }

View File

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