diff options
author | flaviut <tamasflaviu@gmail.com> | 2014-04-13 17:42:52 -0400 |
---|---|---|
committer | flaviut <tamasflaviu@gmail.com> | 2014-04-13 17:49:16 -0400 |
commit | ec59b790c52223ff8c8f3f489005df1b6e4a51b6 (patch) | |
tree | 9e690bdaf921d1f3ddfe920931132905a1b03417 /lib/pure | |
parent | 64d3b9a34d0b51a6507a9be7ebd2d6fd25d64977 (diff) | |
download | Nim-ec59b790c52223ff8c8f3f489005df1b6e4a51b6.tar.gz |
JSON index accesses are bounds checked
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/json.nim | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 38cdcc3db..4d6ecb837 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -644,13 +644,16 @@ proc `[]`*(node: PJsonNode, name: string, default: PJsonNode = nil): PJsonNode = return item return default -proc `[]`*(node: PJsonNode, index: int, default: PJsonNode = nil): PJsonNode = +proc `[]`*(node: PJsonNode, index: int, default: PJsonNode = nil): PJsonNode {.raises: [EInvalidIndex].}= ## Gets the node at `index` in an Array.If `node` is nil, this returns `result`, - ## which is by default `nil` to allow for chaining. Results are undefined if - ## the index is out of range. + ## which is by default `nil` to allow for chaining. `EInvalidIndex` is raised if `index` + ## is out of bounds if isNil(node): return default assert(node.kind == JArray) + if index < 0 or index >= node.elems.len: + raise newException(EInvalidIndex, + "index " & $index & " is out of range [0, " & $node.elems.len & ")") return node.elems[index] proc hasKey*(node: PJsonNode, key: string): bool = @@ -937,13 +940,29 @@ when isMainModule: raise newException(EInvalidValue, "That line was expected to fail") except EInvalidIndex: echo() - let passthroughTest = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" + let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" # nil passthrough - assert(passthroughTest["doesnt_exist"][1] == nil) - assert(passthroughTest["doesnt_exist"]["anything"] == nil) + assert(testJson["doesnt_exist"][1] == nil) + assert(testJson["doesnt_exist"]["anything"] == nil) # default param - assert(passthroughTest["doesnt_exist",%true].bval) - assert(passthroughTest["doesnt_exist"][1,%true].bval) + assert(testJson["doesnt_exist",%true].bval) + assert(testJson["doesnt_exist"][1,%true].bval) + + # Bounds checking + try: + let a = testJson["a"][9] + assert(false, "EInvalidIndex not thrown") + except EInvalidIndex: + discard + try: + let a = testJson["a"][-1] + assert(false, "EInvalidIndex not thrown") + except EInvalidIndex: + discard + try: + assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value") + except: + assert(false, "EInvalidIndex thrown for valid index") discard """ while true: |