mirror of
https://github.com/logos-storage/nim-serde.git
synced 2026-01-05 23:23:12 +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)
|
return success T(n)
|
||||||
|
|
||||||
expectCborKind(T, {cborMap}, n)
|
expectCborKind(T, {cborMap}, n)
|
||||||
|
|
||||||
var res = T.default
|
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:
|
try:
|
||||||
var
|
var
|
||||||
i: int
|
i: int
|
||||||
@ -621,6 +622,8 @@ proc fromCbor*[T: object](_: type T, n: CborNode): ?!T =
|
|||||||
else:
|
else:
|
||||||
res
|
res
|
||||||
):
|
):
|
||||||
|
assertNoPragma(value, deserialize, "deserialize pragma not supported")
|
||||||
|
|
||||||
key.text = name
|
key.text = name
|
||||||
|
|
||||||
if not n.map.hasKey key:
|
if not n.map.hasKey key:
|
||||||
|
|||||||
@ -36,7 +36,3 @@ proc newUnexpectedKindError*(
|
|||||||
|
|
||||||
proc newCborError*(msg: string): ref CborParseError =
|
proc newCborError*(msg: string): ref CborParseError =
|
||||||
newException(CborParseError, msg)
|
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)
|
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 =
|
macro dot*(obj: object, fld: string): untyped =
|
||||||
## Turn ``obj.dot("fld")`` into ``obj.fld``.
|
## Turn ``obj.dot("fld")`` into ``obj.fld``.
|
||||||
newDotExpr(obj, newIdentNode(fld.strVal))
|
newDotExpr(obj, newIdentNode(fld.strVal))
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import std/[streams, options, tables, typetraits, math, endians, times]
|
|||||||
import pkg/questionable
|
import pkg/questionable
|
||||||
import pkg/questionable/results
|
import pkg/questionable/results
|
||||||
import ../utils/errors
|
import ../utils/errors
|
||||||
|
import ../utils/pragmas
|
||||||
import ./types
|
import ./types
|
||||||
|
import ./helpers
|
||||||
|
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
@ -265,10 +267,15 @@ proc writeCbor*(str: Stream, v: CborNode): ?!void =
|
|||||||
|
|
||||||
proc writeCbor*[T: object](str: Stream, v: T): ?!void =
|
proc writeCbor*[T: object](str: Stream, v: T): ?!void =
|
||||||
var n: uint
|
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:
|
for _, _ in v.fieldPairs:
|
||||||
inc n
|
inc n
|
||||||
?str.writeInitial(5, n)
|
?str.writeInitial(5, n)
|
||||||
|
|
||||||
for k, f in v.fieldPairs:
|
for k, f in v.fieldPairs:
|
||||||
|
assertNoPragma(f, serialize, "serialize pragma not supported")
|
||||||
?str.writeCbor(k)
|
?str.writeCbor(k)
|
||||||
?str.writeCbor(f)
|
?str.writeCbor(f)
|
||||||
success()
|
success()
|
||||||
|
|||||||
@ -43,9 +43,6 @@ type
|
|||||||
NewType = ref object
|
NewType = ref object
|
||||||
size: uint64
|
size: uint64
|
||||||
|
|
||||||
# Reference type for Inner object
|
|
||||||
InnerRef = ref Inner
|
|
||||||
|
|
||||||
# Complex object with various field types to test comprehensive serialization
|
# Complex object with various field types to test comprehensive serialization
|
||||||
CompositeNested = object
|
CompositeNested = object
|
||||||
u: uint64 # Unsigned integer
|
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