Kaydet (Commit) 3b81d36d authored tarafından Michael Stahl's avatar Michael Stahl Kaydeden (comit) Caolán McNamara

ofz#4392 sax: guard access to Entity::maSavedException with mutex

The problem here is presumably that the parser thread reports a
low-level SAX exception and the main thread reports a high-level filter
exception at the same time, so both threads modify maSavedException
concurrently.

Reviewed-on: https://gerrit.libreoffice.org/47478Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
(cherry picked from commit 2a88f62a)

Change-Id: Ic8ce9a4992208a24a111c990a67be163858ddaf8
Reviewed-on: https://gerrit.libreoffice.org/47542Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst 7f9a8481
...@@ -174,6 +174,7 @@ struct Entity : public ParserData ...@@ -174,6 +174,7 @@ struct Entity : public ParserData
// resource leaks), therefore any exception thrown by a UNO callback // resource leaks), therefore any exception thrown by a UNO callback
// must be saved somewhere until the C-XmlParser is stopped. // must be saved somewhere until the C-XmlParser is stopped.
css::uno::Any maSavedException; css::uno::Any maSavedException;
osl::Mutex maSavedExceptionMutex;
void saveException( const Any & e ); void saveException( const Any & e );
void throwException( const ::rtl::Reference< FastLocatorImpl > &xDocumentLocator, void throwException( const ::rtl::Reference< FastLocatorImpl > &xDocumentLocator,
bool mbDuringParse ); bool mbDuringParse );
...@@ -586,12 +587,20 @@ void Entity::throwException( const ::rtl::Reference< FastLocatorImpl > &xDocumen ...@@ -586,12 +587,20 @@ void Entity::throwException( const ::rtl::Reference< FastLocatorImpl > &xDocumen
bool mbDuringParse ) bool mbDuringParse )
{ {
// Error during parsing ! // Error during parsing !
Any savedException;
{
osl::MutexGuard g(maSavedExceptionMutex);
if (maSavedException.hasValue())
{
savedException.setValue(&maSavedException, cppu::UnoType<decltype(maSavedException)>::get());
}
}
SAXParseException aExcept( SAXParseException aExcept(
lclGetErrorMessage( mpParser, lclGetErrorMessage( mpParser,
xDocumentLocator->getSystemId(), xDocumentLocator->getSystemId(),
xDocumentLocator->getLineNumber() ), xDocumentLocator->getLineNumber() ),
Reference< XInterface >(), Reference< XInterface >(),
Any( &maSavedException, cppu::UnoType<decltype(maSavedException)>::get() ), savedException,
xDocumentLocator->getPublicId(), xDocumentLocator->getPublicId(),
xDocumentLocator->getSystemId(), xDocumentLocator->getSystemId(),
xDocumentLocator->getLineNumber(), xDocumentLocator->getLineNumber(),
...@@ -623,7 +632,15 @@ void Entity::saveException( const Any & e ) ...@@ -623,7 +632,15 @@ void Entity::saveException( const Any & e )
// for XComponent; and yet expect to continue parsing. // for XComponent; and yet expect to continue parsing.
SAL_WARN("sax", "Unexpected exception from XML parser " SAL_WARN("sax", "Unexpected exception from XML parser "
<< e.get<Exception>().Message); << e.get<Exception>().Message);
maSavedException = e; osl::MutexGuard g(maSavedExceptionMutex);
if (maSavedException.hasValue())
{
SAL_INFO("sax.fastparser", "discarding exception, already have one");
}
else
{
maSavedException = e;
}
} }
} // namespace } // namespace
...@@ -842,6 +859,8 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) ...@@ -842,6 +859,8 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource)
deleteUsedEvents(); deleteUsedEvents();
// callbacks used inside XML_Parse may have caught an exception // callbacks used inside XML_Parse may have caught an exception
// No need to lock maSavedExceptionMutex here because parser
// thread is joined.
if( rEntity.maSavedException.hasValue() ) if( rEntity.maSavedException.hasValue() )
rEntity.throwException( mxDocumentLocator, true ); rEntity.throwException( mxDocumentLocator, true );
} }
...@@ -1050,8 +1069,16 @@ void FastSaxParserImpl::parse() ...@@ -1050,8 +1069,16 @@ void FastSaxParserImpl::parse()
} }
// callbacks used inside XML_Parse may have caught an exception // callbacks used inside XML_Parse may have caught an exception
if( !bContinue || rEntity.maSavedException.hasValue() ) if (!bContinue)
{
rEntity.throwException( mxDocumentLocator, true ); rEntity.throwException( mxDocumentLocator, true );
}
osl::ClearableMutexGuard g(rEntity.maSavedExceptionMutex);
if (rEntity.maSavedException.hasValue())
{
g.clear();
rEntity.throwException( mxDocumentLocator, true );
}
} while( nRead > 0 ); } while( nRead > 0 );
rEntity.getEvent( DONE ); rEntity.getEvent( DONE );
if( rEntity.mbEnableThreads ) if( rEntity.mbEnableThreads )
......
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