summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2024-08-27 14:21:33 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2024-08-28 07:35:23 +0200
commitbf1099e360193e18c29e7b042dcc1480050a4e48 (patch)
tree415bf8d036d923149db9d3391ef53c15869cd2b1 /package
parent1e0ba98adf0123aed4a0f9a208d1b132a6d2b7ab (diff)
tdf#158556 reduce allocations in ZipFile
we can allocate these buffers one caller up in ReadCEN and then re-use them Change-Id: I07e98168ee2884286f4a1c281acd86e365416149 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172481 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
Diffstat (limited to 'package')
-rw-r--r--package/inc/ZipFile.hxx1
-rw-r--r--package/source/zipapi/ZipFile.cxx29
2 files changed, 22 insertions, 8 deletions
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
index 4704d0e09910..c52bfc7a0366 100644
--- a/package/inc/ZipFile.hxx
+++ b/package/inc/ZipFile.hxx
@@ -93,6 +93,7 @@ private:
void getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_Int64 *nSize, sal_Int32 *nCRC );
sal_uInt64 readLOC(ZipEntry &rEntry);
+ sal_uInt64 readLOC_Impl(ZipEntry &rEntry, std::vector<sal_Int8>& rNameBuffer, std::vector<sal_Int8>& rExtraBuffer);
sal_Int32 readCEN();
std::tuple<sal_Int64, sal_Int64, sal_Int64> findCentralDirectory();
void HandlePK34(std::span<const sal_Int8> data, sal_Int64 dataOffset, sal_Int64 totalSize);
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index 706292148da3..7914c772dbb7 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -931,6 +931,16 @@ uno::Reference< XInputStream > ZipFile::getWrappedRawStream(
sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
{
::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
+ std::vector<sal_Int8> aNameBuffer;
+ std::vector<sal_Int8> aExtraBuffer;
+ return readLOC_Impl(rEntry, aNameBuffer, aExtraBuffer);
+}
+
+// Pass in a shared name buffer to reduce the number of allocations
+// we do when reading the CEN.
+sal_uInt64 ZipFile::readLOC_Impl(ZipEntry &rEntry, std::vector<sal_Int8>& rNameBuffer, std::vector<sal_Int8>& rExtraBuffer)
+{
+ ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
sal_Int64 nPos = -rEntry.nOffset;
@@ -977,9 +987,9 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
{
// read always in UTF8, some tools seem not to set UTF8 bit
// coverity[tainted_data] - we've checked negative lens, and up to max short is ok here
- std::vector<sal_Int8> aNameBuffer(nPathLen);
- sal_Int32 nRead = aGrabber.readBytes(aNameBuffer.data(), nPathLen);
- std::string_view aNameView(reinterpret_cast<const char *>(aNameBuffer.data()), nRead);
+ rNameBuffer.reserve(nPathLen);
+ sal_Int32 nRead = aGrabber.readBytes(rNameBuffer.data(), nPathLen);
+ std::string_view aNameView(reinterpret_cast<const char *>(rNameBuffer.data()), nRead);
OUString sLOCPath( aNameView.data(), aNameView.size(), RTL_TEXTENCODING_UTF8 );
@@ -999,9 +1009,9 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
::std::optional<sal_uInt64> oOffset64;
if (nExtraLen != 0)
{
- std::vector<sal_Int8> aExtraBuffer(nExtraLen);
- aGrabber.readBytes(aExtraBuffer.data(), nExtraLen);
- MemoryByteGrabber extraMemGrabber(aExtraBuffer.data(), nExtraLen);
+ rExtraBuffer.reserve(nExtraLen);
+ aGrabber.readBytes(rExtraBuffer.data(), nExtraLen);
+ MemoryByteGrabber extraMemGrabber(rExtraBuffer.data(), nExtraLen);
isZip64 = readExtraFields(extraMemGrabber, nExtraLen,
nLocSize, nLocCompressedSize, oOffset64, &aNameView);
@@ -1330,7 +1340,8 @@ sal_Int32 ZipFile::readCEN()
throw ZipException(u"central directory too big"_ustr);
aGrabber.seek(nCenPos);
- std::vector<sal_Int8> aCENBuffer(nCenLen);
+ std::vector<sal_Int8> aCENBuffer;
+ aCENBuffer.reserve(nCenLen);
sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer.data(), nCenLen );
if (nCenLen != nRead)
throw ZipException (u"Error reading CEN into memory buffer!"_ustr );
@@ -1343,6 +1354,8 @@ sal_Int32 ZipFile::readCEN()
aEntries.reserve(nTotal);
sal_Int64 nCount;
+ std::vector<sal_Int8> aTempNameBuffer;
+ std::vector<sal_Int8> aTempExtraBuffer;
for (nCount = 0 ; nCount < nTotal; nCount++)
{
sal_Int32 nTestSig = aMemGrabber.ReadInt32();
@@ -1420,7 +1433,7 @@ sal_Int32 ZipFile::readCEN()
// unfortunately readLOC is required now to check the consistency
assert(aEntry.nOffset <= 0);
sal_uInt64 const nStart{ o3tl::make_unsigned(-aEntry.nOffset) };
- sal_uInt64 const nEnd = readLOC(aEntry);
+ sal_uInt64 const nEnd = readLOC_Impl(aEntry, aTempNameBuffer, aTempExtraBuffer);
assert(nStart < nEnd);
for (auto it = unallocated.begin(); ; ++it)
{