source: Vago/Libs/quazip-0.7.2/qztest/testquazipfile.cpp@ 1066

Last change on this file since 1066 was 1050, checked in by s10k, 8 years ago
File size: 20.5 KB
Line 
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP test suite.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see 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
39void 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
62void 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
157void 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
166void 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
196void TestQuaZipFile::atEnd_data()
197{
198 bytesAvailable_data();
199}
200
201void 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
231void TestQuaZipFile::pos_data()
232{
233 bytesAvailable_data();
234}
235
236void 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
266void 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
277void 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
294void 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
332void 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
361void 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
375void 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
424void 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}
Note: See TracBrowser for help on using the repository browser.