mirror of https://github.com/status-im/NimYAML.git
made anchor resolution during deserialization safer
This commit is contained in:
parent
aa65c066d5
commit
4305bccbf0
|
@ -211,7 +211,7 @@ suite "Lexer":
|
|||
pl("bar baz"), dirE(), i(0), pl("derp"), e())
|
||||
|
||||
test "Sequence with compact maps":
|
||||
assertEquals("""- a: drzw\n- b""", i(0), ss(), pl("a"), mv(), pl("drzw"), i(0), ss(), pl("b"), e())
|
||||
assertEquals("- a: drzw\n- b", i(0), si(), pl("a"), mv(), pl("drzw"), i(0), si(), pl("b"), e())
|
||||
|
||||
test "Empty lines":
|
||||
assertEquals("""block: foo
|
||||
|
|
|
@ -271,15 +271,4 @@ proc `$`*(event: Event): string {.raises: [].} =
|
|||
of ssLiteral: result &= " |"
|
||||
of ssFolded: result &= " >"
|
||||
result &= yamlTestSuiteEscape(event.scalarContent)
|
||||
of yamlAlias: result = "=ALI *" & $event.aliasTarget
|
||||
|
||||
type
|
||||
TypeID* = int ## unique ID of a type
|
||||
|
||||
var nextTypeID {.compileTime.}: TypeID
|
||||
|
||||
proc typeID*(T:typedesc): TypeID =
|
||||
const id = nextTypeID
|
||||
static:
|
||||
inc nextTypeID
|
||||
return id
|
||||
of yamlAlias: result = "=ALI *" & $event.aliasTarget
|
|
@ -138,7 +138,7 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
|||
template addAnchor(c: ConstructionContext, target: Anchor) =
|
||||
if target != yAnchorNone:
|
||||
yAssert(not c.refs.hasKey(target))
|
||||
c.refs[target] = (id: typeID(YamlNode), p: cast[pointer](result))
|
||||
c.refs[target] = (tag: yamlTag(YamlNode), p: cast[pointer](result))
|
||||
|
||||
var start: Event
|
||||
shallowCopy(start, s.next())
|
||||
|
|
|
@ -32,7 +32,7 @@ type
|
|||
|
||||
ConstructionContext* = ref object
|
||||
## Context information for the process of constructing Nim values from YAML.
|
||||
refs*: Table[Anchor, tuple[id: TypeID, p: pointer]]
|
||||
refs*: Table[Anchor, tuple[tag: Tag, p: pointer]]
|
||||
|
||||
YamlConstructionError* = object of YamlLoadingError
|
||||
## Exception that may be raised when constructing data objects from a
|
||||
|
@ -86,7 +86,7 @@ proc representChild*[O](value: O, ts: TagStyle, c: SerializationContext)
|
|||
|
||||
proc newConstructionContext*(): ConstructionContext =
|
||||
new(result)
|
||||
result.refs = initTable[Anchor, tuple[id: TypeID, p: pointer]]()
|
||||
result.refs = initTable[Anchor, tuple[tag: Tag, p: pointer]]()
|
||||
|
||||
proc newSerializationContext*(s: AnchorStyle,
|
||||
putImpl: proc(e: Event) {.raises: [], closure.}):
|
||||
|
@ -1223,14 +1223,18 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
|||
discard s.next()
|
||||
return
|
||||
elif e.kind == yamlAlias:
|
||||
result = cast[ref O](c.refs.getOrDefault(e.aliasTarget).p)
|
||||
let val = c.refs.getOrDefault(e.aliasTarget)
|
||||
if val.tag != yamlTag(O):
|
||||
raise constructionError(s, e.startPos,
|
||||
"alias node refers to object of incompatible type")
|
||||
result = cast[ref O](val.p)
|
||||
discard s.next()
|
||||
return
|
||||
new(result)
|
||||
template removeAnchor(anchor: var Anchor) {.dirty.} =
|
||||
if anchor != yAnchorNone:
|
||||
yAssert(not c.refs.hasKey(anchor))
|
||||
c.refs[anchor] = (0, cast[pointer](result))
|
||||
c.refs[anchor] = (yamlTag(O), cast[pointer](result))
|
||||
anchor = yAnchorNone
|
||||
|
||||
case e.kind
|
||||
|
|
Loading…
Reference in New Issue