After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 512131 - crash in libxml2 xmlReader with RNG validation
crash in libxml2 xmlReader with RNG validation
Status: RESOLVED FIXED
Product: libxml2
Classification: Platform
Component: relaxng
2.6.30
Other All
: Normal critical
: ---
Assigned To: Daniel Veillard
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2008-01-25 20:54 UTC by Petr Pajas
Modified: 2017-06-12 19:06 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Petr Pajas 2008-01-25 20:54:51 UTC
Steps to reproduce:
1. wget http://ufal.mff.cuni.cz/~pajas/bug.zip
2. unzip bug.zip
3. # examine the files (test*.{xml,rng} and bug.sh)
4. sh bug.sh  # to see the segfault
 
Briefly: there are 3 Relax NG schemas that refer to each other in the following way: test.rng -> test2.rng -> test3.rng. Validation with 

xmllint --stream --relaxng test.rng test.xml 

causes a segmentation fault and the valgrind report below. The samples schemas and a test file are as small as I could manage (two elements and one attribute in the test.xml). It seems however important that the validator backtracks during the validation. Make a slight modification to the schemas (e.g. swap two elements in a <group>) and all goes well. I also copy/paste the four files below.

My system is SuSE 10.3 64bit, libxml2 2.6.30 from RPM, running on a notebook with x86_64 architecture (Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz).

Stack trace:
xmllint: using libxml version 20630
   compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib 
==16990== Memcheck, a memory error detector.
==16990== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==16990== Using LibVEX rev 1732, a library for dynamic binary translation.
==16990== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==16990== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==16990== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==16990== For more details, rerun with: -v
==16990== 
test.xml validates
==16990== Invalid read of size 8
==16990==    at 0x559CDC0: (within /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x559D7AA: xmlRelaxNGFreeValidCtxt (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x55996EE: xmlFreeTextReader (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x405C0C: (within /usr/bin/xmllint)
==16990==    by 0x409128: (within /usr/bin/xmllint)
==16990==    by 0x5E8CB53: (below main) (in /lib64/libc-2.6.1.so)
==16990==  Address 0x40800D0 is 48 bytes inside a block of size 56 free'd
==16990==    at 0x4C2191B: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==16990==    by 0x559D7AA: xmlRelaxNGFreeValidCtxt (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x55996EE: xmlFreeTextReader (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x405C0C: (within /usr/bin/xmllint)
==16990==    by 0x409128: (within /usr/bin/xmllint)
==16990==    by 0x5E8CB53: (below main) (in /lib64/libc-2.6.1.so)
==16990== 
==16990== Invalid free() / delete / delete[]
==16990==    at 0x4C2191B: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==16990==    by 0x559D7AA: xmlRelaxNGFreeValidCtxt (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x55996EE: xmlFreeTextReader (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x405C0C: (within /usr/bin/xmllint)
==16990==    by 0x409128: (within /usr/bin/xmllint)
==16990==    by 0x5E8CB53: (below main) (in /lib64/libc-2.6.1.so)
==16990==  Address 0x40800A0 is 0 bytes inside a block of size 56 free'd
==16990==    at 0x4C2191B: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==16990==    by 0x559D7AA: xmlRelaxNGFreeValidCtxt (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x55996EE: xmlFreeTextReader (in /usr/lib64/libxml2.so.2.6.30)
==16990==    by 0x405C0C: (within /usr/bin/xmllint)
==16990==    by 0x409128: (within /usr/bin/xmllint)
==16990==    by 0x5E8CB53: (below main) (in /lib64/libc-2.6.1.so)
==16990== 
==16990== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 1)
==16990== malloc/free: in use at exit: 56 bytes in 1 blocks.
==16990== malloc/free: 529 allocs, 529 frees, 210,951 bytes allocated.
==16990== For counts of detected errors, rerun with: -v
==16990== searching for pointers to 1 not-freed blocks.
==16990== checked 266,696 bytes.
==16990== 
==16990== LEAK SUMMARY:
==16990==    definitely lost: 56 bytes in 1 blocks.
==16990==      possibly lost: 0 bytes in 0 blocks.
==16990==    still reachable: 0 bytes in 0 blocks.
==16990==         suppressed: 0 bytes in 0 blocks.
==16990== Rerun with --leak-check=full to see details of leaked memory.


Other information:
### test.xml

<?xml version="1.0"?>
<data>
<foo xmlns="http://foo.cz/" version="1.2"/>
</data>


### test.rng

<?xml version="1.0"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="any.element"/>
  </start>
  <define name="any.element">
    <choice>
      <!-- 
	   the error only occurs if this externalRef is first
	   and the data are reversed
      -->
      <externalRef href="test2.rng"/>

      <element>
	<anyName>
	  <except>
	    <name>foo</name>
	  </except>
	</anyName>
	<optional>
	  <ref name="any.element"/>
	</optional>
      </element>

    </choice>
  </define>
</grammar>


### test2.rng

<?xml version="1.0"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">

  <start combine="choice">
    <ref name="foo.element"/>
  </start>

  <include href="test3.rng">
    <define name="version">
      <value>1.2</value>
    </define>
  </include>

</grammar>



### test3.rng

<?xml version="1.0"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="foo.element"/>
  </start>

  <define name="version">
    <value>1.1</value>
  </define>

  <define name="foo.element">
    <element name="foo" ns="http://foo.cz/">
      <attribute name="version">
	<ref name="version"/>
      </attribute>
      <empty/>
    </element>
  </define>
</grammar>
Comment 1 Andreas Degert 2008-04-21 20:27:08 UTC
Maybe this error is related (simpler to reproduce):

t.xml:
<t v="a"/>

t.rnc:
start =
   element t {
      external "a.rnc"
   }

a.rnc:
# dumps core:
attribute v { key }
# works:
#attribute v { text }

Generating rng files with trang and running xmllint dumps core:
xmllint --relaxng t.rng t.xml

below are the generated files:
t.rng:
----------------------
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <element name="t">
      <externalRef href="a.rng"/>
    </element>
  </start>
  <define name="key">
    <value>a</value>
  </define>
</grammar>
----------------------

a.rng:
----------------------
<attribute name="v" xmlns="http://relaxng.org/ns/structure/1.0">
  <ref name="key"/>
</attribute>
----------------------
Comment 2 Daniel Veillard 2009-08-14 14:20:47 UTC
case #1 completely unrelated to the original problem.
Original problem fixed in git, it was a nasty free problem,
  
   thanks Petr !

Daniel
Comment 3 Daniel Veillard 2009-08-14 17:18:13 UTC
For #1 it's different it seems the ref->define link is missing
even after compilation of the schemas. I fixed the internal
code to not crash if there is such a schemas build error
(it was an oversight), fix the schemas compilation code to
fail with an internal error too, and then fix the core of
the issue which was that refs from externalRef were lost
in the gramma compisition (leading to null references).

paphio:~/XML -> xmllint --relaxng t.rng t.xml
<?xml version="1.0"?>
<t v="a"/>
t.xml validates
paphio:~/XML -> xmllint --stream --relaxng t.rng t.xml
t.xml validates
paphio:~/XML -> 

  so fixed, thanks,

Daniel