Skip Menu |

This queue is for tickets about the XML-LibXML CPAN distribution.

Report information
The Basics
Id: 80395
Status: resolved
Priority: 0/
Queue: XML-LibXML

People
Owner: Nobody in particular
Requestors: GUIDO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.90
  • 1.91
  • 1.92
  • 1.93
  • 1.94
  • 1.95
  • 1.96
  • 1.97
  • 1.98
  • 1.99
  • 2.0000
  • 2.0001
  • 2.0002
  • 2.0003
  • 2.0004
  • 2.0005
  • 2.0006
  • 2.0007
  • 2.0008
Fixed in: (no value)



Subject: removeChild() segfaults when not expanding entities
# This script segfaults: use strict; use XML::LibXML; my $xml = <<EOF; <!DOCTYPE bug [ <!ENTITY myent "xyz"> ]> <bug> <elem>&myent;</elem> </bug> EOF my $dom = XML::LibXML->load_xml (string => $xml, expand_entities => 0); my $root = $dom->documentElement; my @nodes = $root->childNodes; foreach my $node (@nodes) { next if $node->nodeType != XML_ELEMENT_NODE; next if $node->nodeName ne 'elem'; $root->removeChild ($node); } __END__ The script doesn't crash if you do one of the following: - set expand_entities to 1 - do not use the entity &myent; - instead of &myent; use &amp; (or &lt;, &gt; ...) In dom.c, at one point the function _domReconileNS() gets called with a tree argument where tree->ns is not NULL but tree->ns->prefix is either NULL or points to lala-land. In the above script, the pointer is NULL. But with a more complicated XML document, tree->ns->prefix pointed to an address beyond the end of the virtual RAM. That means that it is not sufficient to extend the check to if (tree->ns != NULL && tree->ns->prefix != NULL) That just fixes the test case but the crash still happens with my "real" data. The bug occurred on Gentoo x86_64 with version 1.9000 but also with version 2.0008.
Hi GUIDO, On Thu Oct 25 12:46:36 2012, GUIDO wrote: Show quoted text
> # This script segfaults: > > use strict; > > use XML::LibXML; > > my $xml = <<EOF; > <!DOCTYPE bug [ > <!ENTITY myent "xyz"> > ]> > <bug> > <elem>&myent;</elem> > </bug> > EOF > > my $dom = XML::LibXML->load_xml (string => $xml, > expand_entities => 0); > my $root = $dom->documentElement; > > my @nodes = $root->childNodes; > foreach my $node (@nodes) { > next if $node->nodeType != XML_ELEMENT_NODE; > next if $node->nodeName ne 'elem'; > > $root->removeChild ($node); > } > __END__ > > The script doesn't crash if you do one of the following: > > - set expand_entities to 1 > - do not use the entity &myent; > - instead of &myent; use &amp; (or &lt;, &gt; ...) >
I can reproduce it here. Show quoted text
> In dom.c, at one point the function _domReconileNS() gets called with a > tree argument where tree->ns is not NULL but tree->ns->prefix is either > NULL or points to lala-land.
Why is this the case? Do you know whether it's a bug in XML::LibXML or in libxml2? Show quoted text
> > In the above script, the pointer is NULL. But with a more complicated > XML document, tree->ns->prefix pointed to an address beyond the end of > the virtual RAM. That means that it is not sufficient to extend the > check to > > if (tree->ns != NULL && tree->ns->prefix != NULL) > > That just fixes the test case but the crash still happens with my "real" > data.
Doing this both neither fixes the test case, and also introduces a regression in a previous test in the test suite: t/10ns.t (Wstat: 256 Tests: 129 Failed: 1) Failed test: 110 Non-zero exit status: 1 Show quoted text
> > The bug occurred on Gentoo x86_64 with version 1.9000 but also with > version 2.0008.
OK. Regards, -- Shlomi Fish
Hi Shlomi, thanks for the quick reaction. On Sat Oct 27 06:59:25 2012, SHLOMIF wrote: Show quoted text
> Hi GUIDO, > > On Thu Oct 25 12:46:36 2012, GUIDO wrote:
> > In dom.c, at one point the function _domReconileNS() gets called with a > > tree argument where tree->ns is not NULL but tree->ns->prefix is either > > NULL or points to lala-land.
> > Why is this the case? Do you know whether it's a bug in XML::LibXML or > in libxml2?
Hard to say, when removeChild() is not present in libxml2. But it's definetely one that has to be debugged in XML::LibXML first. Even if it is a bug in libxml2, we still don't know which usage in XML::LibXML causes it. Regards, Guido
The problem is that _domReconcileNs() unreferences the ns member of xmlNodePtr for all node types it encounters but it is only valid for element and attribute nodes. The attached patch fixes that. All tests succeded here with the patch applied.
Subject: xml-libxml-reconcile-ns.patch
diff -ur XML-LibXML-2.0008.orig/dom.c XML-LibXML-2.0008.gfl/dom.c --- XML-LibXML-2.0008.orig/dom.c 2012-08-09 10:43:13.000000000 +0300 +++ XML-LibXML-2.0008.gfl/dom.c 2012-10-29 16:55:04.000000000 +0200 @@ -172,7 +172,9 @@ void _domReconcileNs(xmlNodePtr tree, xmlNsPtr * unused) { - if( tree->ns != NULL ) + if( tree->ns != NULL + && (tree->type == XML_ELEMENT_NODE + || tree->type == XML_ATTRIBUTE_NODE)) { xmlNsPtr ns = xmlSearchNs( tree->doc, tree->parent, tree->ns->prefix ); if( ns != NULL && ns->href != NULL && tree->ns->href != NULL &&
Hi, sorry for the late response - I was preoccupied with other things. I have applied a variation of your patch now in the Mercurial repository, and it will be part of a new release (with a test). I'll make the new release - XML-LibXML-2.0011 (or maybe XML-LibXML-2.0100) once I have looked at this bug report: https://rt.cpan.org/Ticket/Display.html?id=80521 Regards, -- Shlomi Fish
On Wed Nov 07 16:11:43 2012, SHLOMIF wrote: Show quoted text
> Hi, > > sorry for the late response - I was preoccupied with other things. I > have applied a variation of your patch now in the Mercurial repository, > and it will be part of a new release (with a test). I'll make the new > release - XML-LibXML-2.0011 (or maybe XML-LibXML-2.0100) once I have > looked at this bug report: > > https://rt.cpan.org/Ticket/Display.html?id=80521 > > Regards, > > -- Shlomi Fish
Fixed in 2.0011, which was uploaded to CPAN. Thanks!