1 | /*
|
---|
2 | Copyright (C) 2005-2014 Sergey A. Tachenov
|
---|
3 |
|
---|
4 | This file is part of QuaZIP test suite.
|
---|
5 |
|
---|
6 | QuaZIP is free software: you can redistribute it and/or modify
|
---|
7 | it under the terms of the GNU Lesser General Public License as published by
|
---|
8 | the Free Software Foundation, either version 2.1 of the License, or
|
---|
9 | (at your option) any later version.
|
---|
10 |
|
---|
11 | QuaZIP is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU Lesser General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU Lesser General Public License
|
---|
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
|
---|
18 |
|
---|
19 | See COPYING file for the full LGPL text.
|
---|
20 |
|
---|
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
|
---|
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "testquazipfile.h"
|
---|
26 |
|
---|
27 | #include "qztest.h"
|
---|
28 |
|
---|
29 | #include <quazip/JlCompress.h>
|
---|
30 | #include <quazip/quazipfile.h>
|
---|
31 | #include <quazip/quazip.h>
|
---|
32 |
|
---|
33 | #include <QFile>
|
---|
34 | #include <QString>
|
---|
35 | #include <QStringList>
|
---|
36 |
|
---|
37 | #include <QtTest/QtTest>
|
---|
38 |
|
---|
39 | void TestQuaZipFile::zipUnzip_data()
|
---|
40 | {
|
---|
41 | QTest::addColumn<QString>("zipName");
|
---|
42 | QTest::addColumn<QStringList>("fileNames");
|
---|
43 | QTest::addColumn<QByteArray>("fileNameCodec");
|
---|
44 | QTest::addColumn<QByteArray>("password");
|
---|
45 | QTest::addColumn<bool>("zip64");
|
---|
46 | QTest::newRow("simple") << "simple.zip" << (
|
---|
47 | QStringList() << "test0.txt" << "testdir1/test1.txt"
|
---|
48 | << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt")
|
---|
49 | << QByteArray() << QByteArray() << false;
|
---|
50 | QTest::newRow("Cyrillic") << "cyrillic.zip" << (
|
---|
51 | QStringList()
|
---|
52 | << QString::fromUtf8("русское имя файла с пробелами.txt"))
|
---|
53 | << QByteArray("IBM866") << QByteArray() << false;
|
---|
54 | QTest::newRow("password") << "password.zip" << (
|
---|
55 | QStringList() << "test.txt")
|
---|
56 | << QByteArray() << QByteArray("PassPass") << false;
|
---|
57 | QTest::newRow("zip64") << "zip64.zip" << (
|
---|
58 | QStringList() << "test64.txt")
|
---|
59 | << QByteArray() << QByteArray() << true;
|
---|
60 | }
|
---|
61 |
|
---|
62 | void TestQuaZipFile::zipUnzip()
|
---|
63 | {
|
---|
64 | QFETCH(QString, zipName);
|
---|
65 | QFETCH(QStringList, fileNames);
|
---|
66 | QFETCH(QByteArray, fileNameCodec);
|
---|
67 | QFETCH(QByteArray, password);
|
---|
68 | QFETCH(bool, zip64);
|
---|
69 | QFile testFile(zipName);
|
---|
70 | if (testFile.exists()) {
|
---|
71 | if (!testFile.remove()) {
|
---|
72 | QFAIL("Couldn't remove existing archive to create a new one");
|
---|
73 | }
|
---|
74 | }
|
---|
75 | if (!createTestFiles(fileNames)) {
|
---|
76 | QFAIL("Couldn't create test files for zipping");
|
---|
77 | }
|
---|
78 | QuaZip testZip(&testFile);
|
---|
79 | testZip.setZip64Enabled(zip64);
|
---|
80 | if (!fileNameCodec.isEmpty())
|
---|
81 | testZip.setFileNameCodec(fileNameCodec);
|
---|
82 | QVERIFY(testZip.open(QuaZip::mdCreate));
|
---|
83 | QString comment = "Test comment";
|
---|
84 | testZip.setComment(comment);
|
---|
85 | foreach (QString fileName, fileNames) {
|
---|
86 | QFile inFile("tmp/" + fileName);
|
---|
87 | if (!inFile.open(QIODevice::ReadOnly)) {
|
---|
88 | qDebug("File name: %s", fileName.toUtf8().constData());
|
---|
89 | QFAIL("Couldn't open input file");
|
---|
90 | }
|
---|
91 | QuaZipFile outFile(&testZip);
|
---|
92 | QVERIFY(outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName,
|
---|
93 | inFile.fileName()),
|
---|
94 | password.isEmpty() ? NULL : password.constData()));
|
---|
95 | for (qint64 pos = 0, len = inFile.size(); pos < len; ) {
|
---|
96 | char buf[4096];
|
---|
97 | qint64 readSize = qMin(static_cast<qint64>(4096), len - pos);
|
---|
98 | qint64 l;
|
---|
99 | if ((l = inFile.read(buf, readSize)) != readSize) {
|
---|
100 | qDebug("Reading %ld bytes from %s at %ld returned %ld",
|
---|
101 | static_cast<long>(readSize),
|
---|
102 | fileName.toUtf8().constData(),
|
---|
103 | static_cast<long>(pos),
|
---|
104 | static_cast<long>(l));
|
---|
105 | QFAIL("Read failure");
|
---|
106 | }
|
---|
107 | QVERIFY(outFile.write(buf, readSize));
|
---|
108 | pos += readSize;
|
---|
109 | }
|
---|
110 | inFile.close();
|
---|
111 | outFile.close();
|
---|
112 | QCOMPARE(outFile.getZipError(), ZIP_OK);
|
---|
113 | }
|
---|
114 | testZip.close();
|
---|
115 | QCOMPARE(testZip.getZipError(), ZIP_OK);
|
---|
116 | // now test unzip
|
---|
117 | QuaZip testUnzip(&testFile);
|
---|
118 | if (!fileNameCodec.isEmpty())
|
---|
119 | testUnzip.setFileNameCodec(fileNameCodec);
|
---|
120 | QVERIFY(testUnzip.open(QuaZip::mdUnzip));
|
---|
121 | QCOMPARE(testUnzip.getComment(), comment);
|
---|
122 | QVERIFY(testUnzip.goToFirstFile());
|
---|
123 | foreach (QString fileName, fileNames) {
|
---|
124 | QuaZipFileInfo64 info;
|
---|
125 | QVERIFY(testUnzip.getCurrentFileInfo(&info));
|
---|
126 | QCOMPARE(info.name, fileName);
|
---|
127 | QCOMPARE(info.isEncrypted(), !password.isEmpty());
|
---|
128 | QFile original("tmp/" + fileName);
|
---|
129 | QVERIFY(original.open(QIODevice::ReadOnly));
|
---|
130 | QuaZipFile archived(&testUnzip);
|
---|
131 | QVERIFY(archived.open(QIODevice::ReadOnly,
|
---|
132 | password.isEmpty() ? NULL : password.constData()));
|
---|
133 | QByteArray originalData = original.readAll();
|
---|
134 | QByteArray archivedData = archived.readAll();
|
---|
135 | QCOMPARE(archivedData, originalData);
|
---|
136 | testUnzip.goToNextFile();
|
---|
137 | }
|
---|
138 | if (!password.isEmpty()) {
|
---|
139 | QVERIFY(testUnzip.goToFirstFile());
|
---|
140 | QuaZipFileInfo64 info;
|
---|
141 | QVERIFY(testUnzip.getCurrentFileInfo(&info));
|
---|
142 | QFile original("tmp/" + info.name);
|
---|
143 | QVERIFY(original.open(QIODevice::ReadOnly));
|
---|
144 | QuaZipFile archived(&testUnzip);
|
---|
145 | QVERIFY(archived.open(QIODevice::ReadOnly, "WrongPassword"));
|
---|
146 | QByteArray originalData = original.readAll();
|
---|
147 | QByteArray archivedData = archived.readAll();
|
---|
148 | QVERIFY(archivedData != originalData);
|
---|
149 | }
|
---|
150 | testUnzip.close();
|
---|
151 | QCOMPARE(testUnzip.getZipError(), UNZ_OK);
|
---|
152 | // clean up
|
---|
153 | removeTestFiles(fileNames);
|
---|
154 | testFile.remove();
|
---|
155 | }
|
---|
156 |
|
---|
157 | void TestQuaZipFile::bytesAvailable_data()
|
---|
158 | {
|
---|
159 | QTest::addColumn<QString>("zipName");
|
---|
160 | QTest::addColumn<QStringList>("fileNames");
|
---|
161 | QTest::newRow("simple") << "test.zip" << (
|
---|
162 | QStringList() << "test0.txt" << "testdir1/test1.txt"
|
---|
163 | << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt");
|
---|
164 | }
|
---|
165 |
|
---|
166 | void TestQuaZipFile::bytesAvailable()
|
---|
167 | {
|
---|
168 | QFETCH(QString, zipName);
|
---|
169 | QFETCH(QStringList, fileNames);
|
---|
170 | QDir curDir;
|
---|
171 | if (!createTestFiles(fileNames)) {
|
---|
172 | QFAIL("Couldn't create test files");
|
---|
173 | }
|
---|
174 | if (!JlCompress::compressDir(zipName, "tmp")) {
|
---|
175 | QFAIL("Couldn't create test archive");
|
---|
176 | }
|
---|
177 | QuaZip testZip(zipName);
|
---|
178 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
179 | foreach (QString fileName, fileNames) {
|
---|
180 | QFileInfo fileInfo("tmp/" + fileName);
|
---|
181 | QVERIFY(testZip.setCurrentFile(fileName));
|
---|
182 | QuaZipFile zipFile(&testZip);
|
---|
183 | QVERIFY(zipFile.open(QIODevice::ReadOnly));
|
---|
184 | QCOMPARE(zipFile.bytesAvailable(), fileInfo.size());
|
---|
185 | QCOMPARE(zipFile.read(1).size(), 1);
|
---|
186 | QCOMPARE(zipFile.bytesAvailable(), fileInfo.size() - 1);
|
---|
187 | QCOMPARE(zipFile.read(fileInfo.size() - 1).size(),
|
---|
188 | static_cast<int>(fileInfo.size() - 1));
|
---|
189 | QCOMPARE(zipFile.bytesAvailable(), (qint64) 0);
|
---|
190 | }
|
---|
191 | removeTestFiles(fileNames);
|
---|
192 | testZip.close();
|
---|
193 | curDir.remove(zipName);
|
---|
194 | }
|
---|
195 |
|
---|
196 | void TestQuaZipFile::atEnd_data()
|
---|
197 | {
|
---|
198 | bytesAvailable_data();
|
---|
199 | }
|
---|
200 |
|
---|
201 | void TestQuaZipFile::atEnd()
|
---|
202 | {
|
---|
203 | QFETCH(QString, zipName);
|
---|
204 | QFETCH(QStringList, fileNames);
|
---|
205 | QDir curDir;
|
---|
206 | if (!createTestFiles(fileNames)) {
|
---|
207 | QFAIL("Couldn't create test files");
|
---|
208 | }
|
---|
209 | if (!JlCompress::compressDir(zipName, "tmp")) {
|
---|
210 | QFAIL("Couldn't create test archive");
|
---|
211 | }
|
---|
212 | QuaZip testZip(zipName);
|
---|
213 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
214 | foreach (QString fileName, fileNames) {
|
---|
215 | QFileInfo fileInfo("tmp/" + fileName);
|
---|
216 | QVERIFY(testZip.setCurrentFile(fileName));
|
---|
217 | QuaZipFile zipFile(&testZip);
|
---|
218 | QVERIFY(zipFile.open(QIODevice::ReadOnly));
|
---|
219 | QCOMPARE(zipFile.atEnd(), false);
|
---|
220 | QCOMPARE(zipFile.read(1).size(), 1);
|
---|
221 | QCOMPARE(zipFile.atEnd(), false);
|
---|
222 | QCOMPARE(zipFile.read(fileInfo.size() - 1).size(),
|
---|
223 | static_cast<int>(fileInfo.size() - 1));
|
---|
224 | QCOMPARE(zipFile.atEnd(), true);
|
---|
225 | }
|
---|
226 | removeTestFiles(fileNames);
|
---|
227 | testZip.close();
|
---|
228 | curDir.remove(zipName);
|
---|
229 | }
|
---|
230 |
|
---|
231 | void TestQuaZipFile::pos_data()
|
---|
232 | {
|
---|
233 | bytesAvailable_data();
|
---|
234 | }
|
---|
235 |
|
---|
236 | void TestQuaZipFile::pos()
|
---|
237 | {
|
---|
238 | QFETCH(QString, zipName);
|
---|
239 | QFETCH(QStringList, fileNames);
|
---|
240 | QDir curDir;
|
---|
241 | if (!createTestFiles(fileNames)) {
|
---|
242 | QFAIL("Couldn't create test files");
|
---|
243 | }
|
---|
244 | if (!JlCompress::compressDir(zipName, "tmp")) {
|
---|
245 | QFAIL("Couldn't create test archive");
|
---|
246 | }
|
---|
247 | QuaZip testZip(zipName);
|
---|
248 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
249 | foreach (QString fileName, fileNames) {
|
---|
250 | QFileInfo fileInfo("tmp/" + fileName);
|
---|
251 | QVERIFY(testZip.setCurrentFile(fileName));
|
---|
252 | QuaZipFile zipFile(&testZip);
|
---|
253 | QVERIFY(zipFile.open(QIODevice::ReadOnly));
|
---|
254 | QCOMPARE(zipFile.pos(), (qint64) 0);
|
---|
255 | QCOMPARE(zipFile.read(1).size(), 1);
|
---|
256 | QCOMPARE(zipFile.pos(), (qint64) 1);
|
---|
257 | QCOMPARE(zipFile.read(fileInfo.size() - 1).size(),
|
---|
258 | static_cast<int>(fileInfo.size() - 1));
|
---|
259 | QCOMPARE(zipFile.pos(), fileInfo.size());
|
---|
260 | }
|
---|
261 | removeTestFiles(fileNames);
|
---|
262 | testZip.close();
|
---|
263 | curDir.remove(zipName);
|
---|
264 | }
|
---|
265 |
|
---|
266 | void TestQuaZipFile::getZip()
|
---|
267 | {
|
---|
268 | QuaZip testZip;
|
---|
269 | QuaZipFile f1(&testZip);
|
---|
270 | QCOMPARE(f1.getZip(), &testZip);
|
---|
271 | QuaZipFile f2("doesntexist.zip", "someFile");
|
---|
272 | QCOMPARE(f2.getZip(), static_cast<QuaZip*>(NULL));
|
---|
273 | f2.setZip(&testZip);
|
---|
274 | QCOMPARE(f2.getZip(), &testZip);
|
---|
275 | }
|
---|
276 |
|
---|
277 | void TestQuaZipFile::setZipName()
|
---|
278 | {
|
---|
279 | QString testFileName = "testZipName.txt";
|
---|
280 | QString testZipName = "testZipName.zip";
|
---|
281 | QVERIFY(createTestFiles(QStringList() << testFileName));
|
---|
282 | QVERIFY(createTestArchive(testZipName, QStringList() << testFileName));
|
---|
283 | QuaZipFile testFile;
|
---|
284 | testFile.setZipName(testZipName);
|
---|
285 | QCOMPARE(testFile.getZipName(), testZipName);
|
---|
286 | testFile.setFileName(testFileName);
|
---|
287 | QVERIFY(testFile.open(QIODevice::ReadOnly));
|
---|
288 | testFile.close();
|
---|
289 | removeTestFiles(QStringList() << testFileName);
|
---|
290 | QDir curDir;
|
---|
291 | curDir.remove(testZipName);
|
---|
292 | }
|
---|
293 |
|
---|
294 | void TestQuaZipFile::getFileInfo()
|
---|
295 | {
|
---|
296 | QuaZipFileInfo info32;
|
---|
297 | QuaZipFileInfo64 info64;
|
---|
298 | QString testFileName = "testZipName.txt";
|
---|
299 | QStringList testFiles;
|
---|
300 | testFiles << testFileName;
|
---|
301 | QString testZipName = "testZipName.zip";
|
---|
302 | QVERIFY(createTestFiles(testFiles));
|
---|
303 | QVERIFY(createTestArchive(testZipName, testFiles));
|
---|
304 | QuaZipFile testFile;
|
---|
305 | testFile.setZipName(testZipName);
|
---|
306 | testFile.setFileName(testFileName);
|
---|
307 | QVERIFY(testFile.open(QIODevice::ReadOnly));
|
---|
308 | QVERIFY(testFile.getFileInfo(&info32));
|
---|
309 | QVERIFY(testFile.getFileInfo(&info64));
|
---|
310 | QCOMPARE(info32.name, info64.name);
|
---|
311 | QCOMPARE(info32.versionCreated, info64.versionCreated);
|
---|
312 | QCOMPARE(info32.versionNeeded, info64.versionNeeded);
|
---|
313 | QCOMPARE(info32.flags, info64.flags);
|
---|
314 | QCOMPARE(info32.method, info64.method);
|
---|
315 | QCOMPARE(info32.dateTime, info64.dateTime);
|
---|
316 | QCOMPARE(info32.crc, info64.crc);
|
---|
317 | QCOMPARE(info32.compressedSize,
|
---|
318 | static_cast<quint32>(info64.compressedSize));
|
---|
319 | QCOMPARE(info32.uncompressedSize,
|
---|
320 | static_cast<quint32>(info64.uncompressedSize));
|
---|
321 | QCOMPARE(info32.diskNumberStart, info64.diskNumberStart);
|
---|
322 | QCOMPARE(info32.internalAttr, info64.internalAttr);
|
---|
323 | QCOMPARE(info32.externalAttr, info64.externalAttr);
|
---|
324 | QCOMPARE(info32.comment, info64.comment);
|
---|
325 | QCOMPARE(info32.extra, info64.extra);
|
---|
326 | testFile.close();
|
---|
327 | removeTestFiles(testFiles);
|
---|
328 | QDir curDir;
|
---|
329 | curDir.remove(testZipName);
|
---|
330 | }
|
---|
331 |
|
---|
332 | void TestQuaZipFile::setFileName()
|
---|
333 | {
|
---|
334 | QString testFileName = "testZipName.txt";
|
---|
335 | QString testZipName = "testZipName.zip";
|
---|
336 | QVERIFY(createTestFiles(QStringList() << testFileName));
|
---|
337 | QVERIFY(createTestArchive(testZipName, QStringList() << testFileName));
|
---|
338 | QuaZipFile testFile(testZipName);
|
---|
339 | testFile.setFileName(testFileName.toUpper());
|
---|
340 | #ifdef Q_OS_WIN
|
---|
341 | QVERIFY(testFile.open(QIODevice::ReadOnly));
|
---|
342 | testFile.close();
|
---|
343 | #else
|
---|
344 | QVERIFY(!testFile.open(QIODevice::ReadOnly));
|
---|
345 | #endif
|
---|
346 | testFile.setFileName(testFileName.toUpper(), QuaZip::csInsensitive);
|
---|
347 | QCOMPARE(testFile.getCaseSensitivity(), QuaZip::csInsensitive);
|
---|
348 | QVERIFY(testFile.open(QIODevice::ReadOnly));
|
---|
349 | QCOMPARE(testFile.getActualFileName(), testFileName);
|
---|
350 | testFile.close();
|
---|
351 | testFile.setFileName(testFileName.toUpper(), QuaZip::csSensitive);
|
---|
352 | QCOMPARE(testFile.getFileName(), testFileName.toUpper());
|
---|
353 | QCOMPARE(testFile.getActualFileName(), QString());
|
---|
354 | QVERIFY(!testFile.open(QIODevice::ReadOnly));
|
---|
355 | testFile.setFileName(testFileName);
|
---|
356 | removeTestFiles(QStringList() << testFileName);
|
---|
357 | QDir curDir;
|
---|
358 | curDir.remove(testZipName);
|
---|
359 | }
|
---|
360 |
|
---|
361 | void TestQuaZipFile::constructorDestructor()
|
---|
362 | {
|
---|
363 | // Just test that all constructors and destructors are available.
|
---|
364 | // (So there are none that are declared but not defined.)
|
---|
365 | QuaZip testZip;
|
---|
366 | QuaZipFile *f1 = new QuaZipFile();
|
---|
367 | delete f1; // test D0 destructor
|
---|
368 | QObject parent;
|
---|
369 | QuaZipFile f2(&testZip, &parent);
|
---|
370 | QuaZipFile f3(&parent);
|
---|
371 | QuaZipFile f4("zipName.zip");
|
---|
372 | QuaZipFile f5("zipName.zip", "fileName.txt", QuaZip::csDefault, &parent);
|
---|
373 | }
|
---|
374 |
|
---|
375 | void TestQuaZipFile::setFileAttrs()
|
---|
376 | {
|
---|
377 | QuaZip testZip("setFileAttrs.zip");
|
---|
378 | QVERIFY(testZip.open(QuaZip::mdCreate));
|
---|
379 | QuaZipFile zipFile(&testZip);
|
---|
380 | QuaZipNewInfo newInfo("testPerm.txt");
|
---|
381 | newInfo.setPermissions(QFile::ReadOwner);
|
---|
382 | QVERIFY(zipFile.open(QIODevice::WriteOnly, newInfo));
|
---|
383 | zipFile.close();
|
---|
384 | QString fileTestAttr = "testAttr.txt";
|
---|
385 | QStringList fileNames;
|
---|
386 | fileNames << fileTestAttr;
|
---|
387 | QVERIFY(createTestFiles(fileNames));
|
---|
388 | newInfo.name = fileTestAttr;
|
---|
389 | newInfo.setFileDateTime("tmp/" + fileTestAttr);
|
---|
390 | newInfo.setFilePermissions("tmp/" + fileTestAttr);
|
---|
391 | QVERIFY(zipFile.open(QIODevice::WriteOnly, newInfo));
|
---|
392 | zipFile.close();
|
---|
393 | testZip.close();
|
---|
394 | QuaZipFileInfo64 info;
|
---|
395 | {
|
---|
396 | QuaZipFile readFilePerm("setFileAttrs.zip", "testPerm.txt");
|
---|
397 | QVERIFY(readFilePerm.open(QIODevice::ReadOnly));
|
---|
398 | QVERIFY(readFilePerm.getFileInfo(&info));
|
---|
399 | QCOMPARE(info.getPermissions(), QFile::ReadOwner);
|
---|
400 | readFilePerm.close();
|
---|
401 | }
|
---|
402 | {
|
---|
403 | QuaZipFile readFileAttrs("setFileAttrs.zip", "testAttr.txt");
|
---|
404 | QVERIFY(readFileAttrs.open(QIODevice::ReadOnly));
|
---|
405 | QVERIFY(readFileAttrs.getFileInfo(&info));
|
---|
406 | QFileInfo srcInfo("tmp/" + fileTestAttr);
|
---|
407 | QFile::Permissions usedPermissions =
|
---|
408 | QFile::WriteOwner | QFile::ReadOwner | QFile::ExeOwner |
|
---|
409 | QFile::WriteGroup | QFile::ReadGroup | QFile::ExeGroup |
|
---|
410 | QFile::WriteOther | QFile::ReadOther | QFile::ExeOther;
|
---|
411 | QCOMPARE(info.getPermissions() & usedPermissions,
|
---|
412 | srcInfo.permissions() & usedPermissions);
|
---|
413 | // I really hope Qt 6 will use quint64 for time_t!
|
---|
414 | quint64 newTime = info.dateTime.toTime_t();
|
---|
415 | quint64 oldTime = srcInfo.lastModified().toTime_t();
|
---|
416 | // ZIP uses weird format with 2 second precision
|
---|
417 | QCOMPARE(newTime / 2, oldTime / 2);
|
---|
418 | readFileAttrs.close();
|
---|
419 | }
|
---|
420 | removeTestFiles(fileNames);
|
---|
421 | QDir().remove(testZip.getZipName());
|
---|
422 | }
|
---|
423 |
|
---|
424 | void TestQuaZipFile::largeFile()
|
---|
425 | {
|
---|
426 | QDir curDir;
|
---|
427 | QVERIFY(curDir.mkpath("tmp"));
|
---|
428 | QFile fakeLargeFile("tmp/large.zip");
|
---|
429 | QVERIFY(fakeLargeFile.open(QIODevice::WriteOnly));
|
---|
430 | QDataStream ds(&fakeLargeFile);
|
---|
431 | ds.setByteOrder(QDataStream::LittleEndian);
|
---|
432 | QList<qint64> localOffsets;
|
---|
433 | const int numFiles = 2; // name fixed to 5 bytes, so MAX 10 FILES!!!
|
---|
434 | for (int i = 0; i < numFiles; ++i) {
|
---|
435 | localOffsets.append(fakeLargeFile.pos());
|
---|
436 | QBuffer extra;
|
---|
437 | extra.open(QIODevice::WriteOnly);
|
---|
438 | QDataStream es(&extra);
|
---|
439 | es.setByteOrder(QDataStream::LittleEndian);
|
---|
440 | // prepare extra
|
---|
441 | es << static_cast<quint16>(0x0001u); // zip64
|
---|
442 | es << static_cast<quint16>(16); // extra data size
|
---|
443 | es << static_cast<quint64>(0); // uncompressed size
|
---|
444 | es << static_cast<quint64>(0); // compressed size
|
---|
445 | // now the local header
|
---|
446 | ds << static_cast<quint32>(0x04034b50u); // local magic
|
---|
447 | ds << static_cast<quint16>(45); // version needed
|
---|
448 | ds << static_cast<quint16>(0); // flags
|
---|
449 | ds << static_cast<quint16>(0); // method
|
---|
450 | ds << static_cast<quint16>(0); // time 00:00:00
|
---|
451 | ds << static_cast<quint16>(0x21); // date 1980-01-01
|
---|
452 | ds << static_cast<quint32>(0); // CRC-32
|
---|
453 | ds << static_cast<quint32>(0xFFFFFFFFu); // compressed size
|
---|
454 | ds << static_cast<quint32>(0xFFFFFFFFu); // uncompressed size
|
---|
455 | ds << static_cast<quint16>(5); // name length
|
---|
456 | ds << static_cast<quint16>(extra.size()); // extra length
|
---|
457 | ds.writeRawData("file", 4); // name
|
---|
458 | ds << static_cast<qint8>('0' + i); // name (contd.)
|
---|
459 | ds.writeRawData(extra.buffer(), extra.size());
|
---|
460 | }
|
---|
461 | // central dir:
|
---|
462 | qint64 centralStart = fakeLargeFile.pos();
|
---|
463 | for (int i = 0; i < numFiles; ++i) {
|
---|
464 | QBuffer extra;
|
---|
465 | extra.open(QIODevice::WriteOnly);
|
---|
466 | QDataStream es(&extra);
|
---|
467 | es.setByteOrder(QDataStream::LittleEndian);
|
---|
468 | // prepare extra
|
---|
469 | es << static_cast<quint16>(0x0001u); // zip64
|
---|
470 | es << static_cast<quint16>(24); // extra data size
|
---|
471 | es << static_cast<quint64>(0); // uncompressed size
|
---|
472 | es << static_cast<quint64>(0); // compressed size
|
---|
473 | es << static_cast<quint64>(localOffsets[i]);
|
---|
474 | // now the central dir header
|
---|
475 | ds << static_cast<quint32>(0x02014b50u); // central magic
|
---|
476 | ds << static_cast<quint16>(45); // version made by
|
---|
477 | ds << static_cast<quint16>(45); // version needed
|
---|
478 | ds << static_cast<quint16>(0); // flags
|
---|
479 | ds << static_cast<quint16>(0); // method
|
---|
480 | ds << static_cast<quint16>(0); // time 00:00:00
|
---|
481 | ds << static_cast<quint16>(0x21); // date 1980-01-01
|
---|
482 | ds << static_cast<quint32>(0); // CRC-32
|
---|
483 | ds << static_cast<quint32>(0xFFFFFFFFu); // compressed size
|
---|
484 | ds << static_cast<quint32>(0xFFFFFFFFu); // uncompressed size
|
---|
485 | ds << static_cast<quint16>(5); // name length
|
---|
486 | ds << static_cast<quint16>(extra.size()); // extra length
|
---|
487 | ds << static_cast<quint16>(0); // comment length
|
---|
488 | ds << static_cast<quint16>(0); // disk number
|
---|
489 | ds << static_cast<quint16>(0); // internal attrs
|
---|
490 | ds << static_cast<quint32>(0); // external attrs
|
---|
491 | ds << static_cast<quint32>(0xFFFFFFFFu); // local offset
|
---|
492 | ds.writeRawData("file", 4); // name
|
---|
493 | ds << static_cast<qint8>('0' + i); // name (contd.)
|
---|
494 | ds.writeRawData(extra.buffer(), extra.size());
|
---|
495 | }
|
---|
496 | qint64 centralEnd = fakeLargeFile.pos();
|
---|
497 | // zip64 end
|
---|
498 | ds << static_cast<quint32>(0x06064b50); // zip64 end magic
|
---|
499 | ds << static_cast<quint64>(44); // size of the zip64 end
|
---|
500 | ds << static_cast<quint16>(45); // version made by
|
---|
501 | ds << static_cast<quint16>(45); // version needed
|
---|
502 | ds << static_cast<quint32>(0); // disk number
|
---|
503 | ds << static_cast<quint32>(0); // central dir disk number
|
---|
504 | ds << static_cast<quint64>(2); // number of entries on disk
|
---|
505 | ds << static_cast<quint64>(2); // total number of entries
|
---|
506 | ds << static_cast<quint64>(centralEnd - centralStart); // size
|
---|
507 | ds << static_cast<quint64>(centralStart); // offset
|
---|
508 | // zip64 locator
|
---|
509 | ds << static_cast<quint32>(0x07064b50); // zip64 locator magic
|
---|
510 | ds << static_cast<quint32>(0); // disk number
|
---|
511 | ds << static_cast<quint64>(centralEnd); // offset
|
---|
512 | ds << static_cast<quint32>(1); // number of disks
|
---|
513 | // zip32 end
|
---|
514 | ds << static_cast<quint32>(0x06054b50); // end magic
|
---|
515 | ds << static_cast<quint16>(0); // disk number
|
---|
516 | ds << static_cast<quint16>(0); // central dir disk number
|
---|
517 | ds << static_cast<quint16>(2); // number of entries
|
---|
518 | ds << static_cast<quint32>(0xFFFFFFFFu); // central dir size
|
---|
519 | ds << static_cast<quint32>(0xFFFFFFFFu); // central dir offset
|
---|
520 | ds << static_cast<quint16>(0); // comment length
|
---|
521 | fakeLargeFile.close();
|
---|
522 | QuaZip fakeLargeZip("tmp/large.zip");
|
---|
523 | QVERIFY(fakeLargeZip.open(QuaZip::mdUnzip));
|
---|
524 | QCOMPARE(fakeLargeZip.getFileInfoList().size(), numFiles);
|
---|
525 | QCOMPARE(fakeLargeZip.getFileInfoList()[0].uncompressedSize,
|
---|
526 | static_cast<quint32>(0));
|
---|
527 | fakeLargeZip.close();
|
---|
528 | curDir.remove("tmp/large.zip");
|
---|
529 | }
|
---|