http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1329 *** shadow/1329 Thu Apr 12 14:12:44 2001 --- shadow/1329.tmp.26322 Thu Apr 12 14:12:44 2001 *************** *** 0 **** --- 1,127 ---- + +============================================================================+ + | SAX2XMLReaderImpl leaks XMLBuffers | + +----------------------------------------------------------------------------+ + | Bug #: 1329 Product: Xerces-C | + | Status: NEW Version: 1.4 | + | Resolution: Platform: PC | + | Severity: Major OS/Version: | + | Priority: Component: SAX/SAX2 | + +----------------------------------------------------------------------------+ + | Assigned To: [EMAIL PROTECTED] | + | Reported By: [EMAIL PROTECTED] | + | CC list: Cc: | + +----------------------------------------------------------------------------+ + | URL: | + +============================================================================+ + | DESCRIPTION | + Overview Description: + The implementations of SAX2XMLReaderImpl::startElement and + SAX2XMLReaderImpl::endElement will leak buffers in the case where the + ContentHandler throws an exception. If you reuse instances of the same + XMLReader repeatedly, XMLBufferManager::bidOnBuffer will eventually throw an + XMLExcepts::BufMgr_NoMoreBuffers. + + Steps to Reproduce: + The following sample code illustrates this problem (built using Microsoft + Visual C++ 6 SP5): + //----------------------------------------------------------------------------- + // SAX2BufferLeak.cpp - demonstrates a bug in Xerces-c 1.4.0 + #include "stdafx.h" + + #include <iostream> + + #include <util/PlatformUtils.hpp> + #include <sax2/DefaultHandler.hpp> + #include <sax2/XMLReaderFactory.hpp> + #include <framework/MemBufInputSource.hpp> + + using namespace std; + + + class ErrorThrowingContentHandler : public DefaultHandler + { + public: + + virtual void startElement( + const XMLCh* const uri, + const XMLCh* const localname, + const XMLCh* const qname, + const Attributes& attributes) + { + throw true; + }; + + virtual void fatalError(const SAXParseException& exception) + { + throw exception; + }; + + }; + + + int main(int argc, char* argv[]) + { + XMLPlatformUtils::Initialize(); + + SAX2XMLReader* reader = XMLReaderFactory::createXMLReader(); + + ErrorThrowingContentHandler* handler = new ErrorThrowingContentHandler + (); + reader->setContentHandler(handler); + reader->setErrorHandler(handler); + + for (size_t i = 0; i < 35; i++) + { + MemBufInputSource is((XMLByte*)"<x:e1 + xmlns:x=\"urn:mynamespace\"></x:e1>", 39, L"FakeSystemID"); + + try + { + reader->parse(is); + } + catch(bool) + { + // Do nothing - we expect this to happen + } + catch(SAXParseException& e) + { + wcout << L"SAXParseException" << endl + << L"i=" << i << endl + << L"Message: " << e.getMessage() << + endl; + break; + } + } + + XMLPlatformUtils::Terminate(); + + return 0; + } + //----------------------------------------------------------------------------- + + This program will print the following on the console: + + SAXParseException + i=31 + Message: An exception occured! Type:RuntimeException, Message:The buffer manager + cannot provide any more buffers + + Expected Results: + The above program should print out nothing. + + Additional Information: + SAX2XMLReaderImpl does not manage the fStringBuffer, fPrefixes and prefixCounts + members properly in the case where: + + - The document uses namespaces. + - An errorHandler stops the parse by throwing an exception. + + This problem only becomes apparent when you attempt to reuse a SAX2XMLReader + repeatedly. The case in point is in the SOAP service we have implemented. It + maintains a thread pool with a complete SAX pipeline setup on each thread. This + is critical for performance reasons (and is a generally good approch when + possible). + + Possible solutions include try/catch blocks to SAX2XMLReader::startElement and + SAX2XMLReader::endElement, or simply ensuring the the fStringBuffer, fPrefixes + and prefixCount (any others?) are reset properly on each reuse of the parser. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
