mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 22:21:59 +00:00
The namespace list that inScopeNamespaces(), namespace(), namespaceDeclarations(), the XPath namespace axis, XPath prefixes and XPath name() collect from a node and its ancestors was built in Rust buffers the heap limit did not see, so a node with many namespaces in scope let a script grow past its limit. The scope now holds the bytes of its list and prefix table until it is dropped, and namespaceDeclarations() also holds its ancestor table and the declarations it returns. The queried node stays rooted while the scope is built, and each declaration is read in place instead of copying every node's namespace list. Other copies in the same files are held against the limit too: - addNamespace(), setNamespace(), setName() and removeNamespace() read an element's attributes one at a time instead of copying the list, and removeNamespace() holds its walk stack. - child(index), comments(), text(), elements(), processingInstructions() and normalize() on an XMLList hold the copy of its items, and replace() holds the copy of the children it matched. - XPath name() holds the units of a prefixed name it builds. - The XML, XMLList, Namespace and QName constructors, isXMLName(), attribute(), namespace(), propertyIsEnumerable(), setName(), setLocalName(), addNamespace(), removeNamespace() and setNamespace() reserve the bytes of the flat copy of a long (rope) string argument before they make it, and attribute() reserves the copy of a name without its leading @. - QName.prototype.toString() reserves its result before it builds it.