JSON index accesses are bounds checked
This commit is contained in:
parent
64d3b9a34d
commit
ec59b790c5
1 changed files with 27 additions and 8 deletions
|
|
@ -644,13 +644,16 @@ proc `[]`*(node: PJsonNode, name: string, default: PJsonNode = nil): PJsonNode =
|
||||||
return item
|
return item
|
||||||
return default
|
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`,
|
## 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
|
## which is by default `nil` to allow for chaining. `EInvalidIndex` is raised if `index`
|
||||||
## the index is out of range.
|
## is out of bounds
|
||||||
if isNil(node):
|
if isNil(node):
|
||||||
return default
|
return default
|
||||||
assert(node.kind == JArray)
|
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]
|
return node.elems[index]
|
||||||
|
|
||||||
proc hasKey*(node: PJsonNode, key: string): bool =
|
proc hasKey*(node: PJsonNode, key: string): bool =
|
||||||
|
|
@ -937,13 +940,29 @@ when isMainModule:
|
||||||
raise newException(EInvalidValue, "That line was expected to fail")
|
raise newException(EInvalidValue, "That line was expected to fail")
|
||||||
except EInvalidIndex: echo()
|
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
|
# nil passthrough
|
||||||
assert(passthroughTest["doesnt_exist"][1] == nil)
|
assert(testJson["doesnt_exist"][1] == nil)
|
||||||
assert(passthroughTest["doesnt_exist"]["anything"] == nil)
|
assert(testJson["doesnt_exist"]["anything"] == nil)
|
||||||
# default param
|
# default param
|
||||||
assert(passthroughTest["doesnt_exist",%true].bval)
|
assert(testJson["doesnt_exist",%true].bval)
|
||||||
assert(passthroughTest["doesnt_exist"][1,%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 """
|
discard """
|
||||||
while true:
|
while true:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue