Skip to content

Commit

Permalink
Fix leaks of libxml2 detached nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
rfm committed Jan 10, 2025
1 parent 496d06f commit 6156b61
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
28 changes: 27 additions & 1 deletion Source/Additions/GSXML.m
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ - (id) _initFrom: (void*)data parent: (id)p;

@interface GSXMLNode (GSPrivate)
- (id) _initFrom: (void*)data parent: (id)p;
- (void) _setOwnsLib: (BOOL)f;
@end

@interface GSXMLParser (Private)
Expand Down Expand Up @@ -500,6 +501,7 @@ - (GSXMLNode*) makeNodeWithNamespace: (GSXMLNamespace*)ns
n = [n _initFrom:
xmlNewDocNode(lib, [ns lib], UTF8STRING(name), UTF8STRING(content))
parent: self];
[n _setOwnsLib: YES]; // Not part of document yet
return AUTORELEASE(n);
}

Expand All @@ -523,6 +525,7 @@ - (GSXMLNode*) setRoot: (GSXMLNode*)node
{
xmlNodePtr nodeLib = (xmlNodePtr)[node lib];
xmlNodePtr selfLib = (xmlNodePtr)[self lib];
xmlNodePtr old;

if (node == nil)
{
Expand All @@ -534,7 +537,20 @@ - (GSXMLNode*) setRoot: (GSXMLNode*)node
[NSException raise: NSInvalidArgumentException
format: @"Attempt to set root to node from other document"];
}
xmlDocSetRootElement(lib, nodeLib);
old = xmlDocSetRootElement(lib, nodeLib);
[node _setOwnsLib: NO];
if (old)
{
/* The old root is detached from the document and can no longer be used.
*/
if (old->_private != 0)
{
GSXMLDocument *owner = (GSXMLDocument*)old->_private;

owner->lib = 0;
}
xmlFreeNode(old);
}
return node;
}

Expand Down Expand Up @@ -595,6 +611,7 @@ - (id) _initFrom: (void*)data parent: (id)p ownsLib: (BOOL)f
}
lib = data;
_ownsLib = f;
((xmlNodePtr)(lib))->_private = self;
ASSIGN(_parent, p);
return self;
}
Expand Down Expand Up @@ -992,6 +1009,11 @@ - (NSString*) content
- (void) dealloc
{
RELEASE(_parent);
if (lib && _ownsLib)
{
xmlFreeNode(lib);
lib = 0;
}
[super dealloc];
}

Expand Down Expand Up @@ -1653,6 +1675,10 @@ - (id) _initFrom: (void*)data parent: (id)p
ASSIGN(_parent, p);
return self;
}
- (void) _setOwnsLib: (BOOL)f
{
_ownsLib = f;
}
@end

/**
Expand Down
2 changes: 1 addition & 1 deletion Tests/base/GSXML/basic.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int main()
[doc setRoot: node];
PASS([[doc root] isEqual: node],"Can set document node as root node");

[doc makeNodeWithNamespace: nil name: @"nicola" content: nil];
node = [doc makeNodeWithNamespace: nil name: @"nicola" content: nil];
[node makeChildWithNamespace: nil
name: @"paragraph"
content: @"Hi this is some text"];
Expand Down

0 comments on commit 6156b61

Please sign in to comment.