Memory access bug in XMLString2Perl()

Chris Cheung <[email protected]>
Newsgroups gmane.text.xml.xerces-p.devel
Message-ID <Pine.LNX.4.44.0312192004210.12995-100000@jupiter.cluster.clc.cuhk.edu.hk>
Dear all,

  I am currently using Xerces-C 2.3.0 and Xerces-Perl 2.3.0-4.

  When I use valgrind (a popular memory debugger, 
(http://valgrind.kde.org/) to check the following simple program:

------------------------------------------
#!/usr/bin/perl -w

use strict;

use XML::Xerces;

my $xmlString = '<?xml version="1.0"?><A><B>Hello</B></A>';

my $parser = XML::Xerces::XercesDOMParser->new();
$parser->parse(XML::Xerces::MemBufInputSource->new($xmlString));

my $doc = $parser->getDocument();

my $root = $doc->getDocumentElement;
print $root->getAttribute("notExist");
-----------------------------------------

$ valgrind ./parse.pl

valgrind detected invalid memory access like:

==24771== Invalid write of size 1
==24771==    at 0x42F06DEA: XMLString2Perl(unsigned short const*) 
(Xerces.cpp:1004)
==24771==    by 0x4306E53B: _wrap_DOMElement_getAttribute 
(Xerces.cpp:59286)
==24771==    by 0x402ACCD5: Perl_pp_entersub (in 
/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE/libperl.so)
==24771==    by 0x402A62E8: Perl_runops_standard (in 
/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE/libperl.so)
==24771==    Address 0x418CD8FC is 0 bytes after a block of size 0 alloc'd
==24771==    at 0x40026268: __builtin_vec_new (in 
/usr/lib/valgrind/vgskin_memcheck.so)
==24771==    by 0x400262C0: operator new[](unsigned) (in 
/usr/lib/valgrind/vgskin_memcheck.so)
==24771==    by 0x42F06DAE: XMLString2Perl(unsigned short const*) 
(Xerces.cpp:995)
==24771==    by 0x4306E53B: _wrap_DOMElement_getAttribute 
(Xerces.cpp:59286)

I used -ggdb3 in building Xerces-Perl and hence line number is displayed 
in the error message. It seems that

in line 995 of Xerces.cpp:

SV*
XMLString2Perl(const XMLCh* input) {
    SV *output;
  unsigned int charsEaten = 0;
  int length  = XMLString::stringLen(input);      // string length

  XMLByte* res = new XMLByte[length * UTF8_MAXLEN];          
     // output string

  unsigned int total_chars =
    UTF8_TRANSCODER->transcodeTo((const XMLCh*) input,
                   (unsigned int) length,
                   (XMLByte*) res,
                   (unsigned int) length*UTF8_MAXLEN,
                   charsEaten,
                   XMLTranscoder::UnRep_Throw
                   );
  res[total_chars] = '\0';

The memory to malloc should be (length * UTF8_MAXLEN + 1):

  XMLByte* res = new XMLByte[length * UTF8_MAXLEN + 1];          // output 

so that the memory for the ending '\0' is not missed.

Thank you for your attention.


-- 
Best Regards,

Chris Cheung
Center for Large-Scale Computation

Have a nice day!
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.