avoid implicit `CaseTransition` in keystore Json parsing (#5061)

Override default Json parsing for keystore case objects to avoid
`CaseTransition` logic to be emitted. When parsing the discriminator,
reinitialize the entire object instead of implicitly changing it,
to avoid UB and also possible oversights when extending the object.
See https://github.com/status-im/nim-serialization/pull/59
This commit is contained in:
Etan Kissling 2023-06-16 19:02:53 +02:00 committed by GitHub
parent 591c2246d5
commit aa54760391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 99 additions and 3 deletions

View File

@ -556,8 +556,94 @@ proc readValue*[T: SimpleHexEncodedTypes](r: var JsonReader, value: var T) {.
if len(seq[byte](value)) == 0:
r.raiseUnexpectedValue("Valid hex string expected")
proc readValue*(r: var JsonReader, value: var Kdf)
{.raises: [SerializationError, IOError, Defect].} =
template readValueImpl(r: var JsonReader, value: var Checksum) =
var
functionSpecified = false
paramsSpecified = false
messageSpecified = false
for fieldName in readObjectFields(r):
case fieldName
of "function":
value = Checksum(function: r.readValue(ChecksumFunctionKind))
functionSpecified = true
of "params":
if functionSpecified:
case value.function
of sha256Checksum:
r.readValue(value.params)
else:
r.raiseUnexpectedValue(
"The 'params' field must be specified after the 'function' field")
paramsSpecified = true
of "message":
if functionSpecified:
case value.function
of sha256Checksum:
r.readValue(value.message)
else:
r.raiseUnexpectedValue(
"The 'message' field must be specified after the 'function' field")
messageSpecified = true
else:
r.raiseUnexpectedField(fieldName, "Checksum")
if not (functionSpecified and paramsSpecified and messageSpecified):
r.raiseUnexpectedValue(
"The Checksum value should have sub-fields named " &
"'function', 'params', and 'message'")
{.push warning[ProveField]:off.} # https://github.com/nim-lang/Nim/issues/22060
proc readValue*(r: var JsonReader[DefaultFlavor], value: var Checksum)
{.raises: [SerializationError, IOError].} =
readValueImpl(r, value)
{.pop.}
template readValueImpl(r: var JsonReader, value: var Cipher) =
var
functionSpecified = false
paramsSpecified = false
messageSpecified = false
for fieldName in readObjectFields(r):
case fieldName
of "function":
value = Cipher(
function: r.readValue(CipherFunctionKind), message: value.message)
functionSpecified = true
of "params":
if functionSpecified:
case value.function
of aes128CtrCipher:
r.readValue(value.params)
else:
r.raiseUnexpectedValue(
"The 'params' field must be specified after the 'function' field")
paramsSpecified = true
of "message":
r.readValue(value.message)
messageSpecified = true
else:
r.raiseUnexpectedField(fieldName, "Cipher")
if not (functionSpecified and paramsSpecified and messageSpecified):
r.raiseUnexpectedValue(
"The Cipher value should have sub-fields named " &
"'function', 'params', and 'message'")
{.push warning[ProveField]:off.} # https://github.com/nim-lang/Nim/issues/22060
proc readValue*(r: var JsonReader[DefaultFlavor], value: var Cipher)
{.raises: [SerializationError, IOError].} =
readValueImpl(r, value)
{.pop.}
template readValueImpl(r: var JsonReader, value: var Kdf) =
var
functionSpecified = false
paramsSpecified = false
@ -565,7 +651,7 @@ proc readValue*(r: var JsonReader, value: var Kdf)
for fieldName in readObjectFields(r):
case fieldName
of "function":
value.function = r.readValue(KdfKind)
value = Kdf(function: r.readValue(KdfKind), message: value.message)
functionSpecified = true
of "params":
@ -590,6 +676,16 @@ proc readValue*(r: var JsonReader, value: var Kdf)
r.raiseUnexpectedValue(
"The Kdf value should have sub-fields named 'function' and 'params'")
{.push warning[ProveField]:off.} # https://github.com/nim-lang/Nim/issues/22060
proc readValue*(r: var JsonReader[DefaultFlavor], value: var Kdf)
{.raises: [SerializationError, IOError].} =
readValueImpl(r, value)
{.pop.}
proc readValue*(r: var JsonReader, value: var (Checksum|Cipher|Kdf)) =
static: raiseAssert "Unknown flavor `JsonReader[" & $typeof(r).Flavor &
"]` for `readValue` of `" & $typeof(value) & "`"
# HttpHostUri
proc readValue*(reader: var JsonReader, value: var HttpHostUri) {.
raises: [IOError, SerializationError, Defect].} =