diff --git a/src/jsony.nim b/src/jsony.nim index da3c165..4621185 100644 --- a/src/jsony.nim +++ b/src/jsony.nim @@ -477,7 +477,18 @@ proc parseHook*[T: object|ref object](s: string, i: var int, v: var T) = new(v) break i = saveI - parseObjectInner(s, i, v) + when v.isObjectVariant: + # Object variant, check for duplicate discriminator field. + # -d:release has different behavior. + let discBefore = v.discriminatorField + try: + parseObjectInner(s, i, v) + except FieldDefect: + error("Duplicate discriminator field.", i) + if v.discriminatorField != discBefore: + error("Duplicate discriminator field.", i) + else: + parseObjectInner(s, i, v) eatChar(s, i, '}') proc parseHook*[T](s: string, i: var int, v: var Option[T]) = diff --git a/tests/test_objects.nim b/tests/test_objects.nim index b6ff01d..d1eb34a 100644 --- a/tests/test_objects.nim +++ b/tests/test_objects.nim @@ -282,6 +282,29 @@ block: doAssert c.kind == nkFloat doAssert d.kind == nkInt + +block: + # Duplicate discriminator with a conflicting value raises JsonError. + var raised = false + try: + discard """{"kind":"nkFloat","floatVal":3.14,"kind":"nkInt"}""".fromJson( + ValueNode) + except JsonError: + raised = true + doAssert raised, + "expected JsonError for conflicting duplicate discriminator" + +block: + # Same test for ref object variant. + var raised = false + try: + discard """{"kind":"nkFloat","floatVal":3.14,"kind":"nkInt"}""".fromJson( + RefNode) + except JsonError: + raised = true + doAssert raised, + "expected JsonError for conflicting duplicate discriminator" + # test https://forum.nim-lang.org/t/7619 import jsony