Commits

Anonymous committed 77f9672

Modified Files:
LibXML.xs
+ improved namespace handling - missing prefix will not cause
errors anymore
[fix] memory leak i introduced with Xpath error reporting

Changes
+ version notes

t/03doc.t
+ createElementNS segfault test

Comments (0)

Files changed (3)

      (very special thanks to andreas koenig for the patch)
    - fixed findnodes() and find() to return empty arrays in array context
      if the statement was legal but produced no result.
+   - fixed local namespace handling in DOM functions
    - pretty formating to all serializing functions
      *NOTE* the XML::LibXML::Node::toString interface changed
      check the XML::LibXML::Node man page 
         SV * nsURI
         SV * name
     PREINIT:
-        xmlChar * ename;
-        xmlChar * prefix;
-        xmlChar * localname;
-        xmlChar * eURI;
-        xmlNsPtr ns = NULL;
-        xmlDocPtr doc;
-        ProxyNodePtr docfrag = NULL;
-        xmlNodePtr newNode = NULL;
+        xmlChar * ename        = NULL;
+        xmlChar * prefix       = NULL;
+        xmlChar * localname    = NULL;
+        xmlChar * eURI         = NULL;
+        const xmlChar * pchar  = NULL;
+        xmlNsPtr ns            = NULL;
+        xmlDocPtr doc          = NULL;
+        ProxyNodePtr docfrag   = NULL;
+        xmlNodePtr newNode     = NULL;
     CODE:
         doc = (xmlDocPtr)PmmSvNode( pdoc );
         ename = nodeSv2C( name , (xmlNodePtr) doc );
         eURI  = Sv2C( nsURI , NULL );
 
         if ( eURI != NULL && xmlStrlen(eURI)!=0 ){
-            localname = xmlSplitQName2(ename, &prefix);
+            pchar = xmlStrchr( ename, ':' );
+            if ( pchar != NULL ) {
+                localname = xmlSplitQName2(ename, &prefix);
+            }
+            else {
+                localname = xmlStrdup( ename );
+            }
 
             newNode = xmlNewNode( NULL , localname );
             newNode->doc = doc;
                 xmlFreeNode( newNode );
                 xmlFree(eURI);
                 xmlFree(localname);
-                xmlFree(prefix);
+                if ( prefix != NULL ) {
+                    xmlFree(prefix);
+                }
                 xmlFree(ename);
                 XSRETURN_UNDEF;
             }
         xmlChar * name = NULL;
         xmlChar * value = NULL;
         xmlChar * prefix = NULL;
+        const xmlChar * pchar = NULL;
         xmlChar * localname = NULL;
         xmlChar * nsURI = NULL;
         xmlAttrPtr self = NULL;
         if ( nsURI ) {
             xmlNodePtr root = xmlDocGetRootElement( doc );
             if ( root ) {
-                localname = xmlSplitQName2(name, &prefix);
+                pchar = xmlStrchr(name, ':');
+                if ( pchar != NULL ) {
+                    localname = xmlSplitQName2(name, &prefix);
+                }
+                else {
+                    localname = xmlStrdup( name );
+                }
                 ns = xmlSearchNsByHref( doc, root, nsURI );
                 if ( ns == NULL ) {
                     /* create a new NS if the NS does not already exists */
                 if ( ns == NULL ) { 
                     xmlFree(nsURI);
                     xmlFree(localname);
-                    xmlFree(prefix);
+                    if ( prefix ) {
+                        xmlFree(prefix);
+                    }
                     xmlFree(name);
                     xmlFree(value);
                     XSRETURN_UNDEF;
                 RETVAL = PmmNodeToSv((xmlNodePtr)self, NULL );
                 xmlFree(nsURI);
                 xmlFree(name);
-                xmlFree(prefix);
+                if ( prefix ) {
+                    xmlFree(prefix);
+                }
                 xmlFree(localname);
                 xmlFree(value);
             }   
         xmlFree( xpath );
 
         xmlSetGenericErrorFunc(NULL, NULL);
+        
+        sv_2mortal( LibXML_error );
 
         if ( SvCUR( LibXML_error ) > 0 ) {
             croak(SvPV(LibXML_error, len));
         nodelist = domXPathSelect( node, xpath );
         xmlFree(xpath);
         xmlSetGenericErrorFunc(NULL, NULL);
+
+        sv_2mortal( LibXML_error );
+
         if ( SvCUR( LibXML_error ) > 0 ) {
             croak(SvPV(LibXML_error, len));
         }
         xmlChar * nsURI = nodeSv2C( namespaceURI, node );
         xmlChar * name  = NULL;
         xmlChar * value = NULL;
+        const xmlChar * pchar = NULL;
         xmlNsPtr ns;
     CODE:
         if ( nsURI && xmlStrlen(nsURI) ) {
             ns = xmlSearchNsByHref( node->doc, node, nsURI );
             if ( !ns ) {
                 /* create new ns */
-                xmlChar * localname;
-                xmlChar * prefix;
+                xmlChar * localname = NULL;
+                xmlChar * prefix = NULL;
 
                 name  = nodeSv2C( attr_name, node );
                 if ( ! name ) {
                     xmlFree(nsURI);
                     XSRETURN_UNDEF;
                 }
-                localname = xmlSplitQName2(name, &prefix); 
+
+                pchar = xmlStrchr(name, ':');
+                if ( pchar ) {
+                    localname = xmlSplitQName2(name, &prefix); 
+                }
+                else {
+                    localname = xmlStrdup( name );
+                }
             
                 xmlFree( name );
                 name = localname;
             
                 ns = xmlNewNs(node, nsURI , prefix );
-                xmlFree( prefix );
+                if ( prefix ) {
+                    xmlFree( prefix );
+                }
             }
             else {
-                xmlChar * localname;
-                xmlChar * prefix;
+                xmlChar * localname = NULL;
+                xmlChar * prefix = NULL;
 
                 name  = nodeSv2C( attr_name, node );
                 if (!name) {
                     xmlFree(nsURI);
                     XSRETURN_UNDEF;
                 }
-                localname = xmlSplitQName2(name, &prefix); 
-                xmlFree(prefix);
+
+                pchar = xmlStrchr(name, ':');
+                if ( pchar ) {
+                    localname = xmlSplitQName2(name, &prefix); 
+                }
+                else {
+                    localname = xmlStrdup( name );
+                }
+
+                if ( prefix ) {
+                    xmlFree(prefix);
+                }
                 xmlFree(name);
                 name = localname;
             }
 use Test;
 use strict;
 
-BEGIN { plan tests => 62 };
+BEGIN { plan tests => 63 };
 use XML::LibXML;
 
 {
     ok( scalar(@cn) , 1);
     ok($cn[0]->isSameNode($node2));
 
+    my $node3 = $doc->createElementNS( "http://foo", "bar" );
+    ok($node3);
+
     print "# 3.2 Processing Instructions\n"; 
     {
         my $pi = $doc->createProcessingInstruction( "foo", "bar" );