Commits

Shlomi Fish  committed 000146c Merge
  • Participants
  • Parent commits 897aa5d, f0c0e13

Comments (0)

Files changed (3)

 Revision history for Perl extension XML::LibXML
 
+2.0115  2014-04-03
+    - Fix double free when calling $node->addSibling with text nodes.
+          - https://rt.cpan.org/Ticket/Display.html?id=94149
+          - Thanks to Jeff Trout for the report.
+
 2.0114  2014-04-03
     - Fix memory leaks and segfaults related to removal and insertion of
       DTD nodes.
         }
         owner = PmmOWNERPO(PmmPROXYNODE(self));
 
-        ret = xmlAddSibling( self, nNode );
-
-        if ( ret ) {
-            RETVAL = PmmNodeToSv(ret,NULL);
-            if (nNode->type == XML_DTD_NODE) {
-                LibXML_set_int_subset(self->doc, nNode);
-            }
-            PmmFixOwner(SvPROXYNODE(RETVAL), owner);
+        if (self->type == XML_TEXT_NODE && nNode->type == XML_TEXT_NODE
+            && self->name == nNode->name) {
+            /* As a result of text merging, the added node may be freed. */
+            xmlNodePtr copy = xmlCopyNode(nNode, 0);
+            ret = xmlAddSibling(self, copy);
+
+            if (ret) {
+                RETVAL = PmmNodeToSv(ret, owner);
+                /* Unlink original node. */
+                xmlUnlinkNode(nNode);
+                LibXML_reparent_removed_node(nNode);
+            }
+            else {
+                xmlFreeNode(copy);
+                XSRETURN_UNDEF;
+            }
         }
         else {
-            XSRETURN_UNDEF;
+            ret = xmlAddSibling( self, nNode );
+
+            if ( ret ) {
+                RETVAL = PmmNodeToSv(ret, owner);
+                if (nNode->type == XML_DTD_NODE) {
+                    LibXML_set_int_subset(self->doc, nNode);
+                }
+                PmmFixOwner(SvPROXYNODE(RETVAL), owner);
+            }
+            else {
+                XSRETURN_UNDEF;
+            }
         }
     OUTPUT:
         RETVAL
 # since all tests are run on a preparsed
 
 # Should be 166.
-use Test::More tests => 194;
+use Test::More tests => 195;
 
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
     }
 }
 
+{
+    # RT #94149
+    # https://rt.cpan.org/Ticket/Display.html?id=94149
+
+    my $orig = XML::LibXML::Text->new('Double ');
+    my $ret = $orig->addSibling(XML::LibXML::Text->new('Free'));
+    # TEST
+    is( $ret->textContent, 'Double Free', 'merge text nodes with addSibling' );
+}
+