mirror of
https://github.com/logos-storage/nim-serde.git
synced 2026-01-02 13:43:06 +00:00
add compile-time checks to prevent use of serialize/deserialize pragmas in CBOR
This commit is contained in:
parent
50000bc0c9
commit
0096796d66
@ -607,10 +607,11 @@ proc fromCbor*[T: object](_: type T, n: CborNode): ?!T =
|
||||
return success T(n)
|
||||
|
||||
expectCborKind(T, {cborMap}, n)
|
||||
|
||||
var res = T.default
|
||||
|
||||
let mode = getSerdeMode(T, deserialize)
|
||||
# Added because serde {serialize, deserialize} pragmas and options are not supported cbor
|
||||
assertNoPragma(T, deserialize, "deserialize pragma not supported")
|
||||
|
||||
try:
|
||||
var
|
||||
i: int
|
||||
@ -621,6 +622,8 @@ proc fromCbor*[T: object](_: type T, n: CborNode): ?!T =
|
||||
else:
|
||||
res
|
||||
):
|
||||
assertNoPragma(value, deserialize, "deserialize pragma not supported")
|
||||
|
||||
key.text = name
|
||||
|
||||
if not n.map.hasKey key:
|
||||
|
||||
@ -36,7 +36,3 @@ proc newUnexpectedKindError*(
|
||||
|
||||
proc newCborError*(msg: string): ref CborParseError =
|
||||
newException(CborParseError, msg)
|
||||
|
||||
template parseAssert*(check: bool, msg = "") =
|
||||
if not check:
|
||||
raise newException(CborParseError, msg)
|
||||
|
||||
@ -27,6 +27,15 @@ template expectCborKind*(
|
||||
) =
|
||||
expectCborKind(expectedType, {expectedKind}, cbor)
|
||||
|
||||
template parseAssert*(check: bool, msg = "") =
|
||||
if not check:
|
||||
raise newException(CborParseError, msg)
|
||||
|
||||
template assertNoPragma*(value, pragma, msg) =
|
||||
static:
|
||||
when value.hasCustomPragma(pragma):
|
||||
raiseAssert(msg)
|
||||
|
||||
macro dot*(obj: object, fld: string): untyped =
|
||||
## Turn ``obj.dot("fld")`` into ``obj.fld``.
|
||||
newDotExpr(obj, newIdentNode(fld.strVal))
|
||||
|
||||
@ -5,7 +5,9 @@ import std/[streams, options, tables, typetraits, math, endians, times]
|
||||
import pkg/questionable
|
||||
import pkg/questionable/results
|
||||
import ../utils/errors
|
||||
import ../utils/pragmas
|
||||
import ./types
|
||||
import ./helpers
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
@ -265,10 +267,15 @@ proc writeCbor*(str: Stream, v: CborNode): ?!void =
|
||||
|
||||
proc writeCbor*[T: object](str: Stream, v: T): ?!void =
|
||||
var n: uint
|
||||
# Added because serde {serialize, deserialize} pragma and options are not supported cbor
|
||||
assertNoPragma(T, serialize, "serialize pragma not supported")
|
||||
|
||||
for _, _ in v.fieldPairs:
|
||||
inc n
|
||||
?str.writeInitial(5, n)
|
||||
|
||||
for k, f in v.fieldPairs:
|
||||
assertNoPragma(f, serialize, "serialize pragma not supported")
|
||||
?str.writeCbor(k)
|
||||
?str.writeCbor(f)
|
||||
success()
|
||||
|
||||
@ -43,9 +43,6 @@ type
|
||||
NewType = ref object
|
||||
size: uint64
|
||||
|
||||
# Reference type for Inner object
|
||||
InnerRef = ref Inner
|
||||
|
||||
# Complex object with various field types to test comprehensive serialization
|
||||
CompositeNested = object
|
||||
u: uint64 # Unsigned integer
|
||||
|
||||
45
tests/cbor/testPragmaChecks.nim
Normal file
45
tests/cbor/testPragmaChecks.nim
Normal file
@ -0,0 +1,45 @@
|
||||
import std/unittest
|
||||
import std/streams
|
||||
|
||||
import ../../serde/cbor
|
||||
import ../../serde/utils/pragmas
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
suite "CBOR pragma checks":
|
||||
test "fails to compile when object marked with 'serialize' pragma":
|
||||
type SerializeTest {.serialize.} = object
|
||||
value: int
|
||||
|
||||
check not compiles(toCbor(SerializeTest(value: 42)))
|
||||
|
||||
test "fails to compile when object marked with 'deserialize' pragma":
|
||||
type DeserializeTest {.deserialize.} = object
|
||||
value: int
|
||||
|
||||
let node = CborNode(kind: cborMap)
|
||||
check not compiles(DeserializeTest.fromCbor(node))
|
||||
|
||||
test "fails to compile when field marked with 'serialize' pragma":
|
||||
type FieldSerializeTest = object
|
||||
normalField: int
|
||||
pragmaField {.serialize.}: int
|
||||
|
||||
check not compiles(toCbor(FieldSerializeTest(normalField: 42, pragmaField: 100)))
|
||||
|
||||
test "fails to compile when field marked with 'deserialize' pragma":
|
||||
type FieldDeserializeTest = object
|
||||
normalField: int
|
||||
pragmaField {.deserialize.}: int
|
||||
|
||||
let node = CborNode(kind: cborMap)
|
||||
check not compiles(FieldDeserializeTest.fromCbor(node))
|
||||
|
||||
test "compiles when type has no pragmas":
|
||||
type NoPragmaTest = object
|
||||
value: int
|
||||
|
||||
check compiles(toCbor(NoPragmaTest(value: 42)))
|
||||
|
||||
let node = CborNode(kind: cborMap)
|
||||
check compiles(NoPragmaTest.fromCbor(node))
|
||||
Loading…
x
Reference in New Issue
Block a user