Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Valid json (?) is refused #8

Closed
mratsim opened this issue Feb 9, 2021 · 3 comments
Closed

Valid json (?) is refused #8

mratsim opened this issue Feb 9, 2021 · 3 comments

Comments

@mratsim
Copy link

mratsim commented Feb 9, 2021

I'm trying to isolate a bug with distinct type and create a minimal repro but I ended up getting stuck in another issue:

import jsony

type
  SecretWord = distinct uint64

  CryptographicType = object
    data: array[4, SecretWord]

  TestVector[T] = object
    vectors: seq[T]

proc parseHook(src: string, pos: var int, value: var CryptographicType) =
  var str: string
  parseHook(src, pos, str)
  discard "value.fromHex(str)"

let s = """
{
	"vectors": [{
		"data": "0x2523648240000001ba344d80000000086121000000000013a700000000000013"
	}]
}
"""
let v = s.fromJson(TestVector[CryptographicType])

According to https://jsonlint.com/ this is valid JSON but somehow I get

/[...]/Programming/Nim/constantine/build/jsony_distinct.nim(24) jsony_distinct
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(434) fromJson
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(318) parseHook
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(170) parseHook
/[...]/Programming/Nim/constantine/build/jsony_distinct.nim(14) parseHook
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(44) parseHook
Error: unhandled exception: Expected ". At offset: 15 [JsonError]

End goal

I'll open an issue if this ends up being an issue in jsony

I am trying to replace nim-json-serialization for my test vectors, it brings many dependencies and one is crashing my CI at the moment for a git clone issue: https://github.com/mratsim/constantine/pull/155/checks?check_run_id=1865342674#step:15:60 and unfortunately there is no easy way out of it until Nimble supports task level dependencies (it's a library tested with nim-json-serialization that is brought) (nim-lang/nimble#482).

I use distinct types in there but they are all caught by the 2 readValue in nim-json-serialization (https://github.com/mratsim/constantine/blob/c4a2dee/tests/t_ec_sage_template.nim#L95-L178) and example file (https://github.com/mratsim/constantine/blob/c4a2dee/tests/vectors/tv_BN254_Nogami_scalar_mul_G1.json). Somehow at the moment jsony is trying to parseHook those.

/[...]/Programming/Nim/constantine/tests/t_ec_sage_bls12_381.nim(18, 28) template/generic instantiation of `run_scalar_mul_test_vs_sage` from here
/[...]/Programming/Nim/constantine/tests/t_ec_sage_template.nim(186, 26) template/generic instantiation of `loadVectors` from here
/[...]/Programming/Nim/constantine/tests/t_ec_sage_template.nim(172, 19) template/generic instantiation of `fromJson` from here
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(434, 4) template/generic instantiation of `parseHook` from here
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(318, 20) template/generic instantiation of `parseHook` from here
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(170, 14) template/generic instantiation of `parseHook` from here
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(318, 20) template/generic instantiation of `parseHook` from here
/[...]/.nimble/pkgs/jsony-0.0.5/jsony.nim(197, 14) Error: type mismatch: got <string, int, SecretWord>
but expected one of: 
proc parseHook(s: string; i: var int; v: var JsonNode)
  first type mismatch at position: 3
  required type for v: var JsonNode
  but expression 'value' is of type: SecretWord
proc parseHook(s: string; i: var int; v: var SomeFloat)
  first type mismatch at position: 3
  required type for v: var SomeFloat
  but expression 'value' is of type: SecretWord
@mratsim
Copy link
Author

mratsim commented Feb 9, 2021

Edit: I didn't solve the original issue but found what was wrong for the end goal, it seems like due to Nim visibility constraint with generics parseHook must be exported or Nim won't use the proper one. This might need an entry in the README

@treeform
Copy link
Owner

treeform commented Feb 9, 2021

I could make the error message better. Its not saying the json is invalid is saying it's expecting something like a string but gets some thing else.

You had hook on CryptographicType, but that contains {"data":.... still but you where asking for a string. I changed it to look for var array[4, SecretWord] instead.

... and yes the parse hook needs to be visible where you are doing the parsing. I should add that to the doc.

This works:

import jsony, strutils

type
  SecretWord = distinct uint64

  CryptographicType = object
    data: array[4, SecretWord]

  TestVector[T] = object
    vectors: seq[T]

proc parseHook(src: string, pos: var int, value: var array[4, SecretWord]) =
  var str: string
  parseHook(src, pos, str)
  for i in 0 ..< 4:
    let hexStr = str[2 + i*16 ..< 2 + i*16 + 16]
    echo hexStr
    value[i] = SecretWord(fromHex[uint64](hexStr))

let s = """
{
	"vectors": [{
		"data": "0x2523648240000001ba344d80000000086121000000000013a700000000000013"
	}]
}
"""
let v = s.fromJson(TestVector[CryptographicType])
echo v

@mratsim mratsim closed this as completed Feb 9, 2021
@treeform
Copy link
Owner

treeform commented Feb 9, 2021

Added a message about needed to export as well as have all examples use exports stars.

907bd3c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants