Skip to content

Commit

Permalink
wzmaplib: ZipIOProvider: Support fixedLastMod date for reproducible zips
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due authored and pull[bot] committed Oct 19, 2022
1 parent c1cd2f7 commit 1074267
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
3 changes: 2 additions & 1 deletion lib/wzmaplib/plugins/ZipIOProvider/include/ZipIOProvider.h
Expand Up @@ -37,7 +37,7 @@ class WzMapZipIO : public WzMap::IOProvider
static std::shared_ptr<WzMapZipIO> openZipArchiveFS(const char* fileSystemPath, bool extraConsistencyChecks = false, bool readOnly = false);

// Initialize a new WzMapZipIO provider with a fileSystemPath to a new .zip/.wz archive (to be written)
static std::shared_ptr<WzMapZipIO> createZipArchiveFS(const char* fileSystemPath);
static std::shared_ptr<WzMapZipIO> createZipArchiveFS(const char* fileSystemPath, bool fixedLastMod = false);

~WzMapZipIO();
public:
Expand All @@ -60,6 +60,7 @@ class WzMapZipIO : public WzMap::IOProvider
private:
std::shared_ptr<WrappedZipArchive> m_zipArchive;
std::vector<std::string> m_cachedDirectoriesList;
bool m_fixedLastMod = false;
// for best-effort handling of malformed / non-standard zip archives
optional<bool> m_foundMalformedWindowsPathSeparators;
};
16 changes: 12 additions & 4 deletions lib/wzmaplib/plugins/ZipIOProvider/src/ZipIOProvider.cpp
Expand Up @@ -98,14 +98,15 @@ class WzMapBinaryZipIOStream : public WzMap::BinaryIOStream
return result;
}

static std::unique_ptr<WzMapBinaryZipIOStream> openForWriting(const std::string& filename, std::shared_ptr<WrappedZipArchive> zipArchive)
static std::unique_ptr<WzMapBinaryZipIOStream> openForWriting(const std::string& filename, std::shared_ptr<WrappedZipArchive> zipArchive, bool fixedLastMod = false)
{
if (filename.empty() || zipArchive == nullptr)
{
return nullptr;
}
auto result = std::unique_ptr<WzMapBinaryZipIOStream>(new WzMapBinaryZipIOStream(zipArchive, WzMap::BinaryIOStream::OpenMode::WRITE));
result->m_filename = filename;
result->m_fixedLastMod = fixedLastMod;
return result;
}

Expand Down Expand Up @@ -209,6 +210,11 @@ class WzMapBinaryZipIOStream : public WzMap::BinaryIOStream
m_filename.clear();
return false;
}
if (m_fixedLastMod)
{
// Use Jan 1, 1980 + 12 hours and 1 minute to avoid time zone weirdness (matching "strip-nondeterminism" script behavior)
zip_file_set_dostime(m_zipArchive->handle(), static_cast<zip_uint64_t>(result), 0x6020, 0x21, 0);
}
m_filename.clear();
}
return true;
Expand Down Expand Up @@ -248,6 +254,7 @@ class WzMapBinaryZipIOStream : public WzMap::BinaryIOStream
unsigned char* m_writeBuffer = nullptr;
size_t m_writeBufferLen = 0;
size_t m_writeBufferCapacity = 0;
bool m_fixedLastMod = false;
};

static zip_int64_t wz_zip_name_locate_impl(zip_t *archive, const char *fname, zip_flags_t flags, bool useWindowsPathWorkaroundIfNeeded)
Expand Down Expand Up @@ -318,7 +325,7 @@ std::shared_ptr<WzMapZipIO> WzMapZipIO::openZipArchiveFS(const char* fileSystemP
return result;
}

std::shared_ptr<WzMapZipIO> WzMapZipIO::createZipArchiveFS(const char* fileSystemPath)
std::shared_ptr<WzMapZipIO> WzMapZipIO::createZipArchiveFS(const char* fileSystemPath, bool fixedLastMod /*= false*/)
{
if (fileSystemPath == nullptr) { return nullptr; }
if (*fileSystemPath == '\0') { return nullptr; }
Expand Down Expand Up @@ -393,6 +400,7 @@ std::shared_ptr<WzMapZipIO> WzMapZipIO::createZipArchiveFS(const char* fileSyste
return;
}
});
result->m_fixedLastMod = fixedLastMod;
return result;
}

Expand All @@ -417,7 +425,7 @@ std::unique_ptr<WzMap::BinaryIOStream> WzMapZipIO::openBinaryStream(const std::s
break;
}
case WzMap::BinaryIOStream::OpenMode::WRITE:
pStream = WzMapBinaryZipIOStream::openForWriting(filename, m_zipArchive);
pStream = WzMapBinaryZipIOStream::openForWriting(filename, m_zipArchive, m_fixedLastMod);
break;
}
return pStream;
Expand Down Expand Up @@ -476,7 +484,7 @@ bool WzMapZipIO::loadFullFile(const std::string& filename, std::vector<char>& fi

bool WzMapZipIO::writeFullFile(const std::string& filename, const char *ppFileData, uint32_t fileSize)
{
auto writeStream = WzMapBinaryZipIOStream::openForWriting(filename, m_zipArchive);
auto writeStream = WzMapBinaryZipIOStream::openForWriting(filename, m_zipArchive, m_fixedLastMod);
if (!writeStream)
{
return false;
Expand Down

0 comments on commit 1074267

Please sign in to comment.