Kaydet (Commit) 5591aa36 authored tarafından Caolán McNamara's avatar Caolán McNamara

ofz: always free with xmlFreeParserCtxt

Change-Id: I90aed11ae0a29a0e9fc725b297e10a7ed30c9942
Reviewed-on: https://gerrit.libreoffice.org/45533Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst ab60361f
...@@ -730,6 +730,27 @@ sal_Int32 FastSaxParserImpl::GetTokenWithContextNamespace( sal_Int32 nNamespaceT ...@@ -730,6 +730,27 @@ sal_Int32 FastSaxParserImpl::GetTokenWithContextNamespace( sal_Int32 nNamespaceT
return FastToken::DONTKNOW; 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 * parseStream does Parser-startup initializations. The FastSaxParser::parse() method does
...@@ -755,104 +776,81 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) ...@@ -755,104 +776,81 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource)
pushEntity( entity ); pushEntity( entity );
Entity& rEntity = getEntity(); Entity& rEntity = getEntity();
try ParserCleanup aEnsureFree(*this, rEntity);
// start the document
if( rEntity.mxDocumentHandler.is() )
{ {
// start the document Reference< XLocator > xLoc( mxDocumentLocator.get() );
if( rEntity.mxDocumentHandler.is() ) 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 rEntity.mbEnableThreads = rEntity.maStructSource.aInputStream->available() > 10000
&& !getenv("SAX_DISABLE_THREADS"); && !getenv("SAX_DISABLE_THREADS");
if (rEntity.mbEnableThreads) if (rEntity.mbEnableThreads)
{ {
rtl::Reference<ParserThread> xParser; rtl::Reference<ParserThread> xParser;
xParser = new ParserThread(this); xParser = new ParserThread(this);
xParser->launch(); xParser->launch();
bool done = false; bool done = false;
do { do {
rEntity.maConsumeResume.wait(); rEntity.maConsumeResume.wait();
rEntity.maConsumeResume.reset(); rEntity.maConsumeResume.reset();
osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); osl::ResettableMutexGuard aGuard(rEntity.maEventProtector);
while (!rEntity.maPendingEvents.empty()) while (!rEntity.maPendingEvents.empty())
{ {
if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater) if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater)
rEntity.maProduceResume.set(); // start producer again rEntity.maProduceResume.set(); // start producer again
std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front()); std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front());
rEntity.maPendingEvents.pop(); rEntity.maPendingEvents.pop();
aGuard.clear(); // unlock aGuard.clear(); // unlock
if (!consume(*xEventList)) if (!consume(*xEventList))
done = true; 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(); if (aEventIt->mxAttributes.is())
for (auto aEventIt = xEventList->maEvents.begin();
aEventIt != xEventList->maEvents.end(); ++aEventIt)
{ {
if (aEventIt->mxAttributes.is()) aEventIt->mxAttributes->clear();
{ if( rEntity.mxNamespaceHandler.is() )
aEventIt->mxAttributes->clear(); aEventIt->mxDeclAttributes->clear();
if( rEntity.mxNamespaceHandler.is() )
aEventIt->mxDeclAttributes->clear();
}
xEventList->mbIsAttributesEmpty = true;
} }
aGuard.reset(); xEventList->mbIsAttributesEmpty = true;
} }
aGuard.reset();
rEntity.maUsedEvents.push(std::move(xEventList));
} }
} while (!done);
xParser->join();
deleteUsedEvents();
// callbacks used inside XML_Parse may have caught an exception rEntity.maUsedEvents.push(std::move(xEventList));
if( rEntity.maSavedException.hasValue() ) }
rEntity.throwException( mxDocumentLocator, true ); } while (!done);
} xParser->join();
else deleteUsedEvents();
{
parse();
}
// finish document // callbacks used inside XML_Parse may have caught an exception
if( rEntity.mxDocumentHandler.is() ) if( rEntity.maSavedException.hasValue() )
{ rEntity.throwException( mxDocumentLocator, true );
rEntity.mxDocumentHandler->endDocument();
}
}
catch (const SAXException&)
{
// TODO free mpParser.myDoc ?
xmlFreeParserCtxt( rEntity.mpParser );
popEntity();
throw;
} }
catch (const IOException&) else
{ {
xmlFreeParserCtxt( rEntity.mpParser ); parse();
popEntity();
throw;
} }
catch (const RuntimeException&)
// finish document
if( rEntity.mxDocumentHandler.is() )
{ {
xmlFreeParserCtxt( rEntity.mpParser ); rEntity.mxDocumentHandler->endDocument();
popEntity();
throw;
} }
xmlFreeParserCtxt( rEntity.mpParser );
popEntity();
} }
void FastSaxParserImpl::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) void FastSaxParserImpl::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment