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>
This commit is contained in:
Michael Stahl
2024-07-10 12:08:09 +02:00
parent bf972de2c1
commit 4833f13124
2 changed files with 21 additions and 5 deletions
+4
View File
@@ -30,6 +30,7 @@
#include "EncryptionData.hxx"
#include <span>
#include <unordered_set>
class MemoryByteGrabber;
namespace com::sun::star {
@@ -50,10 +51,13 @@ namespace rtl
class ZipEnumeration;
class ZipFile
{
rtl::Reference<comphelper::RefCountedMutex> m_aMutexHolder;
std::unordered_set<OUString> m_EntriesInsensitive;
EntryHash aEntries;
ByteGrabber aGrabber;
ZipUtils::Inflater aInflater;
+17 -5
View File
@@ -94,6 +94,7 @@ ZipFile::ZipFile( rtl::Reference<comphelper::RefCountedMutex> aMutexHolder,
if (bInitialise && readCEN() == -1 )
{
aEntries.clear();
m_EntriesInsensitive.clear();
throw ZipException( u"stream data looks to be broken"_ustr );
}
}
@@ -118,6 +119,7 @@ ZipFile::ZipFile( rtl::Reference< comphelper::RefCountedMutex > aMutexHolder,
else if ( readCEN() == -1 )
{
aEntries.clear();
m_EntriesInsensitive.clear();
throw ZipException(u"stream data looks to be broken"_ustr );
}
}
@@ -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)
@@ -1335,6 +1341,12 @@ void ZipFile::HandlePK34(std::span<const sal_Int8> data, sal_Int64 dataOffset, s
!= aEntries.end())
return;
auto const lowerPath(aEntry.sPath.toAsciiLowerCase());
if (m_EntriesInsensitive.find(lowerPath) != m_EntriesInsensitive.end())
{ // this is required for OOXML, but not for ODF
return;
}
m_EntriesInsensitive.insert(lowerPath);
aEntries.emplace(aEntry.sPath, aEntry);
// Drop any "directory" entry corresponding to this one's path; since we don't use