Page MenuHomeWildfire Games

D1511.id6600.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D1511.id6600.diff

Index: source/lib/file/archive/archive_zip.cpp
===================================================================
--- source/lib/file/archive/archive_zip.cpp
+++ source/lib/file/archive/archive_zip.cpp
@@ -269,6 +269,11 @@
cd_size = (size_t)read_le32(&m_cd_size);
}
+ off_t getCommentLength() const
+ {
+ return (off_t)read_le16(&m_comment_len);
+ }
+
private:
u32 m_magic;
u16 m_diskNum;
@@ -521,8 +526,29 @@
io::Operation op(*file.get(), buf, scanSize, ofs);
RETURN_STATUS_IF_ERR(io::Run(op));
+ // Scanning for ECDR first assumes no comment exists
+ // (standard case), so ECDR structure exists right at
+ // end of file
+ off_t offsetInBlock = scanSize - sizeof(ECDR);
+ const ECDR* ecdr = NULL;
+
+ for (off_t commentSize = 0;
+ (commentSize <= offsetInBlock) && !ecdr;
+ commentSize++) {
+ const u8 *pECDRTest = buf + offsetInBlock - commentSize;
+ if(*(u32*)pECDRTest == ecdr_magic) {
+ // Signature matches, test whether comment
+ // fills up the whole space following the
+ // ECDR
+ ecdr = (const ECDR *)pECDRTest;
+ if (commentSize != ecdr->getCommentLength())
+ {
+ ecdr = NULL;
+ }
+ }
+ }
+
// look for ECDR in buffer
- const ECDR* ecdr = (const ECDR*)FindRecord(buf, scanSize, buf, ecdr_magic, sizeof(ECDR));
if(!ecdr)
return INFO::CANNOT_HANDLE;
@@ -535,14 +561,9 @@
const size_t maxScanSize = 66000u; // see below
UniqueRange buf(io::Allocate(maxScanSize));
- // expected case: ECDR at EOF; no file comment
- Status ret = ScanForEcdr(file, fileSize, (u8*)buf.get(), sizeof(ECDR), cd_numEntries, cd_ofs, cd_size);
+ Status ret = ScanForEcdr(file, fileSize, (u8*)buf.get(), maxScanSize, cd_numEntries, cd_ofs, cd_size);
if(ret == INFO::OK)
return INFO::OK;
- // worst case: ECDR precedes 64 KiB of file comment
- ret = ScanForEcdr(file, fileSize, (u8*)buf.get(), maxScanSize, cd_numEntries, cd_ofs, cd_size);
- if(ret == INFO::OK)
- return INFO::OK;
// both ECDR scans failed - this is not a valid Zip file.
io::Operation op(*file.get(), buf.get(), sizeof(LFH));
Index: source/lib/file/archive/tests/test_archive_zip.h
===================================================================
--- source/lib/file/archive/tests/test_archive_zip.h
+++ source/lib/file/archive/tests/test_archive_zip.h
@@ -0,0 +1,58 @@
+/* Copyright (C) 2010 Wildfire Games.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <iostream>
+#include "lib/self_test.h"
+#include "lib/file/archive/archive_zip.h"
+
+class TestArchiveZip : public CxxTest::TestSuite
+{
+public:
+ void test_scan_suspiciousZipFile() {
+ resultbuffer = "";
+ PIArchiveReader testee =
+ CreateArchiveReader_Zip(
+ DataDir() / "mods" / "_test.lib" / "test.zip");
+
+ TS_ASSERT(NULL != testee);
+
+ testee->ReadEntries(TestArchiveZip::ArchiveEntryCallback, 0);
+
+ TS_ASSERT_EQUALS("buildzipwithcomment.sh", resultbuffer);
+ // delete testee; <- Not used due to shared_ptr
+ }
+
+private:
+ static std::string resultbuffer;
+
+ static void ArchiveEntryCallback(
+ const VfsPath &path,
+ const CFileInfo &,
+ PIArchiveFile,
+ uintptr_t) {
+ resultbuffer = path.string8();
+ }
+};
+
+// Implementation of the static buffer used to communicate with ArchiveEntryCallback
+std::string TestArchiveZip::resultbuffer;
+

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 2:18 AM (19 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3375199
Default Alt Text
D1511.id6600.diff (4 KB)

Event Timeline