[backport:1.0] json: limit recursion depth (#19252)
* json: limit recursion depth * do not run this check for JS backend
This commit is contained in:
parent
3e31f55aed
commit
c17baaefbc
2 changed files with 41 additions and 3 deletions
|
|
@ -202,6 +202,8 @@ type
|
||||||
of JArray:
|
of JArray:
|
||||||
elems*: seq[JsonNode]
|
elems*: seq[JsonNode]
|
||||||
|
|
||||||
|
const DepthLimit = 1000
|
||||||
|
|
||||||
proc newJString*(s: string): JsonNode =
|
proc newJString*(s: string): JsonNode =
|
||||||
## Creates a new `JString JsonNode`.
|
## Creates a new `JString JsonNode`.
|
||||||
result = JsonNode(kind: JString, str: s)
|
result = JsonNode(kind: JString, str: s)
|
||||||
|
|
@ -849,7 +851,7 @@ iterator mpairs*(node: var JsonNode): tuple[key: string, val: var JsonNode] =
|
||||||
for key, val in mpairs(node.fields):
|
for key, val in mpairs(node.fields):
|
||||||
yield (key, val)
|
yield (key, val)
|
||||||
|
|
||||||
proc parseJson(p: var JsonParser; rawIntegers, rawFloats: bool): JsonNode =
|
proc parseJson(p: var JsonParser; rawIntegers, rawFloats: bool, depth = 0): JsonNode =
|
||||||
## Parses JSON from a JSON Parser `p`.
|
## Parses JSON from a JSON Parser `p`.
|
||||||
case p.tok
|
case p.tok
|
||||||
of tkString:
|
of tkString:
|
||||||
|
|
@ -885,6 +887,8 @@ proc parseJson(p: var JsonParser; rawIntegers, rawFloats: bool): JsonNode =
|
||||||
result = newJNull()
|
result = newJNull()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
of tkCurlyLe:
|
of tkCurlyLe:
|
||||||
|
if depth > DepthLimit:
|
||||||
|
raiseParseErr(p, "}")
|
||||||
result = newJObject()
|
result = newJObject()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
while p.tok != tkCurlyRi:
|
while p.tok != tkCurlyRi:
|
||||||
|
|
@ -893,16 +897,18 @@ proc parseJson(p: var JsonParser; rawIntegers, rawFloats: bool): JsonNode =
|
||||||
var key = p.a
|
var key = p.a
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
eat(p, tkColon)
|
eat(p, tkColon)
|
||||||
var val = parseJson(p, rawIntegers, rawFloats)
|
var val = parseJson(p, rawIntegers, rawFloats, depth+1)
|
||||||
result[key] = val
|
result[key] = val
|
||||||
if p.tok != tkComma: break
|
if p.tok != tkComma: break
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
eat(p, tkCurlyRi)
|
eat(p, tkCurlyRi)
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
|
if depth > DepthLimit:
|
||||||
|
raiseParseErr(p, "]")
|
||||||
result = newJArray()
|
result = newJArray()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
while p.tok != tkBracketRi:
|
while p.tok != tkBracketRi:
|
||||||
result.add(parseJson(p, rawIntegers, rawFloats))
|
result.add(parseJson(p, rawIntegers, rawFloats, depth+1))
|
||||||
if p.tok != tkComma: break
|
if p.tok != tkComma: break
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
eat(p, tkBracketRi)
|
eat(p, tkBracketRi)
|
||||||
|
|
|
||||||
|
|
@ -345,3 +345,35 @@ block:
|
||||||
doAssert c == "18446744073709552000"
|
doAssert c == "18446744073709552000"
|
||||||
else:
|
else:
|
||||||
doAssert c == "18446744073709551615"
|
doAssert c == "18446744073709551615"
|
||||||
|
|
||||||
|
block:
|
||||||
|
let a = """
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
|
||||||
|
"""
|
||||||
|
|
||||||
|
when not defined(js):
|
||||||
|
try:
|
||||||
|
discard parseJson(a)
|
||||||
|
except JsonParsingError:
|
||||||
|
doAssert getCurrentExceptionMsg().contains("] expected")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue