diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-11-29 21:18:11 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-11-30 09:55:41 +0100 |
commit | 5591aa360874c9133d046eeaa1c315df1a441bc4 (patch) | |
tree | 165f46c5534fab9ef44fc1dcea6d27fd204d4c38 /sax/source | |
parent | ab60361f66b286144c7f6b58c9c9cecb83c9d223 (diff) |
ofz: always free with xmlFreeParserCtxt
Change-Id: I90aed11ae0a29a0e9fc725b297e10a7ed30c9942
Reviewed-on: https://gerrit.libreoffice.org/45533
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sax/source')
-rw-r--r-- | sax/source/fastparser/fastparser.cxx | 156 |
1 files changed, 77 insertions, 79 deletions
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 8c0286656764..1aa8811366ea 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -730,6 +730,27 @@ sal_Int32 FastSaxParserImpl::GetTokenWithContextNamespace( sal_Int32 nNamespaceT return FastToken::DONTKNOW; } +namespace +{ + class ParserCleanup + { + private: + FastSaxParserImpl& m_rParser; + Entity& m_rEntity; + public: + ParserCleanup(FastSaxParserImpl& rParser, Entity& rEntity) + : m_rParser(rParser) + , m_rEntity(rEntity) + { + } + ~ParserCleanup() + { + //xmlFreeParserCtxt accepts a null arg + xmlFreeParserCtxt(m_rEntity.mpParser); + m_rParser.popEntity(); + } + }; +} /*************** * * parseStream does Parser-startup initializations. The FastSaxParser::parse() method does @@ -755,104 +776,81 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) pushEntity( entity ); Entity& rEntity = getEntity(); - try + ParserCleanup aEnsureFree(*this, rEntity); + + // start the document + if( rEntity.mxDocumentHandler.is() ) { - // start the document - if( rEntity.mxDocumentHandler.is() ) - { - Reference< XLocator > xLoc( mxDocumentLocator.get() ); - rEntity.mxDocumentHandler->setDocumentLocator( xLoc ); - rEntity.mxDocumentHandler->startDocument(); - } + Reference< XLocator > xLoc( mxDocumentLocator.get() ); + rEntity.mxDocumentHandler->setDocumentLocator( xLoc ); + rEntity.mxDocumentHandler->startDocument(); + } - rEntity.mbEnableThreads = rEntity.maStructSource.aInputStream->available() > 10000 - && !getenv("SAX_DISABLE_THREADS"); + rEntity.mbEnableThreads = rEntity.maStructSource.aInputStream->available() > 10000 + && !getenv("SAX_DISABLE_THREADS"); - if (rEntity.mbEnableThreads) - { - rtl::Reference<ParserThread> xParser; - xParser = new ParserThread(this); - xParser->launch(); - bool done = false; - do { - rEntity.maConsumeResume.wait(); - rEntity.maConsumeResume.reset(); - - osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); - while (!rEntity.maPendingEvents.empty()) - { - if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater) - rEntity.maProduceResume.set(); // start producer again + if (rEntity.mbEnableThreads) + { + rtl::Reference<ParserThread> xParser; + xParser = new ParserThread(this); + xParser->launch(); + bool done = false; + do { + rEntity.maConsumeResume.wait(); + rEntity.maConsumeResume.reset(); + + osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); + while (!rEntity.maPendingEvents.empty()) + { + if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater) + rEntity.maProduceResume.set(); // start producer again - std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front()); - rEntity.maPendingEvents.pop(); - aGuard.clear(); // unlock + std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front()); + rEntity.maPendingEvents.pop(); + aGuard.clear(); // unlock - if (!consume(*xEventList)) - done = true; + if (!consume(*xEventList)) + done = true; - aGuard.reset(); // lock + aGuard.reset(); // lock - if ( rEntity.maPendingEvents.size() <= Entity::mnEventLowWater ) + if ( rEntity.maPendingEvents.size() <= Entity::mnEventLowWater ) + { + aGuard.clear(); + for (auto aEventIt = xEventList->maEvents.begin(); + aEventIt != xEventList->maEvents.end(); ++aEventIt) { - aGuard.clear(); - for (auto aEventIt = xEventList->maEvents.begin(); - aEventIt != xEventList->maEvents.end(); ++aEventIt) + if (aEventIt->mxAttributes.is()) { - if (aEventIt->mxAttributes.is()) - { - aEventIt->mxAttributes->clear(); - if( rEntity.mxNamespaceHandler.is() ) - aEventIt->mxDeclAttributes->clear(); - } - xEventList->mbIsAttributesEmpty = true; + aEventIt->mxAttributes->clear(); + if( rEntity.mxNamespaceHandler.is() ) + aEventIt->mxDeclAttributes->clear(); } - aGuard.reset(); + xEventList->mbIsAttributesEmpty = true; } - - rEntity.maUsedEvents.push(std::move(xEventList)); + aGuard.reset(); } - } while (!done); - xParser->join(); - deleteUsedEvents(); - // callbacks used inside XML_Parse may have caught an exception - if( rEntity.maSavedException.hasValue() ) - rEntity.throwException( mxDocumentLocator, true ); - } - else - { - parse(); - } + rEntity.maUsedEvents.push(std::move(xEventList)); + } + } while (!done); + xParser->join(); + deleteUsedEvents(); - // finish document - if( rEntity.mxDocumentHandler.is() ) - { - rEntity.mxDocumentHandler->endDocument(); - } - } - catch (const SAXException&) - { - // TODO free mpParser.myDoc ? - xmlFreeParserCtxt( rEntity.mpParser ); - popEntity(); - throw; + // callbacks used inside XML_Parse may have caught an exception + if( rEntity.maSavedException.hasValue() ) + rEntity.throwException( mxDocumentLocator, true ); } - catch (const IOException&) + else { - xmlFreeParserCtxt( rEntity.mpParser ); - popEntity(); - throw; + parse(); } - catch (const RuntimeException&) + + // finish document + if( rEntity.mxDocumentHandler.is() ) { - xmlFreeParserCtxt( rEntity.mpParser ); - popEntity(); - throw; + rEntity.mxDocumentHandler->endDocument(); } - - xmlFreeParserCtxt( rEntity.mpParser ); - popEntity(); } void FastSaxParserImpl::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) |