Kaydet (Commit) 8d8b9b80 authored tarafından Michael Stahl's avatar Michael Stahl

package: fix exception handling in DeflateThread (related tdf#91807)

In the bugdoc of tdf#91807 there are at least 49 corrupt zip streams
that raise exceptions in the DeflateThreads.  Because the maximum
allowed number of threads happens to be 48, this results in an infinite
loop in ZipOutputStream::reduceScheduledThreadsToGivenNumberOrLess().

(regression from 7e2ea27e)

In case an exception is thrown, don't re-throw it immediately, which
might cause trouble such as leaking all of the ZipOutputEntry instances
in m_aEntries.

Change-Id: Ia74ab8e46fa1349c049d05dbec3454bfbe7d61d9
üst cd292ba1
...@@ -40,6 +40,7 @@ class ZipOutputStream ...@@ -40,6 +40,7 @@ class ZipOutputStream
ZipEntry *m_pCurrentEntry; ZipEntry *m_pCurrentEntry;
comphelper::ThreadPool &m_rSharedThreadPool; comphelper::ThreadPool &m_rSharedThreadPool;
std::vector< ZipOutputEntry* > m_aEntries; std::vector< ZipOutputEntry* > m_aEntries;
::css::uno::Any m_aDeflateException;
public: public:
ZipOutputStream( ZipOutputStream(
......
...@@ -98,7 +98,12 @@ void ZipOutputStream::consumeScheduledThreadEntry(ZipOutputEntry* pCandidate) ...@@ -98,7 +98,12 @@ void ZipOutputStream::consumeScheduledThreadEntry(ZipOutputEntry* pCandidate)
//Any exceptions thrown in the threads were caught and stored for now //Any exceptions thrown in the threads were caught and stored for now
::css::uno::Any aCaughtException(pCandidate->getParallelDeflateException()); ::css::uno::Any aCaughtException(pCandidate->getParallelDeflateException());
if (aCaughtException.hasValue()) if (aCaughtException.hasValue())
::cppu::throwException(aCaughtException); {
m_aDeflateException = aCaughtException; // store it for later throwing
// the exception handler in DeflateThread should have cleaned temp file
delete pCandidate;
return;
}
writeLOC(pCandidate->getZipEntry(), pCandidate->isEncrypt()); writeLOC(pCandidate->getZipEntry(), pCandidate->isEncrypt());
...@@ -178,6 +183,11 @@ void ZipOutputStream::finish() ...@@ -178,6 +183,11 @@ void ZipOutputStream::finish()
// consume all processed entries // consume all processed entries
consumeAllScheduledThreadEntries(); consumeAllScheduledThreadEntries();
if (m_aDeflateException.hasValue())
{ // throw once all threads are finished and m_aEntries can be released
::cppu::throwException(m_aDeflateException);
}
sal_Int32 nOffset= static_cast < sal_Int32 > (m_aChucker.GetPosition()); sal_Int32 nOffset= static_cast < sal_Int32 > (m_aChucker.GetPosition());
for (ZipEntry* p : m_aZipList) for (ZipEntry* p : m_aZipList)
{ {
......
...@@ -486,6 +486,17 @@ private: ...@@ -486,6 +486,17 @@ private:
catch (const uno::Exception&) catch (const uno::Exception&)
{ {
mpEntry->setParallelDeflateException(::cppu::getCaughtException()); mpEntry->setParallelDeflateException(::cppu::getCaughtException());
try
{
if (mpEntry->m_xOutStream.is())
mpEntry->closeBufferFile();
if (!mpEntry->m_aTempURL.isEmpty())
mpEntry->deleteBufferFile();
}
catch (uno::Exception const&)
{
}
mpEntry->setFinished();
} }
} }
}; };
......
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