qzip.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/text/qzip.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include <qglobal.h>-
35-
36#ifndef QT_NO_TEXTODFWRITER-
37-
38#include "qzipreader_p.h"-
39#include "qzipwriter_p.h"-
40#include <qdatetime.h>-
41#include <qendian.h>-
42#include <qdebug.h>-
43#include <qdir.h>-
44-
45#include <zlib.h>-
46-
47// Zip standard version for archives handled by this API-
48// (actually, the only basic support of this version is implemented but it is enough for now)-
49#define ZIP_VERSION 20-
50-
51#if 0-
52#define ZDEBUG qDebug-
53#else-
54#define ZDEBUG if (0) qDebug-
55#endif-
56-
57QT_BEGIN_NAMESPACE-
58-
59static inline uint readUInt(const uchar *data)-
60{-
61 return (data[0]) + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
never executed: return (data[0]) + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
0
62}-
63-
64static inline ushort readUShort(const uchar *data)-
65{-
66 return (data[0]) + (data[1]<<8);
never executed: return (data[0]) + (data[1]<<8);
0
67}-
68-
69static inline void writeUInt(uchar *data, uint i)-
70{-
71 data[0] = i & 0xff;-
72 data[1] = (i>>8) & 0xff;-
73 data[2] = (i>>16) & 0xff;-
74 data[3] = (i>>24) & 0xff;-
75}
never executed: end of block
0
76-
77static inline void writeUShort(uchar *data, ushort i)-
78{-
79 data[0] = i & 0xff;-
80 data[1] = (i>>8) & 0xff;-
81}
never executed: end of block
0
82-
83static inline void copyUInt(uchar *dest, const uchar *src)-
84{-
85 dest[0] = src[0];-
86 dest[1] = src[1];-
87 dest[2] = src[2];-
88 dest[3] = src[3];-
89}
never executed: end of block
0
90-
91static inline void copyUShort(uchar *dest, const uchar *src)-
92{-
93 dest[0] = src[0];-
94 dest[1] = src[1];-
95}
never executed: end of block
0
96-
97static void writeMSDosDate(uchar *dest, const QDateTime& dt)-
98{-
99 if (dt.isValid()) {
dt.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
100 quint16 time =-
101 (dt.time().hour() << 11) // 5 bit hour-
102 | (dt.time().minute() << 5) // 6 bit minute-
103 | (dt.time().second() >> 1); // 5 bit double seconds-
104-
105 dest[0] = time & 0xff;-
106 dest[1] = time >> 8;-
107-
108 quint16 date =-
109 ((dt.date().year() - 1980) << 9) // 7 bit year 1980-based-
110 | (dt.date().month() << 5) // 4 bit month-
111 | (dt.date().day()); // 5 bit day-
112-
113 dest[2] = char(date);-
114 dest[3] = char(date >> 8);-
115 } else {
never executed: end of block
0
116 dest[0] = 0;-
117 dest[1] = 0;-
118 dest[2] = 0;-
119 dest[3] = 0;-
120 }
never executed: end of block
0
121}-
122-
123static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)-
124{-
125 z_stream stream;-
126 int err;-
127-
128 stream.next_in = const_cast<Bytef*>(source);-
129 stream.avail_in = (uInt)sourceLen;-
130 if ((uLong)stream.avail_in != sourceLen)
(uLong)stream....n != sourceLenDescription
TRUEnever evaluated
FALSEnever evaluated
0
131 return Z_BUF_ERROR;
never executed: return (-5);
0
132-
133 stream.next_out = dest;-
134 stream.avail_out = (uInt)*destLen;-
135 if ((uLong)stream.avail_out != *destLen)
(uLong)stream....ut != *destLenDescription
TRUEnever evaluated
FALSEnever evaluated
0
136 return Z_BUF_ERROR;
never executed: return (-5);
0
137-
138 stream.zalloc = (alloc_func)0;-
139 stream.zfree = (free_func)0;-
140-
141 err = inflateInit2(&stream, -MAX_WBITS);-
142 if (err != Z_OK)
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
143 return err;
never executed: return err;
0
144-
145 err = inflate(&stream, Z_FINISH);-
146 if (err != Z_STREAM_END) {
err != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
147 inflateEnd(&stream);-
148 if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
err == 2Description
TRUEnever evaluated
FALSEnever evaluated
err == (-5)Description
TRUEnever evaluated
FALSEnever evaluated
stream.avail_in == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
149 return Z_DATA_ERROR;
never executed: return (-3);
0
150 return err;
never executed: return err;
0
151 }-
152 *destLen = stream.total_out;-
153-
154 err = inflateEnd(&stream);-
155 return err;
never executed: return err;
0
156}-
157-
158static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)-
159{-
160 z_stream stream;-
161 int err;-
162-
163 stream.next_in = const_cast<Bytef*>(source);-
164 stream.avail_in = (uInt)sourceLen;-
165 stream.next_out = dest;-
166 stream.avail_out = (uInt)*destLen;-
167 if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
never executed: return (-5);
(uLong)stream....ut != *destLenDescription
TRUEnever evaluated
FALSEnever evaluated
0
168-
169 stream.zalloc = (alloc_func)0;-
170 stream.zfree = (free_func)0;-
171 stream.opaque = (voidpf)0;-
172-
173 err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);-
174 if (err != Z_OK) return err;
never executed: return err;
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
175-
176 err = deflate(&stream, Z_FINISH);-
177 if (err != Z_STREAM_END) {
err != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
178 deflateEnd(&stream);-
179 return err == Z_OK ? Z_BUF_ERROR : err;
never executed: return err == 0 ? (-5) : err;
err == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
180 }-
181 *destLen = stream.total_out;-
182-
183 err = deflateEnd(&stream);-
184 return err;
never executed: return err;
0
185}-
186-
187-
188namespace WindowsFileAttributes {-
189enum {-
190 Dir = 0x10, // FILE_ATTRIBUTE_DIRECTORY-
191 File = 0x80, // FILE_ATTRIBUTE_NORMAL-
192 TypeMask = 0x90,-
193-
194 ReadOnly = 0x01, // FILE_ATTRIBUTE_READONLY-
195 PermMask = 0x01-
196};-
197}-
198-
199namespace UnixFileAttributes {-
200enum {-
201 Dir = 0040000, // __S_IFDIR-
202 File = 0100000, // __S_IFREG-
203 SymLink = 0120000, // __S_IFLNK-
204 TypeMask = 0170000, // __S_IFMT-
205-
206 ReadUser = 0400, // __S_IRUSR-
207 WriteUser = 0200, // __S_IWUSR-
208 ExeUser = 0100, // __S_IXUSR-
209 ReadGroup = 0040, // __S_IRGRP-
210 WriteGroup = 0020, // __S_IWGRP-
211 ExeGroup = 0010, // __S_IXGRP-
212 ReadOther = 0004, // __S_IROTH-
213 WriteOther = 0002, // __S_IWOTH-
214 ExeOther = 0001, // __S_IXOTH-
215 PermMask = 0777-
216};-
217}-
218-
219static QFile::Permissions modeToPermissions(quint32 mode)-
220{-
221 QFile::Permissions ret;-
222 if (mode & UnixFileAttributes::ReadUser)
mode & UnixFil...utes::ReadUserDescription
TRUEnever evaluated
FALSEnever evaluated
0
223 ret |= QFile::ReadOwner | QFile::ReadUser;
never executed: ret |= QFile::ReadOwner | QFile::ReadUser;
0
224 if (mode & UnixFileAttributes::WriteUser)
mode & UnixFil...tes::WriteUserDescription
TRUEnever evaluated
FALSEnever evaluated
0
225 ret |= QFile::WriteOwner | QFile::WriteUser;
never executed: ret |= QFile::WriteOwner | QFile::WriteUser;
0
226 if (mode & UnixFileAttributes::ExeUser)
mode & UnixFil...butes::ExeUserDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 ret |= QFile::ExeOwner | QFile::ExeUser;
never executed: ret |= QFile::ExeOwner | QFile::ExeUser;
0
228 if (mode & UnixFileAttributes::ReadGroup)
mode & UnixFil...tes::ReadGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
229 ret |= QFile::ReadGroup;
never executed: ret |= QFile::ReadGroup;
0
230 if (mode & UnixFileAttributes::WriteGroup)
mode & UnixFil...es::WriteGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
231 ret |= QFile::WriteGroup;
never executed: ret |= QFile::WriteGroup;
0
232 if (mode & UnixFileAttributes::ExeGroup)
mode & UnixFil...utes::ExeGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
233 ret |= QFile::ExeGroup;
never executed: ret |= QFile::ExeGroup;
0
234 if (mode & UnixFileAttributes::ReadOther)
mode & UnixFil...tes::ReadOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
235 ret |= QFile::ReadOther;
never executed: ret |= QFile::ReadOther;
0
236 if (mode & UnixFileAttributes::WriteOther)
mode & UnixFil...es::WriteOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
237 ret |= QFile::WriteOther;
never executed: ret |= QFile::WriteOther;
0
238 if (mode & UnixFileAttributes::ExeOther)
mode & UnixFil...utes::ExeOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
239 ret |= QFile::ExeOther;
never executed: ret |= QFile::ExeOther;
0
240 return ret;
never executed: return ret;
0
241}-
242-
243static quint32 permissionsToMode(QFile::Permissions perms)-
244{-
245 quint32 mode = 0;-
246 if (perms & (QFile::ReadOwner | QFile::ReadUser))
perms & (QFile...ile::ReadUser)Description
TRUEnever evaluated
FALSEnever evaluated
0
247 mode |= UnixFileAttributes::ReadUser;
never executed: mode |= UnixFileAttributes::ReadUser;
0
248 if (perms & (QFile::WriteOwner | QFile::WriteUser))
perms & (QFile...le::WriteUser)Description
TRUEnever evaluated
FALSEnever evaluated
0
249 mode |= UnixFileAttributes::WriteUser;
never executed: mode |= UnixFileAttributes::WriteUser;
0
250 if (perms & (QFile::ExeOwner | QFile::ExeUser))
perms & (QFile...File::ExeUser)Description
TRUEnever evaluated
FALSEnever evaluated
0
251 mode |= UnixFileAttributes::WriteUser;
never executed: mode |= UnixFileAttributes::WriteUser;
0
252 if (perms & QFile::ReadGroup)
perms & QFile::ReadGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
253 mode |= UnixFileAttributes::ReadGroup;
never executed: mode |= UnixFileAttributes::ReadGroup;
0
254 if (perms & QFile::WriteGroup)
perms & QFile::WriteGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
255 mode |= UnixFileAttributes::WriteGroup;
never executed: mode |= UnixFileAttributes::WriteGroup;
0
256 if (perms & QFile::ExeGroup)
perms & QFile::ExeGroupDescription
TRUEnever evaluated
FALSEnever evaluated
0
257 mode |= UnixFileAttributes::ExeGroup;
never executed: mode |= UnixFileAttributes::ExeGroup;
0
258 if (perms & QFile::ReadOther)
perms & QFile::ReadOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
259 mode |= UnixFileAttributes::ReadOther;
never executed: mode |= UnixFileAttributes::ReadOther;
0
260 if (perms & QFile::WriteOther)
perms & QFile::WriteOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
261 mode |= UnixFileAttributes::WriteOther;
never executed: mode |= UnixFileAttributes::WriteOther;
0
262 if (perms & QFile::ExeOther)
perms & QFile::ExeOtherDescription
TRUEnever evaluated
FALSEnever evaluated
0
263 mode |= UnixFileAttributes::ExeOther;
never executed: mode |= UnixFileAttributes::ExeOther;
0
264 return mode;
never executed: return mode;
0
265}-
266-
267static QDateTime readMSDosDate(const uchar *src)-
268{-
269 uint dosDate = readUInt(src);-
270 quint64 uDate;-
271 uDate = (quint64)(dosDate >> 16);-
272 uint tm_mday = (uDate & 0x1f);-
273 uint tm_mon = ((uDate & 0x1E0) >> 5);-
274 uint tm_year = (((uDate & 0x0FE00) >> 9) + 1980);-
275 uint tm_hour = ((dosDate & 0xF800) >> 11);-
276 uint tm_min = ((dosDate & 0x7E0) >> 5);-
277 uint tm_sec = ((dosDate & 0x1f) << 1);-
278-
279 return QDateTime(QDate(tm_year, tm_mon, tm_mday), QTime(tm_hour, tm_min, tm_sec));
never executed: return QDateTime(QDate(tm_year, tm_mon, tm_mday), QTime(tm_hour, tm_min, tm_sec));
0
280}-
281-
282// for details, see http://www.pkware.com/documents/casestudies/APPNOTE.TXT-
283-
284enum HostOS {-
285 HostFAT = 0,-
286 HostAMIGA = 1,-
287 HostVMS = 2, // VAX/VMS-
288 HostUnix = 3,-
289 HostVM_CMS = 4,-
290 HostAtari = 5, // what if it's a minix filesystem? [cjh]-
291 HostHPFS = 6, // filesystem used by OS/2 (and NT 3.x)-
292 HostMac = 7,-
293 HostZ_System = 8,-
294 HostCPM = 9,-
295 HostTOPS20 = 10, // pkzip 2.50 NTFS-
296 HostNTFS = 11, // filesystem used by Windows NT-
297 HostQDOS = 12, // SMS/QDOS-
298 HostAcorn = 13, // Archimedes Acorn RISC OS-
299 HostVFAT = 14, // filesystem used by Windows 95, NT-
300 HostMVS = 15,-
301 HostBeOS = 16, // hybrid POSIX/database filesystem-
302 HostTandem = 17,-
303 HostOS400 = 18,-
304 HostOSX = 19-
305};-
306Q_DECLARE_TYPEINFO(HostOS, Q_PRIMITIVE_TYPE);-
307-
308enum GeneralPurposeFlag {-
309 Encrypted = 0x01,-
310 AlgTune1 = 0x02,-
311 AlgTune2 = 0x04,-
312 HasDataDescriptor = 0x08,-
313 PatchedData = 0x20,-
314 StrongEncrypted = 0x40,-
315 Utf8Names = 0x0800,-
316 CentralDirectoryEncrypted = 0x2000-
317};-
318Q_DECLARE_TYPEINFO(GeneralPurposeFlag, Q_PRIMITIVE_TYPE);-
319-
320enum CompressionMethod {-
321 CompressionMethodStored = 0,-
322 CompressionMethodShrunk = 1,-
323 CompressionMethodReduced1 = 2,-
324 CompressionMethodReduced2 = 3,-
325 CompressionMethodReduced3 = 4,-
326 CompressionMethodReduced4 = 5,-
327 CompressionMethodImploded = 6,-
328 CompressionMethodReservedTokenizing = 7, // reserved for tokenizing-
329 CompressionMethodDeflated = 8,-
330 CompressionMethodDeflated64 = 9,-
331 CompressionMethodPKImploding = 10,-
332-
333 CompressionMethodBZip2 = 12,-
334-
335 CompressionMethodLZMA = 14,-
336-
337 CompressionMethodTerse = 18,-
338 CompressionMethodLz77 = 19,-
339-
340 CompressionMethodJpeg = 96,-
341 CompressionMethodWavPack = 97,-
342 CompressionMethodPPMd = 98,-
343 CompressionMethodWzAES = 99-
344};-
345Q_DECLARE_TYPEINFO(CompressionMethod, Q_PRIMITIVE_TYPE);-
346-
347struct LocalFileHeader-
348{-
349 uchar signature[4]; // 0x04034b50-
350 uchar version_needed[2];-
351 uchar general_purpose_bits[2];-
352 uchar compression_method[2];-
353 uchar last_mod_file[4];-
354 uchar crc_32[4];-
355 uchar compressed_size[4];-
356 uchar uncompressed_size[4];-
357 uchar file_name_length[2];-
358 uchar extra_field_length[2];-
359};-
360Q_DECLARE_TYPEINFO(LocalFileHeader, Q_PRIMITIVE_TYPE);-
361-
362struct DataDescriptor-
363{-
364 uchar crc_32[4];-
365 uchar compressed_size[4];-
366 uchar uncompressed_size[4];-
367};-
368Q_DECLARE_TYPEINFO(DataDescriptor, Q_PRIMITIVE_TYPE);-
369-
370struct CentralFileHeader-
371{-
372 uchar signature[4]; // 0x02014b50-
373 uchar version_made[2];-
374 uchar version_needed[2];-
375 uchar general_purpose_bits[2];-
376 uchar compression_method[2];-
377 uchar last_mod_file[4];-
378 uchar crc_32[4];-
379 uchar compressed_size[4];-
380 uchar uncompressed_size[4];-
381 uchar file_name_length[2];-
382 uchar extra_field_length[2];-
383 uchar file_comment_length[2];-
384 uchar disk_start[2];-
385 uchar internal_file_attributes[2];-
386 uchar external_file_attributes[4];-
387 uchar offset_local_header[4];-
388 LocalFileHeader toLocalHeader() const;-
389};-
390Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE);-
391-
392struct EndOfDirectory-
393{-
394 uchar signature[4]; // 0x06054b50-
395 uchar this_disk[2];-
396 uchar start_of_directory_disk[2];-
397 uchar num_dir_entries_this_disk[2];-
398 uchar num_dir_entries[2];-
399 uchar directory_size[4];-
400 uchar dir_start_offset[4];-
401 uchar comment_length[2];-
402};-
403Q_DECLARE_TYPEINFO(EndOfDirectory, Q_PRIMITIVE_TYPE);-
404-
405struct FileHeader-
406{-
407 CentralFileHeader h;-
408 QByteArray file_name;-
409 QByteArray extra_field;-
410 QByteArray file_comment;-
411};-
412Q_DECLARE_TYPEINFO(FileHeader, Q_MOVABLE_TYPE);-
413-
414class QZipPrivate-
415{-
416public:-
417 QZipPrivate(QIODevice *device, bool ownDev)-
418 : device(device), ownDevice(ownDev), dirtyFileTree(true), start_of_directory(0)-
419 {-
420 }
never executed: end of block
0
421-
422 ~QZipPrivate()-
423 {-
424 if (ownDevice)
ownDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
425 delete device;
never executed: delete device;
0
426 }
never executed: end of block
0
427-
428 QZipReader::FileInfo fillFileInfo(int index) const;-
429-
430 QIODevice *device;-
431 bool ownDevice;-
432 bool dirtyFileTree;-
433 QVector<FileHeader> fileHeaders;-
434 QByteArray comment;-
435 uint start_of_directory;-
436};-
437-
438QZipReader::FileInfo QZipPrivate::fillFileInfo(int index) const-
439{-
440 QZipReader::FileInfo fileInfo;-
441 FileHeader header = fileHeaders.at(index);-
442 quint32 mode = readUInt(header.h.external_file_attributes);-
443 const HostOS hostOS = HostOS(readUShort(header.h.version_made) >> 8);-
444 switch (hostOS) {-
445 case HostUnix:
never executed: case HostUnix:
0
446 mode = (mode >> 16) & 0xffff;-
447 switch (mode & UnixFileAttributes::TypeMask) {-
448 case UnixFileAttributes::SymLink:
never executed: case UnixFileAttributes::SymLink:
0
449 fileInfo.isSymLink = true;-
450 break;
never executed: break;
0
451 case UnixFileAttributes::Dir:
never executed: case UnixFileAttributes::Dir:
0
452 fileInfo.isDir = true;-
453 break;
never executed: break;
0
454 case UnixFileAttributes::File:
never executed: case UnixFileAttributes::File:
0
455 default: // ### just for the case; should we warn?
never executed: default:
0
456 fileInfo.isFile = true;-
457 break;
never executed: break;
0
458 }-
459 fileInfo.permissions = modeToPermissions(mode);-
460 break;
never executed: break;
0
461 case HostFAT:
never executed: case HostFAT:
0
462 case HostNTFS:
never executed: case HostNTFS:
0
463 case HostHPFS:
never executed: case HostHPFS:
0
464 case HostVFAT:
never executed: case HostVFAT:
0
465 switch (mode & WindowsFileAttributes::TypeMask) {-
466 case WindowsFileAttributes::Dir:
never executed: case WindowsFileAttributes::Dir:
0
467 fileInfo.isDir = true;-
468 break;
never executed: break;
0
469 case WindowsFileAttributes::File:
never executed: case WindowsFileAttributes::File:
0
470 default:
never executed: default:
0
471 fileInfo.isFile = true;-
472 break;
never executed: break;
0
473 }-
474 fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther;-
475 if ((mode & WindowsFileAttributes::ReadOnly) == 0)
(mode & Window...ReadOnly) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
476 fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
never executed: fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
0
477 if (fileInfo.isDir)
fileInfo.isDirDescription
TRUEnever evaluated
FALSEnever evaluated
0
478 fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther;
never executed: fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther;
0
479 break;
never executed: break;
0
480 default:
never executed: default:
0
481 qWarning("QZip: Zip entry format at %d is not supported.", index);-
482 return fileInfo; // we don't support anything else
never executed: return fileInfo;
0
483 }-
484-
485 ushort general_purpose_bits = readUShort(header.h.general_purpose_bits);-
486 // if bit 11 is set, the filename and comment fields must be encoded using UTF-8-
487 const bool inUtf8 = (general_purpose_bits & Utf8Names) != 0;-
488 fileInfo.filePath = inUtf8 ? QString::fromUtf8(header.file_name) : QString::fromLocal8Bit(header.file_name);
inUtf8Description
TRUEnever evaluated
FALSEnever evaluated
0
489 fileInfo.crc = readUInt(header.h.crc_32);-
490 fileInfo.size = readUInt(header.h.uncompressed_size);-
491 fileInfo.lastModified = readMSDosDate(header.h.last_mod_file);-
492-
493 // fix the file path, if broken (convert separators, eat leading and trailing ones)-
494 fileInfo.filePath = QDir::fromNativeSeparators(fileInfo.filePath);-
495 while (!fileInfo.filePath.isEmpty() && (fileInfo.filePath.at(0) == QLatin1Char('.') || fileInfo.filePath.at(0) == QLatin1Char('/')))
!fileInfo.filePath.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
fileInfo.fileP...atin1Char('.')Description
TRUEnever evaluated
FALSEnever evaluated
fileInfo.fileP...atin1Char('/')Description
TRUEnever evaluated
FALSEnever evaluated
0
496 fileInfo.filePath = fileInfo.filePath.mid(1);
never executed: fileInfo.filePath = fileInfo.filePath.mid(1);
0
497 while (!fileInfo.filePath.isEmpty() && fileInfo.filePath.at(fileInfo.filePath.size() - 1) == QLatin1Char('/'))
!fileInfo.filePath.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
fileInfo.fileP...atin1Char('/')Description
TRUEnever evaluated
FALSEnever evaluated
0
498 fileInfo.filePath.chop(1);
never executed: fileInfo.filePath.chop(1);
0
499-
500 return fileInfo;
never executed: return fileInfo;
0
501}-
502-
503class QZipReaderPrivate : public QZipPrivate-
504{-
505public:-
506 QZipReaderPrivate(QIODevice *device, bool ownDev)-
507 : QZipPrivate(device, ownDev), status(QZipReader::NoError)-
508 {-
509 }
never executed: end of block
0
510-
511 void scanFiles();-
512-
513 QZipReader::Status status;-
514};-
515-
516class QZipWriterPrivate : public QZipPrivate-
517{-
518public:-
519 QZipWriterPrivate(QIODevice *device, bool ownDev)-
520 : QZipPrivate(device, ownDev),-
521 status(QZipWriter::NoError),-
522 permissions(QFile::ReadOwner | QFile::WriteOwner),-
523 compressionPolicy(QZipWriter::AlwaysCompress)-
524 {-
525 }
never executed: end of block
0
526-
527 QZipWriter::Status status;-
528 QFile::Permissions permissions;-
529 QZipWriter::CompressionPolicy compressionPolicy;-
530-
531 enum EntryType { Directory, File, Symlink };-
532-
533 void addEntry(EntryType type, const QString &fileName, const QByteArray &contents);-
534};-
535-
536LocalFileHeader CentralFileHeader::toLocalHeader() const-
537{-
538 LocalFileHeader h;-
539 writeUInt(h.signature, 0x04034b50);-
540 copyUShort(h.version_needed, version_needed);-
541 copyUShort(h.general_purpose_bits, general_purpose_bits);-
542 copyUShort(h.compression_method, compression_method);-
543 copyUInt(h.last_mod_file, last_mod_file);-
544 copyUInt(h.crc_32, crc_32);-
545 copyUInt(h.compressed_size, compressed_size);-
546 copyUInt(h.uncompressed_size, uncompressed_size);-
547 copyUShort(h.file_name_length, file_name_length);-
548 copyUShort(h.extra_field_length, extra_field_length);-
549 return h;
never executed: return h;
0
550}-
551-
552void QZipReaderPrivate::scanFiles()-
553{-
554 if (!dirtyFileTree)
!dirtyFileTreeDescription
TRUEnever evaluated
FALSEnever evaluated
0
555 return;
never executed: return;
0
556-
557 if (! (device->isOpen() || device->open(QIODevice::ReadOnly))) {
device->isOpen()Description
TRUEnever evaluated
FALSEnever evaluated
device->open(Q...ice::ReadOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
558 status = QZipReader::FileOpenError;-
559 return;
never executed: return;
0
560 }-
561-
562 if ((device->openMode() & QIODevice::ReadOnly) == 0) { // only read the index from readable files.
(device->openM...ReadOnly) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
563 status = QZipReader::FileReadError;-
564 return;
never executed: return;
0
565 }-
566-
567 dirtyFileTree = false;-
568 uchar tmp[4];-
569 device->read((char *)tmp, 4);-
570 if (readUInt(tmp) != 0x04034b50) {
readUInt(tmp) != 0x04034b50Description
TRUEnever evaluated
FALSEnever evaluated
0
571 qWarning() << "QZip: not a zip file!";-
572 return;
never executed: return;
0
573 }-
574-
575 // find EndOfDirectory header-
576 int i = 0;-
577 int start_of_directory = -1;-
578 int num_dir_entries = 0;-
579 EndOfDirectory eod;-
580 while (start_of_directory == -1) {
start_of_directory == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
581 const int pos = device->size() - int(sizeof(EndOfDirectory)) - i;-
582 if (pos < 0 || i > 65535) {
pos < 0Description
TRUEnever evaluated
FALSEnever evaluated
i > 65535Description
TRUEnever evaluated
FALSEnever evaluated
0
583 qWarning() << "QZip: EndOfDirectory not found";-
584 return;
never executed: return;
0
585 }-
586-
587 device->seek(pos);-
588 device->read((char *)&eod, sizeof(EndOfDirectory));-
589 if (readUInt(eod.signature) == 0x06054b50)
readUInt(eod.s... == 0x06054b50Description
TRUEnever evaluated
FALSEnever evaluated
0
590 break;
never executed: break;
0
591 ++i;-
592 }
never executed: end of block
0
593-
594 // have the eod-
595 start_of_directory = readUInt(eod.dir_start_offset);-
596 num_dir_entries = readUShort(eod.num_dir_entries);-
597 ZDEBUG("start_of_directory at %d, num_dir_entries=%d", start_of_directory, num_dir_entries);
dead code: QMessageLogger(__FILE__, 597, __PRETTY_FUNCTION__).debug("start_of_directory at %d, num_dir_entries=%d", start_of_directory, num_dir_entries);
-
598 int comment_length = readUShort(eod.comment_length);-
599 if (comment_length != i)
comment_length != iDescription
TRUEnever evaluated
FALSEnever evaluated
0
600 qWarning() << "QZip: failed to parse zip file.";
never executed: QMessageLogger(__FILE__, 600, __PRETTY_FUNCTION__).warning() << "QZip: failed to parse zip file.";
0
601 comment = device->read(qMin(comment_length, i));-
602-
603-
604 device->seek(start_of_directory);-
605 for (i = 0; i < num_dir_entries; ++i) {
i < num_dir_entriesDescription
TRUEnever evaluated
FALSEnever evaluated
0
606 FileHeader header;-
607 int read = device->read((char *) &header.h, sizeof(CentralFileHeader));-
608 if (read < (int)sizeof(CentralFileHeader)) {
read < (int)si...ralFileHeader)Description
TRUEnever evaluated
FALSEnever evaluated
0
609 qWarning() << "QZip: Failed to read complete header, index may be incomplete";-
610 break;
never executed: break;
0
611 }-
612 if (readUInt(header.h.signature) != 0x02014b50) {
readUInt(heade... != 0x02014b50Description
TRUEnever evaluated
FALSEnever evaluated
0
613 qWarning() << "QZip: invalid header signature, index may be incomplete";-
614 break;
never executed: break;
0
615 }-
616-
617 int l = readUShort(header.h.file_name_length);-
618 header.file_name = device->read(l);-
619 if (header.file_name.length() != l) {
header.file_name.length() != lDescription
TRUEnever evaluated
FALSEnever evaluated
0
620 qWarning() << "QZip: Failed to read filename from zip index, index may be incomplete";-
621 break;
never executed: break;
0
622 }-
623 l = readUShort(header.h.extra_field_length);-
624 header.extra_field = device->read(l);-
625 if (header.extra_field.length() != l) {
header.extra_f....length() != lDescription
TRUEnever evaluated
FALSEnever evaluated
0
626 qWarning() << "QZip: Failed to read extra field in zip file, skipping file, index may be incomplete";-
627 break;
never executed: break;
0
628 }-
629 l = readUShort(header.h.file_comment_length);-
630 header.file_comment = device->read(l);-
631 if (header.file_comment.length() != l) {
header.file_co....length() != lDescription
TRUEnever evaluated
FALSEnever evaluated
0
632 qWarning() << "QZip: Failed to read read file comment, index may be incomplete";-
633 break;
never executed: break;
0
634 }-
635-
636 ZDEBUG("found file '%s'", header.file_name.data());
dead code: QMessageLogger(__FILE__, 636, __PRETTY_FUNCTION__).debug("found file '%s'", header.file_name.data());
-
637 fileHeaders.append(header);-
638 }
never executed: end of block
0
639}
never executed: end of block
0
640-
641void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QByteArray &contents/*, QFile::Permissions permissions, QZip::Method m*/)-
642{-
643#ifndef NDEBUG-
644 static const char *const entryTypes[] = {-
645 "directory",-
646 "file ",-
647 "symlink " };-
648 ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : "");
dead code: QMessageLogger(__FILE__, 648, __PRETTY_FUNCTION__).debug() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : "");
-
649#endif-
650-
651 if (! (device->isOpen() || device->open(QIODevice::WriteOnly))) {
device->isOpen()Description
TRUEnever evaluated
FALSEnever evaluated
device->open(Q...ce::WriteOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
652 status = QZipWriter::FileOpenError;-
653 return;
never executed: return;
0
654 }-
655 device->seek(start_of_directory);-
656-
657 // don't compress small files-
658 QZipWriter::CompressionPolicy compression = compressionPolicy;-
659 if (compressionPolicy == QZipWriter::AutoCompress) {
compressionPol...::AutoCompressDescription
TRUEnever evaluated
FALSEnever evaluated
0
660 if (contents.length() < 64)
contents.length() < 64Description
TRUEnever evaluated
FALSEnever evaluated
0
661 compression = QZipWriter::NeverCompress;
never executed: compression = QZipWriter::NeverCompress;
0
662 else-
663 compression = QZipWriter::AlwaysCompress;
never executed: compression = QZipWriter::AlwaysCompress;
0
664 }-
665-
666 FileHeader header;-
667 memset(&header.h, 0, sizeof(CentralFileHeader));-
668 writeUInt(header.h.signature, 0x02014b50);-
669-
670 writeUShort(header.h.version_needed, ZIP_VERSION);-
671 writeUInt(header.h.uncompressed_size, contents.length());-
672 writeMSDosDate(header.h.last_mod_file, QDateTime::currentDateTime());-
673 QByteArray data = contents;-
674 if (compression == QZipWriter::AlwaysCompress) {
compression ==...AlwaysCompressDescription
TRUEnever evaluated
FALSEnever evaluated
0
675 writeUShort(header.h.compression_method, CompressionMethodDeflated);-
676-
677 ulong len = contents.length();-
678 // shamelessly copied form zlib-
679 len += (len >> 12) + (len >> 14) + 11;-
680 int res;-
681 do {-
682 data.resize(len);-
683 res = deflate((uchar*)data.data(), &len, (const uchar*)contents.constData(), contents.length());-
684-
685 switch (res) {-
686 case Z_OK:
never executed: case 0:
0
687 data.resize(len);-
688 break;
never executed: break;
0
689 case Z_MEM_ERROR:
never executed: case (-4):
0
690 qWarning("QZip: Z_MEM_ERROR: Not enough memory to compress file, skipping");-
691 data.resize(0);-
692 break;
never executed: break;
0
693 case Z_BUF_ERROR:
never executed: case (-5):
0
694 len *= 2;-
695 break;
never executed: break;
0
696 }-
697 } while (res == Z_BUF_ERROR);
never executed: end of block
res == (-5)Description
TRUEnever evaluated
FALSEnever evaluated
0
698 }
never executed: end of block
0
699// TODO add a check if data.length() > contents.length(). Then try to store the original and revert the compression method to be uncompressed-
700 writeUInt(header.h.compressed_size, data.length());-
701 uint crc_32 = ::crc32(0, 0, 0);-
702 crc_32 = ::crc32(crc_32, (const uchar *)contents.constData(), contents.length());-
703 writeUInt(header.h.crc_32, crc_32);-
704-
705 // if bit 11 is set, the filename and comment fields must be encoded using UTF-8-
706 ushort general_purpose_bits = Utf8Names; // always use utf-8-
707 writeUShort(header.h.general_purpose_bits, general_purpose_bits);-
708-
709 const bool inUtf8 = (general_purpose_bits & Utf8Names) != 0;-
710 header.file_name = inUtf8 ? fileName.toUtf8() : fileName.toLocal8Bit();
inUtf8Description
TRUEnever evaluated
FALSEnever evaluated
0
711 if (header.file_name.size() > 0xffff) {
header.file_na...ize() > 0xffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
712 qWarning("QZip: Filename is too long, chopping it to 65535 bytes");-
713 header.file_name = header.file_name.left(0xffff); // ### don't break the utf-8 sequence, if any-
714 }
never executed: end of block
0
715 if (header.file_comment.size() + header.file_name.size() > 0xffff) {
header.file_co...ize() > 0xffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
716 qWarning("QZip: File comment is too long, chopping it to 65535 bytes");-
717 header.file_comment.truncate(0xffff - header.file_name.size()); // ### don't break the utf-8 sequence, if any-
718 }
never executed: end of block
0
719 writeUShort(header.h.file_name_length, header.file_name.length());-
720 //h.extra_field_length[2];-
721-
722 writeUShort(header.h.version_made, HostUnix << 8);-
723 //uchar internal_file_attributes[2];-
724 //uchar external_file_attributes[4];-
725 quint32 mode = permissionsToMode(permissions);-
726 switch (type) {-
727 case Symlink:
never executed: case Symlink:
0
728 mode |= UnixFileAttributes::SymLink;-
729 break;
never executed: break;
0
730 case Directory:
never executed: case Directory:
0
731 mode |= UnixFileAttributes::Dir;-
732 break;
never executed: break;
0
733 case File:
never executed: case File:
0
734 mode |= UnixFileAttributes::File;-
735 break;
never executed: break;
0
736 default:
never executed: default:
0
737 Q_UNREACHABLE();-
738 break;
never executed: break;
0
739 }-
740 writeUInt(header.h.external_file_attributes, mode << 16);-
741 writeUInt(header.h.offset_local_header, start_of_directory);-
742-
743-
744 fileHeaders.append(header);-
745-
746 LocalFileHeader h = header.h.toLocalHeader();-
747 device->write((const char *)&h, sizeof(LocalFileHeader));-
748 device->write(header.file_name);-
749 device->write(data);-
750 start_of_directory = device->pos();-
751 dirtyFileTree = true;-
752}
never executed: end of block
0
753-
754////////////////////////////// Reader-
755-
756/*!-
757 \class QZipReader::FileInfo-
758 \internal-
759 Represents one entry in the zip table of contents.-
760*/-
761-
762/*!-
763 \variable FileInfo::filePath-
764 The full filepath inside the archive.-
765*/-
766-
767/*!-
768 \variable FileInfo::isDir-
769 A boolean type indicating if the entry is a directory.-
770*/-
771-
772/*!-
773 \variable FileInfo::isFile-
774 A boolean type, if it is one this entry is a file.-
775*/-
776-
777/*!-
778 \variable FileInfo::isSymLink-
779 A boolean type, if it is one this entry is symbolic link.-
780*/-
781-
782/*!-
783 \variable FileInfo::permissions-
784 A list of flags for the permissions of this entry.-
785*/-
786-
787/*!-
788 \variable FileInfo::crc-
789 The calculated checksum as a crc type.-
790*/-
791-
792/*!-
793 \variable FileInfo::size-
794 The total size of the unpacked content.-
795*/-
796-
797/*!-
798 \class QZipReader-
799 \internal-
800 \since 4.5-
801-
802 \brief the QZipReader class provides a way to inspect the contents of a zip-
803 archive and extract individual files from it.-
804-
805 QZipReader can be used to read a zip archive either from a file or from any-
806 device. An in-memory QBuffer for instance. The reader can be used to read-
807 which files are in the archive using fileInfoList() and entryInfoAt() but-
808 also to extract individual files using fileData() or even to extract all-
809 files in the archive using extractAll()-
810*/-
811-
812/*!-
813 Create a new zip archive that operates on the \a fileName. The file will be-
814 opened with the \a mode.-
815*/-
816QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode)-
817{-
818 QScopedPointer<QFile> f(new QFile(archive));-
819 QZipReader::Status status;-
820 if (f->open(mode) && f->error() == QFile::NoError)
f->open(mode)Description
TRUEnever evaluated
FALSEnever evaluated
f->error() == QFile::NoErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
821 status = NoError;
never executed: status = NoError;
0
822 else {-
823 if (f->error() == QFile::ReadError)
f->error() == QFile::ReadErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
824 status = FileReadError;
never executed: status = FileReadError;
0
825 else if (f->error() == QFile::OpenError)
f->error() == QFile::OpenErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
826 status = FileOpenError;
never executed: status = FileOpenError;
0
827 else if (f->error() == QFile::PermissionsError)
f->error() == ...rmissionsErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
828 status = FilePermissionsError;
never executed: status = FilePermissionsError;
0
829 else-
830 status = FileError;
never executed: status = FileError;
0
831 }-
832-
833 d = new QZipReaderPrivate(f.data(), /*ownDevice=*/true);-
834 f.take();-
835 d->status = status;-
836}
never executed: end of block
0
837-
838/*!-
839 Create a new zip archive that operates on the archive found in \a device.-
840 You have to open the device previous to calling the constructor and only a-
841 device that is readable will be scanned for zip filecontent.-
842 */-
843QZipReader::QZipReader(QIODevice *device)-
844 : d(new QZipReaderPrivate(device, /*ownDevice=*/false))-
845{-
846 Q_ASSERT(device);-
847}
never executed: end of block
0
848-
849/*!-
850 Desctructor-
851*/-
852QZipReader::~QZipReader()-
853{-
854 close();-
855 delete d;-
856}
never executed: end of block
0
857-
858/*!-
859 Returns device used for reading zip archive.-
860*/-
861QIODevice* QZipReader::device() const-
862{-
863 return d->device;
never executed: return d->device;
0
864}-
865-
866/*!-
867 Returns \c true if the user can read the file; otherwise returns \c false.-
868*/-
869bool QZipReader::isReadable() const-
870{-
871 return d->device->isReadable();
never executed: return d->device->isReadable();
0
872}-
873-
874/*!-
875 Returns \c true if the file exists; otherwise returns \c false.-
876*/-
877bool QZipReader::exists() const-
878{-
879 QFile *f = qobject_cast<QFile*> (d->device);-
880 if (f == 0)
f == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
881 return true;
never executed: return true;
0
882 return f->exists();
never executed: return f->exists();
0
883}-
884-
885/*!-
886 Returns the list of files the archive contains.-
887*/-
888QVector<QZipReader::FileInfo> QZipReader::fileInfoList() const-
889{-
890 d->scanFiles();-
891 QVector<FileInfo> files;-
892 const int numFileHeaders = d->fileHeaders.size();-
893 files.reserve(numFileHeaders);-
894 for (int i = 0; i < numFileHeaders; ++i)
i < numFileHeadersDescription
TRUEnever evaluated
FALSEnever evaluated
0
895 files.append(d->fillFileInfo(i));
never executed: files.append(d->fillFileInfo(i));
0
896 return files;
never executed: return files;
0
897-
898}-
899-
900/*!-
901 Return the number of items in the zip archive.-
902*/-
903int QZipReader::count() const-
904{-
905 d->scanFiles();-
906 return d->fileHeaders.count();
never executed: return d->fileHeaders.count();
0
907}-
908-
909/*!-
910 Returns a FileInfo of an entry in the zipfile.-
911 The \a index is the index into the directory listing of the zipfile.-
912 Returns an invalid FileInfo if \a index is out of boundaries.-
913-
914 \sa fileInfoList()-
915*/-
916QZipReader::FileInfo QZipReader::entryInfoAt(int index) const-
917{-
918 d->scanFiles();-
919 if (index >= 0 && index < d->fileHeaders.count())
index >= 0Description
TRUEnever evaluated
FALSEnever evaluated
index < d->fileHeaders.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
920 return d->fillFileInfo(index);
never executed: return d->fillFileInfo(index);
0
921 return QZipReader::FileInfo();
never executed: return QZipReader::FileInfo();
0
922}-
923-
924/*!-
925 Fetch the file contents from the zip archive and return the uncompressed bytes.-
926*/-
927QByteArray QZipReader::fileData(const QString &fileName) const-
928{-
929 d->scanFiles();-
930 int i;-
931 for (i = 0; i < d->fileHeaders.size(); ++i) {
i < d->fileHeaders.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
932 if (QString::fromLocal8Bit(d->fileHeaders.at(i).file_name) == fileName)
QString::fromL...e) == fileNameDescription
TRUEnever evaluated
FALSEnever evaluated
0
933 break;
never executed: break;
0
934 }
never executed: end of block
0
935 if (i == d->fileHeaders.size())
i == d->fileHeaders.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
936 return QByteArray();
never executed: return QByteArray();
0
937-
938 FileHeader header = d->fileHeaders.at(i);-
939-
940 ushort version_needed = readUShort(header.h.version_needed);-
941 if (version_needed > ZIP_VERSION) {
version_needed > 20Description
TRUEnever evaluated
FALSEnever evaluated
0
942 qWarning("QZip: .ZIP specification version %d implementationis needed to extract the data.", version_needed);-
943 return QByteArray();
never executed: return QByteArray();
0
944 }-
945-
946 ushort general_purpose_bits = readUShort(header.h.general_purpose_bits);-
947 int compressed_size = readUInt(header.h.compressed_size);-
948 int uncompressed_size = readUInt(header.h.uncompressed_size);-
949 int start = readUInt(header.h.offset_local_header);-
950 //qDebug("uncompressing file %d: local header at %d", i, start);-
951-
952 d->device->seek(start);-
953 LocalFileHeader lh;-
954 d->device->read((char *)&lh, sizeof(LocalFileHeader));-
955 uint skip = readUShort(lh.file_name_length) + readUShort(lh.extra_field_length);-
956 d->device->seek(d->device->pos() + skip);-
957-
958 int compression_method = readUShort(lh.compression_method);-
959 //qDebug("file=%s: compressed_size=%d, uncompressed_size=%d", fileName.toLocal8Bit().data(), compressed_size, uncompressed_size);-
960-
961 if ((general_purpose_bits & Encrypted) != 0) {
(general_purpo...ncrypted) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
962 qWarning("QZip: Unsupported encryption method is needed to extract the data.");-
963 return QByteArray();
never executed: return QByteArray();
0
964 }-
965-
966 //qDebug("file at %lld", d->device->pos());-
967 QByteArray compressed = d->device->read(compressed_size);-
968 if (compression_method == CompressionMethodStored) {
compression_me...onMethodStoredDescription
TRUEnever evaluated
FALSEnever evaluated
0
969 // no compression-
970 compressed.truncate(uncompressed_size);-
971 return compressed;
never executed: return compressed;
0
972 } else if (compression_method == CompressionMethodDeflated) {
compression_me...MethodDeflatedDescription
TRUEnever evaluated
FALSEnever evaluated
0
973 // Deflate-
974 //qDebug("compressed=%d", compressed.size());-
975 compressed.truncate(compressed_size);-
976 QByteArray baunzip;-
977 ulong len = qMax(uncompressed_size, 1);-
978 int res;-
979 do {-
980 baunzip.resize(len);-
981 res = inflate((uchar*)baunzip.data(), &len,-
982 (const uchar*)compressed.constData(), compressed_size);-
983-
984 switch (res) {-
985 case Z_OK:
never executed: case 0:
0
986 if ((int)len != baunzip.size())
(int)len != baunzip.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
987 baunzip.resize(len);
never executed: baunzip.resize(len);
0
988 break;
never executed: break;
0
989 case Z_MEM_ERROR:
never executed: case (-4):
0
990 qWarning("QZip: Z_MEM_ERROR: Not enough memory");-
991 break;
never executed: break;
0
992 case Z_BUF_ERROR:
never executed: case (-5):
0
993 len *= 2;-
994 break;
never executed: break;
0
995 case Z_DATA_ERROR:
never executed: case (-3):
0
996 qWarning("QZip: Z_DATA_ERROR: Input data is corrupted");-
997 break;
never executed: break;
0
998 }-
999 } while (res == Z_BUF_ERROR);
never executed: end of block
res == (-5)Description
TRUEnever evaluated
FALSEnever evaluated
0
1000 return baunzip;
never executed: return baunzip;
0
1001 }-
1002-
1003 qWarning("QZip: Unsupported compression method %d is needed to extract the data.", compression_method);-
1004 return QByteArray();
never executed: return QByteArray();
0
1005}-
1006-
1007/*!-
1008 Extracts the full contents of the zip file into \a destinationDir on-
1009 the local filesystem.-
1010 In case writing or linking a file fails, the extraction will be aborted.-
1011*/-
1012bool QZipReader::extractAll(const QString &destinationDir) const-
1013{-
1014 QDir baseDir(destinationDir);-
1015-
1016 // create directories first-
1017 const QVector<FileInfo> allFiles = fileInfoList();-
1018 foreach (const FileInfo &fi, allFiles) {-
1019 const QString absPath = destinationDir + QDir::separator() + fi.filePath;-
1020 if (fi.isDir) {
fi.isDirDescription
TRUEnever evaluated
FALSEnever evaluated
0
1021 if (!baseDir.mkpath(fi.filePath))
!baseDir.mkpath(fi.filePath)Description
TRUEnever evaluated
FALSEnever evaluated
0
1022 return false;
never executed: return false;
0
1023 if (!QFile::setPermissions(absPath, fi.permissions))
!QFile::setPer...i.permissions)Description
TRUEnever evaluated
FALSEnever evaluated
0
1024 return false;
never executed: return false;
0
1025 }
never executed: end of block
0
1026 }
never executed: end of block
0
1027-
1028 // set up symlinks-
1029 foreach (const FileInfo &fi, allFiles) {-
1030 const QString absPath = destinationDir + QDir::separator() + fi.filePath;-
1031 if (fi.isSymLink) {
fi.isSymLinkDescription
TRUEnever evaluated
FALSEnever evaluated
0
1032 QString destination = QFile::decodeName(fileData(fi.filePath));-
1033 if (destination.isEmpty())
destination.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1034 return false;
never executed: return false;
0
1035 QFileInfo linkFi(absPath);-
1036 if (!QFile::exists(linkFi.absolutePath()))
!QFile::exists...bsolutePath())Description
TRUEnever evaluated
FALSEnever evaluated
0
1037 QDir::root().mkpath(linkFi.absolutePath());
never executed: QDir::root().mkpath(linkFi.absolutePath());
0
1038 if (!QFile::link(destination, absPath))
!QFile::link(d...tion, absPath)Description
TRUEnever evaluated
FALSEnever evaluated
0
1039 return false;
never executed: return false;
0
1040 /* cannot change permission of links-
1041 if (!QFile::setPermissions(absPath, fi.permissions))-
1042 return false;-
1043 */-
1044 }
never executed: end of block
0
1045 }
never executed: end of block
0
1046-
1047 foreach (const FileInfo &fi, allFiles) {-
1048 const QString absPath = destinationDir + QDir::separator() + fi.filePath;-
1049 if (fi.isFile) {
fi.isFileDescription
TRUEnever evaluated
FALSEnever evaluated
0
1050 QFile f(absPath);-
1051 if (!f.open(QIODevice::WriteOnly))
!f.open(QIODevice::WriteOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1052 return false;
never executed: return false;
0
1053 f.write(fileData(fi.filePath));-
1054 f.setPermissions(fi.permissions);-
1055 f.close();-
1056 }
never executed: end of block
0
1057 }
never executed: end of block
0
1058-
1059 return true;
never executed: return true;
0
1060}-
1061-
1062/*!-
1063 \enum QZipReader::Status-
1064-
1065 The following status values are possible:-
1066-
1067 \value NoError No error occurred.-
1068 \value FileReadError An error occurred when reading from the file.-
1069 \value FileOpenError The file could not be opened.-
1070 \value FilePermissionsError The file could not be accessed.-
1071 \value FileError Another file error occurred.-
1072*/-
1073-
1074/*!-
1075 Returns a status code indicating the first error that was met by QZipReader,-
1076 or QZipReader::NoError if no error occurred.-
1077*/-
1078QZipReader::Status QZipReader::status() const-
1079{-
1080 return d->status;
never executed: return d->status;
0
1081}-
1082-
1083/*!-
1084 Close the zip file.-
1085*/-
1086void QZipReader::close()-
1087{-
1088 d->device->close();-
1089}
never executed: end of block
0
1090-
1091////////////////////////////// Writer-
1092-
1093/*!-
1094 \class QZipWriter-
1095 \internal-
1096 \since 4.5-
1097-
1098 \brief the QZipWriter class provides a way to create a new zip archive.-
1099-
1100 QZipWriter can be used to create a zip archive containing any number of files-
1101 and directories. The files in the archive will be compressed in a way that is-
1102 compatible with common zip reader applications.-
1103*/-
1104-
1105-
1106/*!-
1107 Create a new zip archive that operates on the \a archive filename. The file will-
1108 be opened with the \a mode.-
1109 \sa isValid()-
1110*/-
1111QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)-
1112{-
1113 QScopedPointer<QFile> f(new QFile(fileName));-
1114 QZipWriter::Status status;-
1115 if (f->open(mode) && f->error() == QFile::NoError)
f->open(mode)Description
TRUEnever evaluated
FALSEnever evaluated
f->error() == QFile::NoErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1116 status = QZipWriter::NoError;
never executed: status = QZipWriter::NoError;
0
1117 else {-
1118 if (f->error() == QFile::WriteError)
f->error() == ...le::WriteErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1119 status = QZipWriter::FileWriteError;
never executed: status = QZipWriter::FileWriteError;
0
1120 else if (f->error() == QFile::OpenError)
f->error() == QFile::OpenErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1121 status = QZipWriter::FileOpenError;
never executed: status = QZipWriter::FileOpenError;
0
1122 else if (f->error() == QFile::PermissionsError)
f->error() == ...rmissionsErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1123 status = QZipWriter::FilePermissionsError;
never executed: status = QZipWriter::FilePermissionsError;
0
1124 else-
1125 status = QZipWriter::FileError;
never executed: status = QZipWriter::FileError;
0
1126 }-
1127-
1128 d = new QZipWriterPrivate(f.data(), /*ownDevice=*/true);-
1129 f.take();-
1130 d->status = status;-
1131}
never executed: end of block
0
1132-
1133/*!-
1134 Create a new zip archive that operates on the archive found in \a device.-
1135 You have to open the device previous to calling the constructor and-
1136 only a device that is readable will be scanned for zip filecontent.-
1137 */-
1138QZipWriter::QZipWriter(QIODevice *device)-
1139 : d(new QZipWriterPrivate(device, /*ownDevice=*/false))-
1140{-
1141 Q_ASSERT(device);-
1142}
never executed: end of block
0
1143-
1144QZipWriter::~QZipWriter()-
1145{-
1146 close();-
1147 delete d;-
1148}
never executed: end of block
0
1149-
1150/*!-
1151 Returns device used for writing zip archive.-
1152*/-
1153QIODevice* QZipWriter::device() const-
1154{-
1155 return d->device;
never executed: return d->device;
0
1156}-
1157-
1158/*!-
1159 Returns \c true if the user can write to the archive; otherwise returns \c false.-
1160*/-
1161bool QZipWriter::isWritable() const-
1162{-
1163 return d->device->isWritable();
never executed: return d->device->isWritable();
0
1164}-
1165-
1166/*!-
1167 Returns \c true if the file exists; otherwise returns \c false.-
1168*/-
1169bool QZipWriter::exists() const-
1170{-
1171 QFile *f = qobject_cast<QFile*> (d->device);-
1172 if (f == 0)
f == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1173 return true;
never executed: return true;
0
1174 return f->exists();
never executed: return f->exists();
0
1175}-
1176-
1177/*!-
1178 \enum QZipWriter::Status-
1179-
1180 The following status values are possible:-
1181-
1182 \value NoError No error occurred.-
1183 \value FileWriteError An error occurred when writing to the device.-
1184 \value FileOpenError The file could not be opened.-
1185 \value FilePermissionsError The file could not be accessed.-
1186 \value FileError Another file error occurred.-
1187*/-
1188-
1189/*!-
1190 Returns a status code indicating the first error that was met by QZipWriter,-
1191 or QZipWriter::NoError if no error occurred.-
1192*/-
1193QZipWriter::Status QZipWriter::status() const-
1194{-
1195 return d->status;
never executed: return d->status;
0
1196}-
1197-
1198/*!-
1199 \enum QZipWriter::CompressionPolicy-
1200-
1201 \value AlwaysCompress A file that is added is compressed.-
1202 \value NeverCompress A file that is added will be stored without changes.-
1203 \value AutoCompress A file that is added will be compressed only if that will give a smaller file.-
1204*/-
1205-
1206/*!-
1207 Sets the policy for compressing newly added files to the new \a policy.-
1208-
1209 \note the default policy is AlwaysCompress-
1210-
1211 \sa compressionPolicy()-
1212 \sa addFile()-
1213*/-
1214void QZipWriter::setCompressionPolicy(CompressionPolicy policy)-
1215{-
1216 d->compressionPolicy = policy;-
1217}
never executed: end of block
0
1218-
1219/*!-
1220 Returns the currently set compression policy.-
1221 \sa setCompressionPolicy()-
1222 \sa addFile()-
1223*/-
1224QZipWriter::CompressionPolicy QZipWriter::compressionPolicy() const-
1225{-
1226 return d->compressionPolicy;
never executed: return d->compressionPolicy;
0
1227}-
1228-
1229/*!-
1230 Sets the permissions that will be used for newly added files.-
1231-
1232 \note the default permissions are QFile::ReadOwner | QFile::WriteOwner.-
1233-
1234 \sa creationPermissions()-
1235 \sa addFile()-
1236*/-
1237void QZipWriter::setCreationPermissions(QFile::Permissions permissions)-
1238{-
1239 d->permissions = permissions;-
1240}
never executed: end of block
0
1241-
1242/*!-
1243 Returns the currently set creation permissions.-
1244-
1245 \sa setCreationPermissions()-
1246 \sa addFile()-
1247*/-
1248QFile::Permissions QZipWriter::creationPermissions() const-
1249{-
1250 return d->permissions;
never executed: return d->permissions;
0
1251}-
1252-
1253/*!-
1254 Add a file to the archive with \a data as the file contents.-
1255 The file will be stored in the archive using the \a fileName which-
1256 includes the full path in the archive.-
1257-
1258 The new file will get the file permissions based on the current-
1259 creationPermissions and it will be compressed using the zip compression-
1260 based on the current compression policy.-
1261-
1262 \sa setCreationPermissions()-
1263 \sa setCompressionPolicy()-
1264*/-
1265void QZipWriter::addFile(const QString &fileName, const QByteArray &data)-
1266{-
1267 d->addEntry(QZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), data);-
1268}
never executed: end of block
0
1269-
1270/*!-
1271 Add a file to the archive with \a device as the source of the contents.-
1272 The contents returned from QIODevice::readAll() will be used as the-
1273 filedata.-
1274 The file will be stored in the archive using the \a fileName which-
1275 includes the full path in the archive.-
1276*/-
1277void QZipWriter::addFile(const QString &fileName, QIODevice *device)-
1278{-
1279 Q_ASSERT(device);-
1280 QIODevice::OpenMode mode = device->openMode();-
1281 bool opened = false;-
1282 if ((mode & QIODevice::ReadOnly) == 0) {
(mode & QIODev...ReadOnly) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1283 opened = true;-
1284 if (! device->open(QIODevice::ReadOnly)) {
! device->open...ice::ReadOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1285 d->status = FileOpenError;-
1286 return;
never executed: return;
0
1287 }-
1288 }
never executed: end of block
0
1289 d->addEntry(QZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), device->readAll());-
1290 if (opened)
openedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1291 device->close();
never executed: device->close();
0
1292}
never executed: end of block
0
1293-
1294/*!-
1295 Create a new directory in the archive with the specified \a dirName and-
1296 the \a permissions;-
1297*/-
1298void QZipWriter::addDirectory(const QString &dirName)-
1299{-
1300 QString name(QDir::fromNativeSeparators(dirName));-
1301 // separator is mandatory-
1302 if (!name.endsWith(QLatin1Char('/')))
!name.endsWith...tin1Char('/'))Description
TRUEnever evaluated
FALSEnever evaluated
0
1303 name.append(QLatin1Char('/'));
never executed: name.append(QLatin1Char('/'));
0
1304 d->addEntry(QZipWriterPrivate::Directory, name, QByteArray());-
1305}
never executed: end of block
0
1306-
1307/*!-
1308 Create a new symbolic link in the archive with the specified \a dirName-
1309 and the \a permissions;-
1310 A symbolic link contains the destination (relative) path and name.-
1311*/-
1312void QZipWriter::addSymLink(const QString &fileName, const QString &destination)-
1313{-
1314 d->addEntry(QZipWriterPrivate::Symlink, QDir::fromNativeSeparators(fileName), QFile::encodeName(destination));-
1315}
never executed: end of block
0
1316-
1317/*!-
1318 Closes the zip file.-
1319*/-
1320void QZipWriter::close()-
1321{-
1322 if (!(d->device->openMode() & QIODevice::WriteOnly)) {
!(d->device->o...ce::WriteOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1323 d->device->close();-
1324 return;
never executed: return;
0
1325 }-
1326-
1327 //qDebug("QZip::close writing directory, %d entries", d->fileHeaders.size());-
1328 d->device->seek(d->start_of_directory);-
1329 // write new directory-
1330 for (int i = 0; i < d->fileHeaders.size(); ++i) {
i < d->fileHeaders.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1331 const FileHeader &header = d->fileHeaders.at(i);-
1332 d->device->write((const char *)&header.h, sizeof(CentralFileHeader));-
1333 d->device->write(header.file_name);-
1334 d->device->write(header.extra_field);-
1335 d->device->write(header.file_comment);-
1336 }
never executed: end of block
0
1337 int dir_size = d->device->pos() - d->start_of_directory;-
1338 // write end of directory-
1339 EndOfDirectory eod;-
1340 memset(&eod, 0, sizeof(EndOfDirectory));-
1341 writeUInt(eod.signature, 0x06054b50);-
1342 //uchar this_disk[2];-
1343 //uchar start_of_directory_disk[2];-
1344 writeUShort(eod.num_dir_entries_this_disk, d->fileHeaders.size());-
1345 writeUShort(eod.num_dir_entries, d->fileHeaders.size());-
1346 writeUInt(eod.directory_size, dir_size);-
1347 writeUInt(eod.dir_start_offset, d->start_of_directory);-
1348 writeUShort(eod.comment_length, d->comment.length());-
1349-
1350 d->device->write((const char *)&eod, sizeof(EndOfDirectory));-
1351 d->device->write(d->comment);-
1352 d->device->close();-
1353}
never executed: end of block
0
1354-
1355QT_END_NAMESPACE-
1356-
1357#endif // QT_NO_TEXTODFWRITER-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9