Fix ownership of xmlNodePtr & xmlAttrPtr fields in xmlSetTreeDoc()
When changing doc
on an xmlNodePtr or xmlAttrPtr, certain
fields must either be a free-standing string, or they must be
owned by doc->dict
.
The code to make this change was simply missing, so the crash
happened when an xmlAttrPtr was being torn down after doc
changed from non-NULL to NULL, but the name
field was not
copied. This is scenario 1 below.
The xmlNodePtr->name and xmlNodePtr->content fields are also
fixed at the same time. Note that xmlNodePtr->content is never
added to the dictionary, so NULL is used instead of newDict
to
force a free-standing copy.
This change covers all cases of dictionary changes:
- Owned by old dictionary -> NULL new dictionary
- Create free-standing copy of string.
- Owned by old dictionary -> Non-NULL new dictionary
- Get string from new dictionary pool.
- Not owned by old dictionary -> Non-NULL new dictionary
- No action necessary (already a free-standing string).
- Not owned by old dictionary -> NULL new dictionary
- No action necessary (already a free-standing string).
- tree.c: (_copyStringForNewDictIfNeeded): Add. (xmlSetTreeDoc):
- Update xmlNodePtr->name, xmlNodePtr->content and xmlAttrPtr->name when changing the document, if needed.
Found by OSS-Fuzz Issue 45132.
Edited by David Kilzer