mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-20 22:00:57 +00:00
Add checks to fromJson when trying to convert to an array (#26109)
Issue popped up when using `fromJson` into an array but the JSON passed
is an object
```nim
import std/[jsonutils, json]
let data = parseJson """
{"key": "value"}
"""
var foo: seq[int]
foo.fromJson(data)
echo foo #> @[0]
```
Basically the `setLen` would set the size to be equal to the number of
keys, but `getElems` just returns an empty array if the JSON isn't an
array which lead to it just creating zero'd items in the seq without
letting the user know.
Felt adding the checks was better than just skipping the `setLen` since
it lets the user know that there is a problem with the JSON
This commit is contained in:
@@ -99,6 +99,7 @@ parameter and result types, not just their source-level shape. Use
|
||||
works without single-quoting.
|
||||
- `std/uri`: The `?` operator now appends query parameters to an existing query
|
||||
string instead of replacing it. Fixes [#19782](https://github.com/nim-lang/Nim/issues/19782).
|
||||
- `std/jsonutils`: `fromJson` now throws an exception when converting to `array`/`seq` if the JSON isn't an array instead of silently failing
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
@@ -238,6 +238,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
|
||||
a = T()
|
||||
fromJson(a[], b, opt)
|
||||
elif T is array:
|
||||
checkJson b.kind == JArray
|
||||
checkJson a.len == b.len, "Json array size doesn't match for " & $T
|
||||
var i = 0
|
||||
for ai in mitems(a):
|
||||
@@ -248,6 +249,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
|
||||
for val in b.getElems:
|
||||
incl a, jsonTo(val, E)
|
||||
elif T is seq:
|
||||
checkJson b.kind == JArray
|
||||
a.setLen b.len
|
||||
for i, val in b.getElems:
|
||||
fromJson(a[i], val, opt)
|
||||
|
||||
@@ -451,6 +451,12 @@ template fn() =
|
||||
let json = inner.toJson(ToJsonOptions(enumMode: joptEnumSymbol))
|
||||
doAssert $json == """{"x":"hello","y":"A"}"""
|
||||
|
||||
block arrayTypeCheck:
|
||||
let json = """{"key": "value"}""".parseJson()
|
||||
var output: seq[int]
|
||||
doAssertRaises(ValueError):
|
||||
output.fromJson(json)
|
||||
|
||||
block: # bug #21638
|
||||
type Something = object
|
||||
|
||||
|
||||
Reference in New Issue
Block a user