summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2016-06-23 11:24:55 +0200
committerMichael Stahl <mstahl@redhat.com>2016-06-23 11:40:35 +0200
commit8d8b9b80b114b94b20b0bf1438d80e925b49e3bf (patch)
treea7cd922f6c5b94138934e8687a2c5f41a7d37185 /package
parentcd292ba17c62a90f3530326f7fc87036da16a353 (diff)
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 7e2ea27e5d56f5cf767a6718a0f5edc28e24af14) 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
Diffstat (limited to 'package')
-rw-r--r--package/inc/ZipOutputStream.hxx1
-rw-r--r--package/source/zipapi/ZipOutputStream.cxx12
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx11
3 files changed, 23 insertions, 1 deletions
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 26d7715c05b9..136bc72b249d 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -40,6 +40,7 @@ class ZipOutputStream
ZipEntry *m_pCurrentEntry;
comphelper::ThreadPool &m_rSharedThreadPool;
std::vector< ZipOutputEntry* > m_aEntries;
+ ::css::uno::Any m_aDeflateException;
public:
ZipOutputStream(
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 9213ed7c586b..2daff01fc1c2 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -98,7 +98,12 @@ void ZipOutputStream::consumeScheduledThreadEntry(ZipOutputEntry* pCandidate)
//Any exceptions thrown in the threads were caught and stored for now
::css::uno::Any aCaughtException(pCandidate->getParallelDeflateException());
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());
@@ -178,6 +183,11 @@ void ZipOutputStream::finish()
// consume all processed entries
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());
for (ZipEntry* p : m_aZipList)
{
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 43a9b8567aa0..5efb145fd9f7 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -486,6 +486,17 @@ private:
catch (const uno::Exception&)
{
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();
}
}
};