diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp index 690458bf77a4d732527b5eea28b1f932ca534661..fe2b2d2b7c02f7c96c428cc2f4b7bb903d115684 100644 --- a/src/xercesc/internal/IGXMLScanner.cpp +++ b/src/xercesc/internal/IGXMLScanner.cpp @@ -1371,7 +1371,14 @@ void IGXMLScanner::scanDocTypeDecl() // this will break getRootElemId on DTDGrammar when // cached grammars are in use, but // why would one use this anyway??? - ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl)); + try { + ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl)); + } + catch(const XMLException&) + { + delete rootDecl; + throw; + } } else { // attach this to the undeclared element pool so that it gets deleted diff --git a/src/xercesc/internal/XMLReader.cpp b/src/xercesc/internal/XMLReader.cpp index cacead230a99abcad54552da44a27e8b3432168b..fedfb15e3eec72f4a80d5e326943c56d0eaa5dc1 100644 --- a/src/xercesc/internal/XMLReader.cpp +++ b/src/xercesc/internal/XMLReader.cpp @@ -70,6 +70,7 @@ #include <xercesc/util/TransService.hpp> #include <xercesc/util/XMLEBCDICTranscoder.hpp> #include <xercesc/util/XMLString.hpp> +#include <xercesc/util/Janitor.hpp> XERCES_CPP_NAMESPACE_BEGIN @@ -1321,6 +1322,9 @@ void XMLReader::doInitDecode() { fCharsAvail = 0; fRawBufIndex = 0; + fMemoryManager->deallocate(fPublicId); + fMemoryManager->deallocate(fEncodingStr); + ArrayJanitor<XMLCh> janValue(fSystemId, fMemoryManager); ThrowXMLwithMemMgr1 ( TranscodingException @@ -1397,6 +1401,9 @@ void XMLReader::doInitDecode() { fCharsAvail = 0; fRawBufIndex = 0; + fMemoryManager->deallocate(fPublicId); + fMemoryManager->deallocate(fEncodingStr); + ArrayJanitor<XMLCh> janValue(fSystemId, fMemoryManager); ThrowXMLwithMemMgr1 ( TranscodingException @@ -1514,6 +1521,9 @@ void XMLReader::doInitDecode() default : // It should never be anything else here + fMemoryManager->deallocate(fPublicId); + fMemoryManager->deallocate(fEncodingStr); + fMemoryManager->deallocate(fSystemId); ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Reader_BadAutoEncoding, fMemoryManager); break; } diff --git a/src/xercesc/internal/XMLScanner.cpp b/src/xercesc/internal/XMLScanner.cpp index df4d3db431ac52580eee0ea9f08f69bd676538ea..f7ea19a22d32ddf1763e6981ef61614fff0a7c5a 100644 --- a/src/xercesc/internal/XMLScanner.cpp +++ b/src/xercesc/internal/XMLScanner.cpp @@ -782,6 +782,13 @@ void XMLScanner::initValidator(XMLValidator* theValidator) { // These methods are called whenever the scanner wants to emit an error. // It handles getting the message loaded, doing token replacement, etc... // and then calling the error handler, if its installed. +bool XMLScanner::emitErrorWillThrowException(const XMLErrs::Codes toEmit) +{ + if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException) + return true; + return false; +} + void XMLScanner::emitError(const XMLErrs::Codes toEmit) { // Bump the error count if it is not a warning @@ -820,7 +827,7 @@ void XMLScanner::emitError(const XMLErrs::Codes toEmit) } // Bail out if its fatal an we are to give up on the first fatal error - if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException) + if (emitErrorWillThrowException(toEmit)) throw toEmit; } @@ -867,7 +874,7 @@ void XMLScanner::emitError( const XMLErrs::Codes toEmit } // Bail out if its fatal an we are to give up on the first fatal error - if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException) + if (emitErrorWillThrowException(toEmit)) throw toEmit; } @@ -914,7 +921,7 @@ void XMLScanner::emitError( const XMLErrs::Codes toEmit } // Bail out if its fatal an we are to give up on the first fatal error - if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException) + if (emitErrorWillThrowException(toEmit)) throw toEmit; } diff --git a/src/xercesc/internal/XMLScanner.hpp b/src/xercesc/internal/XMLScanner.hpp index 430ae9dcc418f39b00d4f4cabc8cb2022d3de2cf..4569d79548028c0f6c774c8f876a4f15bd68e131 100644 --- a/src/xercesc/internal/XMLScanner.hpp +++ b/src/xercesc/internal/XMLScanner.hpp @@ -56,6 +56,9 @@ /* * $Log$ + * Revision 1.32 2003/12/31 15:40:00 cargilld + * Release memory when an error is encountered. + * * Revision 1.31 2003/11/28 21:18:32 knoaman * Make use of canonical representation in PSVIElement * @@ -429,6 +432,7 @@ public : // ----------------------------------------------------------------------- // Error emitter methods // ----------------------------------------------------------------------- + bool emitErrorWillThrowException(const XMLErrs::Codes toEmit); void emitError(const XMLErrs::Codes toEmit); void emitError ( diff --git a/src/xercesc/validators/DTD/DTDScanner.cpp b/src/xercesc/validators/DTD/DTDScanner.cpp index 08bff4044d365b65d72d1d8f179eff2dea643236..48c6e035efcc44a4566059d68dd1071ae6d05789 100644 --- a/src/xercesc/validators/DTD/DTDScanner.cpp +++ b/src/xercesc/validators/DTD/DTDScanner.cpp @@ -56,6 +56,9 @@ /* * $Log$ + * Revision 1.31 2003/12/31 15:40:00 cargilld + * Release memory when an error is encountered. + * * Revision 1.30 2003/12/17 00:18:40 cargilld * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data. * @@ -1322,7 +1325,13 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse) if (tmpNode != curNode) { if (gotSpaces) + { + if (fScanner->emitErrorWillThrowException(XMLErrs::UnexpectedWhitespace)) + { + delete tmpNode; + } fScanner->emitError(XMLErrs::UnexpectedWhitespace); + } fReaderMgr->getNextChar(); curNode = tmpNode; } @@ -1447,7 +1456,15 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse) curReader = fReaderMgr->getCurrentReaderNum(); // Recurse to handle this new guy - ContentSpecNode* subNode = scanChildren(elemDecl, bufToUse); + ContentSpecNode* subNode; + try { + subNode = scanChildren(elemDecl, bufToUse); + } + catch (const XMLErrs::Codes) + { + delete headNode; + throw; + } // If it failed, we are done, clean up here and return failure if (!subNode) @@ -1542,6 +1559,7 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse) else { // Cannot be valid + delete headNode; // emitError may do a throw so need to clean-up first if (opCh == chComma) { fScanner->emitError(XMLErrs::ExpectedChoiceOrCloseParen); @@ -1553,8 +1571,7 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse) XMLErrs::ExpectedSeqOrCloseParen , elemDecl.getFullName() ); - } - delete headNode; + } return 0; } } @@ -3421,6 +3438,10 @@ bool DTDScanner::scanMixed(DTDElementDecl& toFill) // Tell them they can't have reps in mixed model, but eat // it and keep going if we are allowed to. // + if (fScanner->emitErrorWillThrowException(XMLErrs::NoRepInMixed)) + { + delete headNode; + } fScanner->emitError(XMLErrs::NoRepInMixed); } else if (fReaderMgr->skippedSpace()) @@ -3446,7 +3467,13 @@ bool DTDScanner::scanMixed(DTDElementDecl& toFill) starSkipped = false; if (starRequired) + { + if (fScanner->emitErrorWillThrowException(XMLErrs::UnterminatedContentModel)) + { + delete headNode; + } fScanner->emitError(XMLErrs::ExpectedAsterisk); + } } //