Skip to content

Commit 0b1fee5

Browse files
committed
[backport:1.0] json: limit recursion depth (#19252)
* json: limit recursion depth * do not run this check for JS backend (cherry picked from commit c17baae)
1 parent 5948316 commit 0b1fee5

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

lib/pure/json.nim

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ type
181181
of JArray:
182182
elems*: seq[JsonNode]
183183

184+
const DepthLimit = 1000
185+
184186
proc newJString*(s: string): JsonNode =
185187
## Creates a new `JString JsonNode`.
186188
result = JsonNode(kind: JString, str: s)
@@ -771,7 +773,7 @@ iterator mpairs*(node: var JsonNode): tuple[key: string, val: var JsonNode] =
771773
for key, val in mpairs(node.fields):
772774
yield (key, val)
773775

774-
proc parseJson(p: var JsonParser): JsonNode =
776+
proc parseJson(p: var JsonParser, depth=0): JsonNode =
775777
## Parses JSON from a JSON Parser `p`.
776778
case p.tok
777779
of tkString:
@@ -795,6 +797,8 @@ proc parseJson(p: var JsonParser): JsonNode =
795797
result = newJNull()
796798
discard getTok(p)
797799
of tkCurlyLe:
800+
if depth > DepthLimit:
801+
raiseParseErr(p, "}")
798802
result = newJObject()
799803
discard getTok(p)
800804
while p.tok != tkCurlyRi:
@@ -803,16 +807,18 @@ proc parseJson(p: var JsonParser): JsonNode =
803807
var key = p.a
804808
discard getTok(p)
805809
eat(p, tkColon)
806-
var val = parseJson(p)
810+
var val = parseJson(p, depth+1)
807811
result[key] = val
808812
if p.tok != tkComma: break
809813
discard getTok(p)
810814
eat(p, tkCurlyRi)
811815
of tkBracketLe:
816+
if depth > DepthLimit:
817+
raiseParseErr(p, "]")
812818
result = newJArray()
813819
discard getTok(p)
814820
while p.tok != tkBracketRi:
815-
result.add(parseJson(p))
821+
result.add(parseJson(p, depth+1))
816822
if p.tok != tkComma: break
817823
discard getTok(p)
818824
eat(p, tkBracketRi)

0 commit comments

Comments
 (0)