diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-07-09 17:22:15 +0200 |
---|---|---|
committer | Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> | 2024-07-10 17:10:28 +0200 |
commit | e1ce2e92f1198afa09ae418dcd414753cd283923 (patch) | |
tree | ced59229b1fe421d6dd1047e5ede4740b83c16db | |
parent | update credits (diff) | |
download | core-e1ce2e92f1198afa09ae418dcd414753cd283923.tar.gz core-e1ce2e92f1198afa09ae418dcd414753cd283923.zip |
package: ZipFile: don't accept duplicate entries (case insensitive)
This is required for OOXML, but not for ODF.
Unclear if there are use cases for this with ODF, can add some
conditions if it turns out to be a problem.
Change-Id: I3810da5c2273574135d133b4a9bbad98dc97af44
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170223
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit 4833f131243bdb409ddfaff8b4db87d4ed2af98f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170291
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r-- | package/inc/ZipFile.hxx | 4 | ||||
-rw-r--r-- | package/source/zipapi/ZipFile.cxx | 24 |
2 files changed, 22 insertions, 6 deletions
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx index 8bc726af8457..d9910fde92a9 100644 --- a/package/inc/ZipFile.hxx +++ b/package/inc/ZipFile.hxx @@ -29,6 +29,8 @@ #include "HashMaps.hxx" #include "EncryptionData.hxx" +#include <unordered_set> + class MemoryByteGrabber; namespace com::sun::star { namespace uno { class XComponentContext; } @@ -52,6 +54,8 @@ class ZipFile { rtl::Reference<comphelper::RefCountedMutex> m_aMutexHolder; + std::unordered_set<OUString> m_EntriesInsensitive; + EntryHash aEntries; ByteGrabber aGrabber; ZipUtils::Inflater aInflater; diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index c7e10cb06e39..1e1ab575dcfe 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -94,6 +94,7 @@ ZipFile::ZipFile( rtl::Reference<comphelper::RefCountedMutex> aMutexHolder, if (bInitialise && readCEN() == -1 ) { aEntries.clear(); + m_EntriesInsensitive.clear(); throw ZipException( "stream data looks to be broken" ); } } @@ -118,6 +119,7 @@ ZipFile::ZipFile( rtl::Reference< comphelper::RefCountedMutex > aMutexHolder, else if ( readCEN() == -1 ) { aEntries.clear(); + m_EntriesInsensitive.clear(); throw ZipException("stream data looks to be broken" ); } } @@ -1156,15 +1158,19 @@ sal_Int32 ZipFile::readCEN() continue; // This is a directory entry, not a stream - skip it } - if (auto it = aEntries.find(aEntry.sPath); it == aEntries.end()) - { - aEntries[aEntry.sPath] = aEntry; - } - else + if (aEntries.find(aEntry.sPath) != aEntries.end()) { SAL_INFO("package", "Duplicate CEN entry: \"" << aEntry.sPath << "\""); throw ZipException(u"Duplicate CEN entry"_ustr); } + // this is required for OOXML, but not for ODF + auto const lowerPath(aEntry.sPath.toAsciiLowerCase()); + if (!m_EntriesInsensitive.insert(lowerPath).second) + { + SAL_INFO("package", "Duplicate CEN entry (case insensitive): \"" << aEntry.sPath << "\""); + throw ZipException(u"Duplicate CEN entry (case insensitive)"_ustr); + } + aEntries[aEntry.sPath] = aEntry; } if (nCount != nTotal) @@ -1373,7 +1379,13 @@ void ZipFile::recover() nPos += 4; continue; } - + auto const lowerPath(aEntry.sPath.toAsciiLowerCase()); + if (m_EntriesInsensitive.find(lowerPath) != m_EntriesInsensitive.end()) + { // this is required for OOXML, but not for ODF + nPos += 4; + continue; + } + m_EntriesInsensitive.insert(lowerPath); aEntries.emplace( aEntry.sPath, aEntry ); // Drop any "directory" entry corresponding to this one's path; |