summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2016-06-23 11:24:55 +0200
committerAndras Timar <andras.timar@collabora.com>2016-06-26 14:01:58 +0200
commitf12527af8ba964dffa36c61f6465e3a1127284f0 (patch)
tree9c1283321d728aae0148bd228a2df60636d60d09 /package
parent253e31d0f367f283be5db2bbe3c304bb6c7cc257 (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. (cherry picked from commit 8d8b9b80b114b94b20b0bf1438d80e925b49e3bf) sfx2: exception on storage commit is an error (related: tdf#91807) For no good or obvious reason, SfxMedium::StorageCommit_Impl() swallows embed::UseBackupException if there is a pTempFile, which (as the comment claims) is "always now". This results in the temp file actually being copied to the user-visible file and the SaveAs "succeeding", when it clearly did not. Also move the exception throwing to the end of ZipOutputStream::finish() to avoid more memory leaks. (cherry picked from commit 9084c11fb472f2024e609770ce922c911227e7a8) Change-Id: I448cc43291754ef20adfa6b65916282fcc365a11 Reviewed-on: https://gerrit.libreoffice.org/26618 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 60f668ba594c08aa935887ecd0e76d6ba016f166)
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 f995469b29e6..0f306182f63a 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 8cd8b9056989..94413e26f716 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());
@@ -187,6 +192,11 @@ void ZipOutputStream::finish()
writeEND( nOffset, static_cast < sal_Int32 > (m_aChucker.GetPosition()) - nOffset);
m_xStream->flush();
m_aZipList.clear();
+
+ if (m_aDeflateException.hasValue())
+ { // throw once all threads are finished and m_aEntries can be released
+ ::cppu::throwException(m_aDeflateException);
+ }
}
css::uno::Reference< css::io::XOutputStream > ZipOutputStream::getStream()
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 0ff190a69411..3e84d1ef127e 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();
}
}
};