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:
Jake Leahy
2026-08-19 16:24:25 +10:00
committed by GitHub
parent 1201c184d7
commit 81325d0745
3 changed files with 9 additions and 0 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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