[libxml2/fix-ownership-of-xmlAttrPtr-name-in-xmlSetTreeDoc] Fix ownership of xmlAttrPtr->name in xmlSetTreeDoc()
- From: David Kilzer <ddkilzer src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml2/fix-ownership-of-xmlAttrPtr-name-in-xmlSetTreeDoc] Fix ownership of xmlAttrPtr->name in xmlSetTreeDoc()
- Date: Tue, 17 May 2022 21:28:29 +0000 (UTC)
commit 4147bf386fd5eecd0413a6b655ce496403b30282
Author: David Kilzer <ddkilzer apple com>
Date: Sat Mar 19 17:17:40 2022 -0700
Fix ownership of xmlAttrPtr->name in xmlSetTreeDoc()
When changing `doc` on an xmlAttrPtr, the `name` field must
either be a free-standing string, or it must be owned by
`doc->dict` for the xmlAttrPtr. The code to make this change
was simply missing from xmlSetTreeDoc(), 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.
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
- Get string from new dictionary pool & free old copy.
4. Not owned by old dictionary -> NULL new dictionary
- No action necessary (already a free-standing string).
Found by OSS-Fuzz Issue 45132.
tree.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
---
diff --git a/tree.c b/tree.c
index 689a6b66..12aa2e9a 100644
--- a/tree.c
+++ b/tree.c
@@ -2833,7 +2833,19 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
xmlRemoveID(tree->doc, prop);
}
- prop->doc = doc;
+ if (prop->doc != doc) {
+ /* Update ownership of prop->name if prop->doc changes. */
+ int oldPropDictOwnsName = (prop->doc != NULL) && (xmlDictOwns(prop->doc->dict,
prop->name) == 1);
+ const xmlChar *oldName = prop->name;
+ if ((doc != NULL) && (doc->dict != NULL)) {
+ prop->name = xmlDictLookup(doc->dict, oldName, -1);
+ if (!oldPropDictOwnsName)
+ xmlFree((void *)oldName);
+ } else if (oldPropDictOwnsName)
+ prop->name = xmlStrdup(oldName);
+
+ prop->doc = doc;
+ }
xmlSetListDoc(prop->children, doc);
/*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]