mirror of
https://github.com/zeux/pugixml.git
synced 2025-01-14 01:47:55 +08:00
Adjust node_copy_tree to be more explicit about invariants
The loop traverses the source tree and simultaneously builds up a copy of it at destination. Short of race conditions, this code is safe - however, it's not obvious that dit stays inside the destination tree. This change adds a few assertions to help enforce/document these invariants. One particular subtlety is that dit can actually *become* null after we exit out of the loop, but it's guaranteed to only do so once sit goes back to sn. This is only possible when doing a full document copy - for some reason we weren't using this for that (in reset(xml_document)), but we are now. Fixes #314.
This commit is contained in:
parent
76c3914484
commit
5e64076af9
@ -4435,6 +4435,9 @@ PUGI__NS_BEGIN
|
|||||||
|
|
||||||
while (sit && sit != sn)
|
while (sit && sit != sn)
|
||||||
{
|
{
|
||||||
|
// loop invariant: dit is inside the subtree rooted at dn
|
||||||
|
assert(dit);
|
||||||
|
|
||||||
// when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop
|
// when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop
|
||||||
if (sit != dn)
|
if (sit != dn)
|
||||||
{
|
{
|
||||||
@ -4464,9 +4467,14 @@ PUGI__NS_BEGIN
|
|||||||
|
|
||||||
sit = sit->parent;
|
sit = sit->parent;
|
||||||
dit = dit->parent;
|
dit = dit->parent;
|
||||||
|
|
||||||
|
// loop invariant: dit is inside the subtree rooted at dn while sit is inside sn
|
||||||
|
assert(sit == sn || dit);
|
||||||
}
|
}
|
||||||
while (sit != sn);
|
while (sit != sn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(!sit || dit == dn->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa)
|
PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa)
|
||||||
@ -6949,8 +6957,7 @@ namespace pugi
|
|||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling())
|
impl::node_copy_tree(_root, proto._root);
|
||||||
append_copy(cur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN void xml_document::_create()
|
PUGI__FN void xml_document::_create()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user