summaryrefslogtreecommitdiff
path: root/sax
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-11-29 21:18:11 +0000
committerCaolán McNamara <caolanm@redhat.com>2017-11-30 09:55:41 +0100
commit5591aa360874c9133d046eeaa1c315df1a441bc4 (patch)
tree165f46c5534fab9ef44fc1dcea6d27fd204d4c38 /sax
parentab60361f66b286144c7f6b58c9c9cecb83c9d223 (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')
-rw-r--r--sax/source/fastparser/fastparser.cxx156
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 )