Commits

pa...@9ae0c189-cd1f-4510-a509-f4891f5cf20d  committed 1fcb906

fix possible SIGSEGV when PI's or attrs created with
createDocument can get garbage-collected after their owning
document (old-standing bug suddenly caught by XML::Compile regression tests)

  • Participants
  • Parent commits 736effc

Comments (0)

Files changed (3)

 Revision history for Perl extension XML::LibXML
 1.65pre
    - fix bug in t/40reader.t revealed by a bugfix in Test::More 0.71 (Jonathan Rockway)
+   - fix possible SIGSEGV when PI's or attrs created with
+     createDocument can get garbage-collected after their owning
+     document (old-standing bug suddenly caught by XML::Compile regression tests)
 
 1.64
    - fix reconcilation of the "xml" namespace [rt.cpan.org #26450] 
 
         value = nodeSv2C( pvalue , (xmlNodePtr) self );
         newAttr = xmlNewDocProp( self, name, value );
-        RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, NULL);
+        RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, PmmPROXYNODE(self));
 
         xmlFree(name);
         if ( value ) {
                 newAttr = xmlNewDocProp( self, localname, value );
                 xmlSetNs((xmlNodePtr)newAttr, ns);
 
-                RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, NULL );
+                RETVAL = PmmNodeToSv((xmlNodePtr)newAttr, PmmPROXYNODE(self) );
 
                 xmlFree(nsURI);
                 xmlFree(name);
         }
         else {
             newAttr = xmlNewDocProp( self, name, value );
-            RETVAL = PmmNodeToSv((xmlNodePtr)newAttr,NULL);
+            RETVAL = PmmNodeToSv((xmlNodePtr)newAttr,PmmPROXYNODE(self));
             xmlFree(name);
             if ( value ) {
                 xmlFree(value);
     PREINIT:
         xmlChar * n = NULL;
         xmlChar * v = NULL;
-        xmlNodePtr pinode = NULL;
+        xmlNodePtr newNode = NULL;
+        ProxyNodePtr docfrag = NULL;
     CODE:
         n = nodeSv2C(name, (xmlNodePtr)self);
         if ( !n ) {
             XSRETURN_UNDEF;
         }
         v = nodeSv2C(value, (xmlNodePtr)self);
-        pinode = xmlNewPI(n,v);
-        pinode->doc = self;
-
-        RETVAL = PmmNodeToSv(pinode,NULL);
-
+        newNode = xmlNewPI(n,v);
         xmlFree(v);
         xmlFree(n);
-    OUTPUT:
-        RETVAL
-
-
+	if ( newNode != NULL ) {
+ 	   docfrag = PmmNewFragment( self );
+           newNode->doc = self;
+	   xmlAddChild(PmmNODE(docfrag), newNode);
+	   RETVAL = PmmNodeToSv(newNode,docfrag);
+	} else {
+ 	   xs_warn( "no node created!" );
+ 	   XSRETURN_UNDEF;
+        }
+    OUTPUT:
+        RETVAL
 
 void
 _setDocumentElement( self , proxy )
 use Test;
 use strict;
 
-BEGIN { plan tests => 131 };
+BEGIN { plan tests => 135 };
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
 
 }
 
 {
-    print "# 4. Document Storeing\n";
+    print "# 4. Document Storing\n";
     my $parser = XML::LibXML->new;
     my $doc = $parser->parse_string("<foo>bar</foo>");  
 
         }
     }
 }
+{
+    print "# 5. Bug fixes (to be use with valgrind)\n";
+    {  
+       my $doc=XML::LibXML->createDocument(); # create a doc
+       my $x=$doc->createPI(foo=>"bar");      # create a PI
+       undef $doc;                            # should not free
+       undef $x;                              # free the PI
+       ok(1);
+    }
+    {  
+       my $doc=XML::LibXML->createDocument(); # create a doc
+       my $x=$doc->createAttribute(foo=>"bar"); # create an attribute
+       undef $doc;                            # should not free
+       undef $x;                              # free the attribute
+       ok(1);
+    }
+    {  
+       my $doc=XML::LibXML->createDocument(); # create a doc
+       my $x=$doc->createAttributeNS(undef,foo=>"bar"); # create an attribute
+       undef $doc;                            # should not free
+       undef $x;                              # free the attribute
+       ok(1);
+    }
+    {  
+       my $doc=XML::LibXML->new->parse_string('<foo xmlns:x="http://foo.bar"/>');
+       my $x=$doc->createAttributeNS('http://foo.bar','x:foo'=>"bar"); # create an attribute
+       undef $doc;                            # should not free
+       undef $x;                              # free the attribute
+       ok(1);
+    }
+
+}