From a57b1d7face65057573c6bf9aacb19ef12015c62 Mon Sep 17 00:00:00 2001 From: Miran Date: Tue, 14 Dec 2021 18:16:49 +0100 Subject: [PATCH] [backport:1.0] json: limit recursion depth (#19252) * json: limit recursion depth * do not run this check for JS backend (cherry picked from commit c17baaefbcff5c207a4e95242fa0790e64ca6c8c) --- lib/pure/json.nim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 9d2d1c82191b..4c776ef4fb1f 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -181,6 +181,8 @@ type of JArray: elems*: seq[JsonNode] +const DepthLimit = 1000 + proc newJString*(s: string): JsonNode = ## Creates a new `JString JsonNode`. result = JsonNode(kind: JString, str: s) @@ -785,7 +787,7 @@ iterator mpairs*(node: var JsonNode): tuple[key: string, val: var JsonNode] = for key, val in mpairs(node.fields): yield (key, val) -proc parseJson(p: var JsonParser): JsonNode = +proc parseJson(p: var JsonParser, depth=0): JsonNode = ## Parses JSON from a JSON Parser `p`. case p.tok of tkString: @@ -809,6 +811,8 @@ proc parseJson(p: var JsonParser): JsonNode = result = newJNull() discard getTok(p) of tkCurlyLe: + if depth > DepthLimit: + raiseParseErr(p, "}") result = newJObject() discard getTok(p) while p.tok != tkCurlyRi: @@ -817,16 +821,18 @@ proc parseJson(p: var JsonParser): JsonNode = var key = p.a discard getTok(p) eat(p, tkColon) - var val = parseJson(p) + var val = parseJson(p, depth+1) result[key] = val if p.tok != tkComma: break discard getTok(p) eat(p, tkCurlyRi) of tkBracketLe: + if depth > DepthLimit: + raiseParseErr(p, "]") result = newJArray() discard getTok(p) while p.tok != tkBracketRi: - result.add(parseJson(p)) + result.add(parseJson(p, depth+1)) if p.tok != tkComma: break discard getTok(p) eat(p, tkBracketRi)