Skip to content

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:

  1. Owned by old dictionary -> NULL new dictionary
    • Create free-standing copy of string.
  2. Owned by old dictionary -> Non-NULL new dictionary
    • Get string from new dictionary pool.
  3. Not owned by old dictionary -> Non-NULL new dictionary
    • No action necessary (already a free-standing string).
  4. 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

Merge request reports