Commit ef241a8
committed
XML: mutate XML nodes in place
Previously, text and structural mutators copied and replaced the receiver's
libxml2 node. Existing XMLNode wrappers continued to point at the detached
original, while subsequent lookups returned the replacement. Wrappers for
children preserved by the operation likewise pointed into the detached old
subtree. In QuickJS, mutating the detached receiver again could dereference
the NULL result of xmlReplaceNode().
The fix is to modify the existing receiver's child list directly. Existing
wrappers and subsequent lookups therefore continue to refer to the same
libxml2 node. Removed child lists remain readable until the QuickJS
document or njs VM is destroyed. A node is considered live only when
following its parent links reaches its xmlDoc. Replacement children and
cleanup records are prepared before the live tree is modified.
Changed behaviour:
- A removed child has an undefined $parent, while its descendants retain
their internal parent links.
- Mutating or canonicalizing a removed XMLNode throws TypeError.
- Text and attribute values must be primitive strings; null and undefined
retain their deletion semantics.
- C14N rejects an excluding node from another document or a detached list.
- addChild() and $tags reject namespace-bearing or unsupported source trees
before mutation.
- Named $tags assignments are consistently rejected by both engines.
While here, use an unsigned QuickJS $tags array length, support assigning
$tags on an empty njs XMLNode, and make deleting $tags from an empty node
a no-op.1 parent 130a5d5 commit ef241a8
3 files changed
Lines changed: 933 additions & 295 deletions
0 commit comments