diff options
-rw-r--r-- | lib/pure/json.nim | 10 | ||||
-rw-r--r-- | tests/stdlib/tjsonmacro.nim | 4 | ||||
-rw-r--r-- | tests/stdlib/tjsonmacro_reject2.nim | 21 |
3 files changed, 32 insertions, 3 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 1d2f480c4..9e7510e45 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1651,6 +1651,13 @@ import options proc workaroundMacroNone[T](): Option[T] = none(T) +proc depth(n: NimNode, current = 0): int = + result = 1 + for child in n: + let d = 1 + child.depth(current + 1) + if d > result: + result = d + proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ## Accepts a type description, i.e. "ref Type", "seq[Type]", "Type" etc. ## @@ -1660,6 +1667,9 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = # echo("--createConsuctor-- \n", treeRepr(typeSym)) # echo() + if depth(jsonNode) > 150: + error("The `to` macro does not support ref objects with cycles.", jsonNode) + case typeSym.kind of nnkBracketExpr: var bracketName = ($typeSym[0]).normalize diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 2baa7bed1..e2d8c27cf 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -354,6 +354,4 @@ when isMainModule: let dataDeser = to(dataParsed, Test) doAssert dataDeser.name == "FooBar" doAssert dataDeser.fallback.kind == JFloat - doAssert dataDeser.fallback.getFloat() == 56.42 - - # TODO: Cycles lead to infinite loops. \ No newline at end of file + doAssert dataDeser.fallback.getFloat() == 56.42 \ No newline at end of file diff --git a/tests/stdlib/tjsonmacro_reject2.nim b/tests/stdlib/tjsonmacro_reject2.nim new file mode 100644 index 000000000..b01153553 --- /dev/null +++ b/tests/stdlib/tjsonmacro_reject2.nim @@ -0,0 +1,21 @@ +discard """ + file: "tjsonmacro_reject2.nim" + line: 10 + errormsg: "The `to` macro does not support ref objects with cycles." +""" +import json + +type + Misdirection = object + cycle: Cycle + + Cycle = ref object + foo: string + cycle: Misdirection + +let data = """ + {"cycle": null} +""" + +let dataParsed = parseJson(data) +let dataDeser = to(dataParsed, Cycle) \ No newline at end of file |