diff --git a/project.diff b/project.diff new file mode 100644 --- /dev/null +++ b/project.diff @@ -0,0 +1,60 @@ +--- a/quazip/quazip.pri 2019-09-12 12:50:50.932633078 +0300 ++++ b/quazip/quazip.pri 2019-09-12 13:47:01.683852447 +0300 +@@ -1,15 +1,8 @@ + INCLUDEPATH += $$PWD + DEPENDPATH += $$PWD + HEADERS += \ +- $$PWD/minizip_crypt.h \ + $$PWD/ioapi.h \ +- $$PWD/JlCompress.h \ +- $$PWD/quaadler32.h \ +- $$PWD/quachecksum32.h \ +- $$PWD/quacrc32.h \ +- $$PWD/quagzipfile.h \ + $$PWD/quaziodevice.h \ +- $$PWD/quazipdir.h \ + $$PWD/quazipfile.h \ + $$PWD/quazipfileinfo.h \ + $$PWD/quazip_global.h \ +@@ -19,13 +12,8 @@ + $$PWD/zip.h + + SOURCES += $$PWD/qioapi.cpp \ +- $$PWD/JlCompress.cpp \ +- $$PWD/quaadler32.cpp \ +- $$PWD/quacrc32.cpp \ +- $$PWD/quagzipfile.cpp \ + $$PWD/quaziodevice.cpp \ + $$PWD/quazip.cpp \ +- $$PWD/quazipdir.cpp \ + $$PWD/quazipfile.cpp \ + $$PWD/quazipfileinfo.cpp \ + $$PWD/quazipnewinfo.cpp \ +--- a/qztest/qztest.pro 2019-09-12 12:50:50.956633046 +0300 ++++ b/qztest/qztest.pro 2019-09-12 13:48:07.143753675 +0300 +@@ -16,23 +16,19 @@ + + # Input + HEADERS += qztest.h \ ++JlCompress.h \ + testjlcompress.h \ +-testquachecksum32.h \ +-testquagzipfile.h \ + testquaziodevice.h \ +-testquazipdir.h \ + testquazipfile.h \ + testquazip.h \ + testquazipnewinfo.h \ + testquazipfileinfo.h + + SOURCES += qztest.cpp \ ++JlCompress.cpp \ + testjlcompress.cpp \ +-testquachecksum32.cpp \ +-testquagzipfile.cpp \ + testquaziodevice.cpp \ + testquazip.cpp \ +-testquazipdir.cpp \ + testquazipfile.cpp \ + testquazipnewinfo.cpp \ + testquazipfileinfo.cpp diff --git a/quazip/minizip_crypt.h b/quazip/minizip_crypt.h deleted file mode 100644 --- a/quazip/minizip_crypt.h +++ /dev/null @@ -1,135 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#include "quazip_global.h" - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab QUAZIP_UNUSED) -{ - //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const z_crc_t FAR * pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/quazip/quaadler32.cpp b/quazip/quaadler32.cpp deleted file mode 100644 --- a/quazip/quaadler32.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (C) 2010 Adam Walczak -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quaadler32.h" - -#include "zlib.h" - -QuaAdler32::QuaAdler32() -{ - reset(); -} - -quint32 QuaAdler32::calculate(const QByteArray &data) -{ - return adler32( adler32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); -} - -void QuaAdler32::reset() -{ - checksum = adler32(0L, Z_NULL, 0); -} - -void QuaAdler32::update(const QByteArray &buf) -{ - checksum = adler32( checksum, (const Bytef*)buf.data(), buf.size() ); -} - -quint32 QuaAdler32::value() -{ - return checksum; -} diff --git a/quazip/quaadler32.h b/quazip/quaadler32.h deleted file mode 100644 --- a/quazip/quaadler32.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef QUAADLER32_H -#define QUAADLER32_H - -/* -Copyright (C) 2010 Adam Walczak -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -#include "quachecksum32.h" - -/// Adler32 checksum -/** \class QuaAdler32 quaadler32.h - * This class wrappers the adler32 function with the QuaChecksum32 interface. - * See QuaChecksum32 for more info. - */ -class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32 -{ - -public: - QuaAdler32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUAADLER32_H diff --git a/quazip/quachecksum32.h b/quazip/quachecksum32.h deleted file mode 100644 --- a/quazip/quachecksum32.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef QUACHECKSUM32_H -#define QUACHECKSUM32_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include "quazip_global.h" - -/// Checksum interface. -/** \class QuaChecksum32 quachecksum32.h - * This is an interface for 32 bit checksums. - * Classes implementing this interface can calcunate a certin - * checksum in a single step: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * rasoult = crc32->calculate(data); - * \endcode - * or by streaming the data: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * while(!fileA.atEnd()) - * crc32->update(fileA.read(bufSize)); - * resoultA = crc32->value(); - * crc32->reset(); - * while(!fileB.atEnd()) - * crc32->update(fileB.read(bufSize)); - * resoultB = crc32->value(); - * \endcode - */ -class QUAZIP_EXPORT QuaChecksum32 -{ - -public: - ///Calculates the checksum for data. - /** \a data source data - * \return data checksum - * - * This function has no efect on the value returned by value(). - */ - virtual quint32 calculate(const QByteArray &data) = 0; - - ///Resets the calculation on a checksun for a stream. - virtual void reset() = 0; - - ///Updates the calculated checksum for the stream - /** \a buf next portion of data from the stream - */ - virtual void update(const QByteArray &buf) = 0; - - ///Value of the checksum calculated for the stream passed throw update(). - /** \return checksum - */ - virtual quint32 value() = 0; -}; - -#endif //QUACHECKSUM32_H diff --git a/quazip/quacrc32.cpp b/quazip/quacrc32.cpp deleted file mode 100644 --- a/quazip/quacrc32.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quacrc32.h" - -#include "zlib.h" - -QuaCrc32::QuaCrc32() -{ - reset(); -} - -quint32 QuaCrc32::calculate(const QByteArray &data) -{ - return crc32( crc32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); -} - -void QuaCrc32::reset() -{ - checksum = crc32(0L, Z_NULL, 0); -} - -void QuaCrc32::update(const QByteArray &buf) -{ - checksum = crc32( checksum, (const Bytef*)buf.data(), buf.size() ); -} - -quint32 QuaCrc32::value() -{ - return checksum; -} diff --git a/quazip/quacrc32.h b/quazip/quacrc32.h deleted file mode 100644 --- a/quazip/quacrc32.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef QUACRC32_H -#define QUACRC32_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quachecksum32.h" - -///CRC32 checksum -/** \class QuaCrc32 quacrc32.h -* This class wrappers the crc32 function with the QuaChecksum32 interface. -* See QuaChecksum32 for more info. -*/ -class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 { - -public: - QuaCrc32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUACRC32_H diff --git a/quazip/quagzipfile.cpp b/quazip/quagzipfile.cpp deleted file mode 100644 --- a/quazip/quagzipfile.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -#include "quagzipfile.h" - -/// \cond internal -class QuaGzipFilePrivate { - friend class QuaGzipFile; - QString fileName; - gzFile gzd; - inline QuaGzipFilePrivate(): gzd(NULL) {} - inline QuaGzipFilePrivate(const QString &fileName): - fileName(fileName), gzd(NULL) {} - template bool open(FileId id, - QIODevice::OpenMode mode, QString &error); - gzFile open(int fd, const char *modeString); - gzFile open(const QString &name, const char *modeString); -}; - -gzFile QuaGzipFilePrivate::open(const QString &name, const char *modeString) -{ - return gzopen(QFile::encodeName(name).constData(), modeString); -} - -gzFile QuaGzipFilePrivate::open(int fd, const char *modeString) -{ - return gzdopen(fd, modeString); -} - -template -bool QuaGzipFilePrivate::open(FileId id, QIODevice::OpenMode mode, - QString &error) -{ - char modeString[2]; - modeString[0] = modeString[1] = '\0'; - if ((mode & QIODevice::Append) != 0) { - error = QuaGzipFile::trUtf8("QIODevice::Append is not " - "supported for GZIP"); - return false; - } - if ((mode & QIODevice::ReadOnly) != 0 - && (mode & QIODevice::WriteOnly) != 0) { - error = QuaGzipFile::trUtf8("Opening gzip for both reading" - " and writing is not supported"); - return false; - } else if ((mode & QIODevice::ReadOnly) != 0) { - modeString[0] = 'r'; - } else if ((mode & QIODevice::WriteOnly) != 0) { - modeString[0] = 'w'; - } else { - error = QuaGzipFile::trUtf8("You can open a gzip either for reading" - " or for writing. Which is it?"); - return false; - } - gzd = open(id, modeString); - if (gzd == NULL) { - error = QuaGzipFile::trUtf8("Could not gzopen() file"); - return false; - } - return true; -} -/// \endcond - -QuaGzipFile::QuaGzipFile(): -d(new QuaGzipFilePrivate()) -{ -} - -QuaGzipFile::QuaGzipFile(QObject *parent): -QIODevice(parent), -d(new QuaGzipFilePrivate()) -{ -} - -QuaGzipFile::QuaGzipFile(const QString &fileName, QObject *parent): - QIODevice(parent), -d(new QuaGzipFilePrivate(fileName)) -{ -} - -QuaGzipFile::~QuaGzipFile() -{ - if (isOpen()) { - close(); - } - delete d; -} - -void QuaGzipFile::setFileName(const QString& fileName) -{ - d->fileName = fileName; -} - -QString QuaGzipFile::getFileName() const -{ - return d->fileName; -} - -bool QuaGzipFile::isSequential() const -{ - return true; -} - -bool QuaGzipFile::open(QIODevice::OpenMode mode) -{ - QString error; - if (!d->open(d->fileName, mode, error)) { - setErrorString(error); - return false; - } - return QIODevice::open(mode); -} - -bool QuaGzipFile::open(int fd, QIODevice::OpenMode mode) -{ - QString error; - if (!d->open(fd, mode, error)) { - setErrorString(error); - return false; - } - return QIODevice::open(mode); -} - -bool QuaGzipFile::flush() -{ - return gzflush(d->gzd, Z_SYNC_FLUSH) == Z_OK; -} - -void QuaGzipFile::close() -{ - QIODevice::close(); - gzclose(d->gzd); -} - -qint64 QuaGzipFile::readData(char *data, qint64 maxSize) -{ - return gzread(d->gzd, (voidp)data, (unsigned)maxSize); -} - -qint64 QuaGzipFile::writeData(const char *data, qint64 maxSize) -{ - if (maxSize == 0) - return 0; - int written = gzwrite(d->gzd, (voidp)data, (unsigned)maxSize); - if (written == 0) - return -1; - else - return written; -} diff --git a/quazip/quagzipfile.h b/quazip/quagzipfile.h deleted file mode 100644 --- a/quazip/quagzipfile.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef QUAZIP_QUAGZIPFILE_H -#define QUAZIP_QUAGZIPFILE_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include "quazip_global.h" - -#include - -class QuaGzipFilePrivate; - -/// GZIP file -/** - This class is a wrapper around GZIP file access functions in zlib. Unlike QuaZip classes, it doesn't allow reading from a GZIP file opened as QIODevice, for example, if your GZIP file is in QBuffer. It only provides QIODevice access to a GZIP file contents, but the GZIP file itself must be identified by its name on disk or by descriptor id. - */ -class QUAZIP_EXPORT QuaGzipFile: public QIODevice { - Q_OBJECT -public: - /// Empty constructor. - /** - Must call setFileName() before trying to open. - */ - QuaGzipFile(); - /// Empty constructor with a parent. - /** - Must call setFileName() before trying to open. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(QObject *parent); - /// Constructor. - /** - \param fileName The name of the GZIP file. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(const QString &fileName, QObject *parent = NULL); - /// Destructor. - virtual ~QuaGzipFile(); - /// Sets the name of the GZIP file to be opened. - void setFileName(const QString& fileName); - /// Returns the name of the GZIP file. - QString getFileName() const; - /// Returns true. - /** - Strictly speaking, zlib supports seeking for GZIP files, but it is - poorly implemented, because there is no way to implement it - properly. For reading, seeking backwards is very slow, and for - writing, it is downright impossible. Therefore, QuaGzipFile does not - support seeking at all. - */ - virtual bool isSequential() const; - /// Opens the file. - /** - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(QIODevice::OpenMode mode); - /// Opens the file. - /** - \overload - \param fd The file descriptor to read/write the GZIP file from/to. - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(int fd, QIODevice::OpenMode mode); - /// Flushes data to file. - /** - The data is written using Z_SYNC_FLUSH mode. Doesn't make any sense - when reading. - */ - virtual bool flush(); - /// Closes the file. - virtual void close(); -protected: - /// Implementation of QIODevice::readData(). - virtual qint64 readData(char *data, qint64 maxSize); - /// Implementation of QIODevice::writeData(). - virtual qint64 writeData(const char *data, qint64 maxSize); -private: - // not implemented by design to disable copy - QuaGzipFile(const QuaGzipFile &that); - QuaGzipFile& operator=(const QuaGzipFile &that); - QuaGzipFilePrivate *d; -}; - -#endif // QUAZIP_QUAGZIPFILE_H diff --git a/quazip/quazip.pri b/quazip/quazip.pri --- a/quazip/quazip.pri +++ b/quazip/quazip.pri @@ -1,33 +1,21 @@ INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += \ - $$PWD/minizip_crypt.h \ $$PWD/ioapi.h \ - $$PWD/JlCompress.h \ - $$PWD/quaadler32.h \ - $$PWD/quachecksum32.h \ - $$PWD/quacrc32.h \ - $$PWD/quagzipfile.h \ $$PWD/quaziodevice.h \ - $$PWD/quazipdir.h \ $$PWD/quazipfile.h \ $$PWD/quazipfileinfo.h \ $$PWD/quazip_global.h \ $$PWD/quazip.h \ $$PWD/quazipnewinfo.h \ $$PWD/unzip.h \ $$PWD/zip.h SOURCES += $$PWD/qioapi.cpp \ - $$PWD/JlCompress.cpp \ - $$PWD/quaadler32.cpp \ - $$PWD/quacrc32.cpp \ - $$PWD/quagzipfile.cpp \ $$PWD/quaziodevice.cpp \ $$PWD/quazip.cpp \ - $$PWD/quazipdir.cpp \ $$PWD/quazipfile.cpp \ $$PWD/quazipfileinfo.cpp \ $$PWD/quazipnewinfo.cpp \ $$PWD/unzip.c \ $$PWD/zip.c diff --git a/quazip/quazipdir.cpp b/quazip/quazipdir.cpp deleted file mode 100644 --- a/quazip/quazipdir.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quazipdir.h" - -#include -#include - -/// \cond internal -class QuaZipDirPrivate: public QSharedData { - friend class QuaZipDir; -private: - QuaZipDirPrivate(QuaZip *zip, const QString &dir = QString()): - zip(zip), dir(dir), caseSensitivity(QuaZip::csDefault), - filter(QDir::NoFilter), sorting(QDir::NoSort) {} - QuaZip *zip; - QString dir; - QuaZip::CaseSensitivity caseSensitivity; - QDir::Filters filter; - QStringList nameFilters; - QDir::SortFlags sorting; - template - bool entryInfoList(QStringList nameFilters, QDir::Filters filter, - QDir::SortFlags sort, TFileInfoList &result) const; - inline QString simplePath() const {return QDir::cleanPath(dir);} -}; -/// \endcond - -QuaZipDir::QuaZipDir(const QuaZipDir &that): - d(that.d) -{ -} - -QuaZipDir::QuaZipDir(QuaZip *zip, const QString &dir): - d(new QuaZipDirPrivate(zip, dir)) -{ - if (d->dir.startsWith('/')) - d->dir = d->dir.mid(1); -} - -QuaZipDir::~QuaZipDir() -{ -} - -bool QuaZipDir::operator==(const QuaZipDir &that) -{ - return d->zip == that.d->zip && d->dir == that.d->dir; -} - -QuaZipDir& QuaZipDir::operator=(const QuaZipDir &that) -{ - this->d = that.d; - return *this; -} - -QString QuaZipDir::operator[](int pos) const -{ - return entryList().at(pos); -} - -QuaZip::CaseSensitivity QuaZipDir::caseSensitivity() const -{ - return d->caseSensitivity; -} - -bool QuaZipDir::cd(const QString &directoryName) -{ - if (directoryName == "/") { - d->dir = ""; - return true; - } - QString dirName = directoryName; - if (dirName.endsWith('/')) - dirName.chop(1); - if (dirName.contains('/')) { - QuaZipDir dir(*this); - if (dirName.startsWith('/')) { -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::cd(%s): going to /", - dirName.toUtf8().constData()); -#endif - if (!dir.cd("/")) - return false; - } - QStringList path = dirName.split('/', QString::SkipEmptyParts); - for (QStringList::const_iterator i = path.constBegin(); - i != path.end(); - ++i) { - const QString &step = *i; -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::cd(%s): going to %s", - dirName.toUtf8().constData(), - step.toUtf8().constData()); -#endif - if (!dir.cd(step)) - return false; - } - d->dir = dir.path(); - return true; - } else { // no '/' - if (dirName == ".") { - return true; - } else if (dirName == "..") { - if (isRoot()) { - return false; - } else { - int slashPos = d->dir.lastIndexOf('/'); - if (slashPos == -1) { - d->dir = ""; - } else { - d->dir = d->dir.left(slashPos); - } - return true; - } - } else { // a simple subdirectory - if (exists(dirName)) { - if (isRoot()) - d->dir = dirName; - else - d->dir += "/" + dirName; - return true; - } else { - return false; - } - } - } -} - -bool QuaZipDir::cdUp() -{ - return cd(".."); -} - -uint QuaZipDir::count() const -{ - return entryList().count(); -} - -QString QuaZipDir::dirName() const -{ - return QDir(d->dir).dirName(); -} - -QuaZipFileInfo64 QuaZipDir_getFileInfo(QuaZip *zip, bool *ok, - const QString &relativeName, - bool isReal) -{ - QuaZipFileInfo64 info; - if (isReal) { - *ok = zip->getCurrentFileInfo(&info); - } else { - *ok = true; - info.compressedSize = 0; - info.crc = 0; - info.diskNumberStart = 0; - info.externalAttr = 0; - info.flags = 0; - info.internalAttr = 0; - info.method = 0; - info.uncompressedSize = 0; - info.versionCreated = info.versionNeeded = 0; - } - info.name = relativeName; - return info; -} - -static void QuaZipDir_convertInfoList(const QList &from, - QList &to) -{ - to = from; -} - -static void QuaZipDir_convertInfoList(const QList &from, - QStringList &to) -{ - to.clear(); - for (QList::const_iterator i = from.constBegin(); - i != from.constEnd(); - ++i) { - to.append(i->name); - } -} - -static void QuaZipDir_convertInfoList(const QList &from, - QList &to) -{ - to.clear(); - for (QList::const_iterator i = from.constBegin(); - i != from.constEnd(); - ++i) { - QuaZipFileInfo info32; - i->toQuaZipFileInfo(info32); - to.append(info32); - } -} - -/// \cond internal -/** - An utility class to restore the current file. - */ -class QuaZipDirRestoreCurrent { -public: - inline QuaZipDirRestoreCurrent(QuaZip *zip): - zip(zip), currentFile(zip->getCurrentFileName()) {} - inline ~QuaZipDirRestoreCurrent() - { - zip->setCurrentFile(currentFile); - } -private: - QuaZip *zip; - QString currentFile; -}; -/// \endcond - -/// \cond internal -class QuaZipDirComparator -{ - private: - QDir::SortFlags sort; - static QString getExtension(const QString &name); - int compareStrings(const QString &string1, const QString &string2); - public: - inline QuaZipDirComparator(QDir::SortFlags sort): sort(sort) {} - bool operator()(const QuaZipFileInfo64 &info1, const QuaZipFileInfo64 &info2); -}; - -QString QuaZipDirComparator::getExtension(const QString &name) -{ - if (name.endsWith('.') || name.indexOf('.', 1) == -1) { - return ""; - } else { - return name.mid(name.lastIndexOf('.') + 1); - } - -} - -int QuaZipDirComparator::compareStrings(const QString &string1, - const QString &string2) -{ - if (sort & QDir::LocaleAware) { - if (sort & QDir::IgnoreCase) { - return string1.toLower().localeAwareCompare(string2.toLower()); - } else { - return string1.localeAwareCompare(string2); - } - } else { - return string1.compare(string2, (sort & QDir::IgnoreCase) - ? Qt::CaseInsensitive : Qt::CaseSensitive); - } -} - -bool QuaZipDirComparator::operator()(const QuaZipFileInfo64 &info1, - const QuaZipFileInfo64 &info2) -{ - QDir::SortFlags order = sort - & (QDir::Name | QDir::Time | QDir::Size | QDir::Type); - if ((sort & QDir::DirsFirst) == QDir::DirsFirst - || (sort & QDir::DirsLast) == QDir::DirsLast) { - if (info1.name.endsWith('/') && !info2.name.endsWith('/')) - return (sort & QDir::DirsFirst) == QDir::DirsFirst; - else if (!info1.name.endsWith('/') && info2.name.endsWith('/')) - return (sort & QDir::DirsLast) == QDir::DirsLast; - } - bool result; - int extDiff; - switch (order) { - case QDir::Name: - result = compareStrings(info1.name, info2.name) < 0; - break; - case QDir::Type: - extDiff = compareStrings(getExtension(info1.name), - getExtension(info2.name)); - if (extDiff == 0) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = extDiff < 0; - } - break; - case QDir::Size: - if (info1.uncompressedSize == info2.uncompressedSize) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = info1.uncompressedSize < info2.uncompressedSize; - } - break; - case QDir::Time: - if (info1.dateTime == info2.dateTime) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = info1.dateTime < info2.dateTime; - } - break; - default: - qWarning("QuaZipDirComparator(): Invalid sort mode 0x%2X", - static_cast(sort)); - return false; - } - return (sort & QDir::Reversed) ? !result : result; -} - -template -bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters, - QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result) const -{ - QString basePath = simplePath(); - if (!basePath.isEmpty()) - basePath += "/"; - int baseLength = basePath.length(); - result.clear(); - QuaZipDirRestoreCurrent saveCurrent(zip); - if (!zip->goToFirstFile()) { - return zip->getZipError() == UNZ_OK; - } - QDir::Filters fltr = filter; - if (fltr == QDir::NoFilter) - fltr = this->filter; - if (fltr == QDir::NoFilter) - fltr = QDir::AllEntries; - QStringList nmfltr = nameFilters; - if (nmfltr.isEmpty()) - nmfltr = this->nameFilters; - QSet dirsFound; - QList list; - do { - QString name = zip->getCurrentFileName(); - if (!name.startsWith(basePath)) - continue; - QString relativeName = name.mid(baseLength); - if (relativeName.isEmpty()) - continue; - bool isDir = false; - bool isReal = true; - if (relativeName.contains('/')) { - int indexOfSlash = relativeName.indexOf('/'); - // something like "subdir/" - isReal = indexOfSlash == relativeName.length() - 1; - relativeName = relativeName.left(indexOfSlash + 1); - if (dirsFound.contains(relativeName)) - continue; - isDir = true; - } - dirsFound.insert(relativeName); - if ((fltr & QDir::Dirs) == 0 && isDir) - continue; - if ((fltr & QDir::Files) == 0 && !isDir) - continue; - if (!nmfltr.isEmpty() && !QDir::match(nmfltr, relativeName)) - continue; - bool ok; - QuaZipFileInfo64 info = QuaZipDir_getFileInfo(zip, &ok, relativeName, - isReal); - if (!ok) { - return false; - } - list.append(info); - } while (zip->goToNextFile()); - QDir::SortFlags srt = sort; - if (srt == QDir::NoSort) - srt = sorting; -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDirPrivate::entryInfoList(): before sort:"); - foreach (QuaZipFileInfo64 info, list) { - qDebug("%s\t%s", info.name.toUtf8().constData(), - info.dateTime.toString(Qt::ISODate).toUtf8().constData()); - } -#endif - if (srt != QDir::NoSort && (srt & QDir::Unsorted) != QDir::Unsorted) { - if (QuaZip::convertCaseSensitivity(caseSensitivity) - == Qt::CaseInsensitive) - srt |= QDir::IgnoreCase; - QuaZipDirComparator lessThan(srt); - qSort(list.begin(), list.end(), lessThan); - } - QuaZipDir_convertInfoList(list, result); - return true; -} - -/// \endcond - -QList QuaZipDir::entryInfoList(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QList(); -} - -QList QuaZipDir::entryInfoList(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryInfoList(QStringList(), filters, sort); -} - -QList QuaZipDir::entryInfoList64(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QList(); -} - -QList QuaZipDir::entryInfoList64(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryInfoList64(QStringList(), filters, sort); -} - -QStringList QuaZipDir::entryList(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QStringList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QStringList(); -} - -QStringList QuaZipDir::entryList(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryList(QStringList(), filters, sort); -} - -bool QuaZipDir::exists(const QString &filePath) const -{ - if (filePath == "/" || filePath.isEmpty()) - return true; - QString fileName = filePath; - if (fileName.endsWith('/')) - fileName.chop(1); - if (fileName.contains('/')) { - QFileInfo fileInfo(fileName); -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::exists(): fileName=%s, fileInfo.fileName()=%s, " - "fileInfo.path()=%s", fileName.toUtf8().constData(), - fileInfo.fileName().toUtf8().constData(), - fileInfo.path().toUtf8().constData()); -#endif - QuaZipDir dir(*this); - return dir.cd(fileInfo.path()) && dir.exists(fileInfo.fileName()); - } else { - if (fileName == "..") { - return !isRoot(); - } else if (fileName == ".") { - return true; - } else { - QStringList entries = entryList(QDir::AllEntries, QDir::NoSort); -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::exists(): looking for %s", - fileName.toUtf8().constData()); - for (QStringList::const_iterator i = entries.constBegin(); - i != entries.constEnd(); - ++i) { - qDebug("QuaZipDir::exists(): entry: %s", - i->toUtf8().constData()); - } -#endif - Qt::CaseSensitivity cs = QuaZip::convertCaseSensitivity( - d->caseSensitivity); - if (filePath.endsWith('/')) { - return entries.contains(filePath, cs); - } else { - return entries.contains(fileName, cs) - || entries.contains(fileName + "/", cs); - } - } - } -} - -bool QuaZipDir::exists() const -{ - return QuaZipDir(d->zip).exists(d->dir); -} - -QString QuaZipDir::filePath(const QString &fileName) const -{ - return QDir(d->dir).filePath(fileName); -} - -QDir::Filters QuaZipDir::filter() -{ - return d->filter; -} - -bool QuaZipDir::isRoot() const -{ - return d->simplePath().isEmpty(); -} - -QStringList QuaZipDir::nameFilters() const -{ - return d->nameFilters; -} - -QString QuaZipDir::path() const -{ - return d->dir; -} - -QString QuaZipDir::relativeFilePath(const QString &fileName) const -{ - return QDir("/" + d->dir).relativeFilePath(fileName); -} - -void QuaZipDir::setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity) -{ - d->caseSensitivity = caseSensitivity; -} - -void QuaZipDir::setFilter(QDir::Filters filters) -{ - d->filter = filters; -} - -void QuaZipDir::setNameFilters(const QStringList &nameFilters) -{ - d->nameFilters = nameFilters; -} - -void QuaZipDir::setPath(const QString &path) -{ - QString newDir = path; - if (newDir == "/") { - d->dir = ""; - } else { - if (newDir.endsWith('/')) - newDir.chop(1); - if (newDir.startsWith('/')) - newDir = newDir.mid(1); - d->dir = newDir; - } -} - -void QuaZipDir::setSorting(QDir::SortFlags sort) -{ - d->sorting = sort; -} - -QDir::SortFlags QuaZipDir::sorting() const -{ - return d->sorting; -} diff --git a/quazip/quazipdir.h b/quazip/quazipdir.h deleted file mode 100644 --- a/quazip/quazipdir.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef QUAZIP_QUAZIPDIR_H -#define QUAZIP_QUAZIPDIR_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -class QuaZipDirPrivate; - -#include "quazip.h" -#include "quazipfileinfo.h" -#include -#include -#include - -/// Provides ZIP archive navigation. -/** -* This class is modelled after QDir, and is designed to provide similar -* features for ZIP archives. -* -* The only significant difference from QDir is that the root path is not -* '/', but an empty string since that's how the file paths are stored in -* the archive. However, QuaZipDir understands the paths starting with -* '/'. It is important in a few places: -* -* - In the cd() function. -* - In the constructor. -* - In the exists() function. -* - In the relativePath() function. -* -* Note that since ZIP uses '/' on all platforms, the '\' separator is -* not supported. -*/ -class QUAZIP_EXPORT QuaZipDir { -private: - QSharedDataPointer d; -public: - /// The copy constructor. - QuaZipDir(const QuaZipDir &that); - /// Constructs a QuaZipDir instance pointing to the specified directory. - /** - If \a dir is not specified, points to the root of the archive. - The same happens if the \a dir is "/". - */ - QuaZipDir(QuaZip *zip, const QString &dir = QString()); - /// Destructor. - ~QuaZipDir(); - /// The assignment operator. - bool operator==(const QuaZipDir &that); - /// operator!= - /** - \return \c true if either this and \a that use different QuaZip - instances or if they point to different directories. - */ - inline bool operator!=(const QuaZipDir &that) {return !operator==(that);} - /// operator== - /** - \return \c true if both this and \a that use the same QuaZip - instance and point to the same directory. - */ - QuaZipDir& operator=(const QuaZipDir &that); - /// Returns the name of the entry at the specified position. - QString operator[](int pos) const; - /// Returns the current case sensitivity mode. - QuaZip::CaseSensitivity caseSensitivity() const; - /// Changes the 'current' directory. - /** - * If the path starts with '/', it is interpreted as an absolute - * path from the root of the archive. Otherwise, it is interpreted - * as a path relative to the current directory as was set by the - * previous cd() or the constructor. - * - * Note that the subsequent path() call will not return a path - * starting with '/' in all cases. - */ - bool cd(const QString &dirName); - /// Goes up. - bool cdUp(); - /// Returns the number of entries in the directory. - uint count() const; - /// Returns the current directory name. - /** - The name doesn't include the path. - */ - QString dirName() const; - /// Returns the list of the entries in the directory. - /** - \param nameFilters The list of file patterns to list, uses the same - syntax as QDir. - \param filters The entry type filters, only Files and Dirs are - accepted. - \param sort Sorting mode. - */ - QList entryInfoList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory. - /** - \overload - - The same as entryInfoList(QStringList(), filters, sort). - */ - QList entryInfoList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory with zip64 support. - /** - \param nameFilters The list of file patterns to list, uses the same - syntax as QDir. - \param filters The entry type filters, only Files and Dirs are - accepted. - \param sort Sorting mode. - */ - QList entryInfoList64(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory with zip64 support. - /** - \overload - - The same as entryInfoList64(QStringList(), filters, sort). - */ - QList entryInfoList64(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - The same as entryInfoList(nameFilters, filters, sort), but only - returns entry names. - */ - QStringList entryList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - \overload - - The same as entryList(QStringList(), filters, sort). - */ - QStringList entryList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns \c true if the entry with the specified name exists. - /** - The ".." is considered to exist if the current directory - is not root. The "." and "/" are considered to - always exist. Paths starting with "/" are relative to - the archive root, other paths are relative to the current dir. - */ - bool exists(const QString &fileName) const; - /// Return \c true if the directory pointed by this QuaZipDir exists. - bool exists() const; - /// Returns the full path to the specified file. - /** - Doesn't check if the file actually exists. - */ - QString filePath(const QString &fileName) const; - /// Returns the default filter. - QDir::Filters filter(); - /// Returns if the QuaZipDir points to the root of the archive. - /** - Not that the root path is the empty string, not '/'. - */ - bool isRoot() const; - /// Return the default name filter. - QStringList nameFilters() const; - /// Returns the path to the current dir. - /** - The path never starts with '/', and the root path is an empty - string. - */ - QString path() const; - /// Returns the path to the specified file relative to the current dir. - /** - * This function is mostly useless, provided only for the sake of - * completeness. - * - * @param fileName The path to the file, should start with "/" - * if relative to the archive root. - * @return Path relative to the current dir. - */ - QString relativeFilePath(const QString &fileName) const; - /// Sets the default case sensitivity mode. - void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity); - /// Sets the default filter. - void setFilter(QDir::Filters filters); - /// Sets the default name filter. - void setNameFilters(const QStringList &nameFilters); - /// Goes to the specified path. - /** - The difference from cd() is that this function never checks if the - path actually exists and doesn't use relative paths, so it's - possible to go to the root directory with setPath(""). - - Note that this function still chops the trailing and/or leading - '/' and treats a single '/' as the root path (path() will still - return an empty string). - */ - void setPath(const QString &path); - /// Sets the default sorting mode. - void setSorting(QDir::SortFlags sort); - /// Returns the default sorting mode. - QDir::SortFlags sorting() const; -}; - -#endif // QUAZIP_QUAZIPDIR_H diff --git a/quazip/unzip.c b/quazip/unzip.c --- a/quazip/unzip.c +++ b/quazip/unzip.c @@ -1,2150 +1,2020 @@ /* unzip.c -- IO for uncompress .zip files using zlib Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64 Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Modifications for QIODevice support and other QuaZIP fixes Copyright (C) 2005-2014 Sergey A. Tachenov For more info read MiniZip_info.txt Modifications for static code analysis report Copyright (C) 2016 Intel Deutschland GmbH ------------------------------------------------------------------------------------ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of compatibility with older software. The following is from the original crypt.c. Code woven in by Terry Thorsen 1/2003. Copyright (c) 1990-2000 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html crypt.c (full version) by Info-ZIP. Last revised: [see minizip_crypt.h] The encryption/decryption parts of this source code (as opposed to the non-echoing password parts) were originally written in Europe. The whole source package can be freely distributed, including from the USA. (Prior to January 2000, re-export from the US was a violation of US law.) This encryption code is a direct transcription of the algorithm from Roger Schlafly, described by Phil Katz in the file appnote.txt. This file (appnote.txt) is distributed with the PKZIP program (even in the version without encryption capabilities). ------------------------------------------------------------------------------------ Changes in unzip.c 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* 2007-2008 - Even Rouault - Remove old C style function prototypes 2007-2008 - Even Rouault - Add unzip support for ZIP64 Copyright (C) 2007-2008 Even Rouault Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G should only read the compressed/uncompressed size from the Zip64 format if the size from normal header was 0xFFFFFFFF Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) Patch created by Daniel Borca Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson */ #include #include #include #include "zlib.h" #if (ZLIB_VERNUM < 0x1270) typedef uLongf z_crc_t; #endif #include "unzip.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef CASESENSITIVITYDEFAULT_NO # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) # define CASESENSITIVITYDEFAULT_NO # endif #endif #ifndef UNZ_BUFSIZE #define UNZ_BUFSIZE (16384) #endif #ifndef UNZ_MAXFILENAMEINZIP #define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE # define TRYFREE(p) {if (p) free(p);} #endif #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ } unz_file_info64_internal; /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ typedef struct { char *read_buffer; /* internal buffer for compressed data */ z_stream stream; /* zLib stream structure for inflate */ -#ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ -#endif - ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ uLong stream_initialised; /* flag set if stream structure is initialised*/ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ uInt size_local_extrafield;/* size of the local extra field */ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ ZPOS64_T total_out_64; uLong crc32; /* crc32 of all data uncompressed */ uLong crc32_wait; /* crc32 we must obtain after decompress all */ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ zlib_filefunc64_32_def z_filefunc; voidpf filestream; /* io structore of the zipfile */ uLong compression_method; /* compression method (0==store) */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ int raw; } file_in_zip64_read_info_s; /* unz64_s contain internal information about the zipfile */ typedef struct { zlib_filefunc64_32_def z_filefunc; int is64bitOpenFunction; voidpf filestream; /* io structore of the zipfile */ unz_global_info64 gi; /* public global information */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ZPOS64_T num_file; /* number of the current file in the zipfile*/ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ ZPOS64_T central_pos; /* position of the beginning of the central dir*/ ZPOS64_T size_central_dir; /* size of the central directory */ ZPOS64_T offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ unz_file_info64 cur_file_info; /* public info about the current file in zip*/ unz_file_info64_internal cur_file_info_internal; /* private info about it*/ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current file if we are decompressing it */ int encrypted; int isZip64; unsigned flags; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const z_crc_t FAR * pcrc_32_tab; -# endif } unz64_s; -#ifndef NOUNCRYPT -#include "minizip_crypt.h" -#endif - /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. */ local int unz64local_getByte OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) { unsigned char c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); if (err==1) { *pi = (int)c; return UNZ_OK; } else { if (ZERROR64(*pzlib_filefunc_def,filestream)) return UNZ_ERRNO; else return UNZ_EOF; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int unz64local_getShort OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { uLong x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<8; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } local int unz64local_getLong OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { uLong x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<8; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<16; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<24; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } local int unz64local_getLong64 OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { ZPOS64_T x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (ZPOS64_T)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<8; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<16; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<24; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<32; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<40; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<48; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<56; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } /* My own strcmpi / strcasecmp */ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) { for (;;) { char c1=*(fileName1++); char c2=*(fileName2++); if ((c1>='a') && (c1<='z')) c1 -= 0x20; if ((c2>='a') && (c2<='z')) c2 -= 0x20; if (c1=='\0') return ((c2=='\0') ? 0 : -1); if (c2=='\0') return 1; if (c1c2) return 1; } } #ifdef CASESENSITIVITYDEFAULT_NO #define CASESENSITIVITYDEFAULTVALUE 2 #else #define CASESENSITIVITYDEFAULTVALUE 1 #endif #ifndef STRCMPCASENOSENTIVEFUNCTION #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal #endif /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) */ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity) { if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); } #ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound; } /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir64 OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; uLong uL; ZPOS64_T relativeOffset; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); if (uPosFound == 0) return 0; /* Zip64 end of central directory locator */ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature, already checked */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 0) return 0; /* relative offset of the zip64 end of central directory record */ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) return 0; /* total number of disks */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 1) return 0; /* Goto end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 0x06064b50) return 0; return relativeOffset; } /* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer "zlib/zlib114.zip". If the zipfile cannot be opened (file doesn't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ extern unzFile unzOpenInternal (voidpf file, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, int is64bitOpenFunction, unsigned flags) { unz64_s us; unz64_s *s; ZPOS64_T central_pos; uLong uL; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int err=UNZ_OK; if (unz_copyright[0]!=' ') return NULL; us.flags = flags; us.z_filefunc.zseek32_file = NULL; us.z_filefunc.ztell32_file = NULL; if (pzlib_filefunc64_32_def==NULL) fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64); else us.z_filefunc = *pzlib_filefunc64_32_def; us.is64bitOpenFunction = is64bitOpenFunction; us.filestream = ZOPEN64(us.z_filefunc, file, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); if (us.filestream==NULL) return NULL; central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); if (central_pos) { uLong uS; ZPOS64_T uL64; us.isZip64 = 1; if (ZSEEK64(us.z_filefunc, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; /* size of zip64 end of central directory record */ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) err=UNZ_ERRNO; /* version made by */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) err=UNZ_ERRNO; /* version needed to extract */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central directory on this disk */ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central directory */ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) err=UNZ_ERRNO; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) err=UNZ_ERRNO; us.gi.size_comment = 0; } else { central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); if (central_pos==0) err=UNZ_ERRNO; us.isZip64 = 0; if (ZSEEK64(us.z_filefunc, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.gi.number_entry = uL; /* total number of entries in the central dir */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; number_entry_CD = uL; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.size_central_dir = uL; /* offset of start of central directory with respect to the starting disk number */ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.offset_central_dir = uL; /* zipfile comment length */ if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) err=UNZ_ERRNO; } if ((central_pospfile_in_zip_read!=NULL) unzCloseCurrentFile(file); if ((s->flags & UNZ_AUTO_CLOSE) != 0) ZCLOSE64(s->z_filefunc, s->filestream); else ZFAKECLOSE64(s->z_filefunc, s->filestream); TRYFREE(s); return UNZ_OK; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; *pglobal_info=s->gi; return UNZ_OK; } extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; /* to do : check if number_entry is not truncated */ pglobal_info32->number_entry = (uLong)s->gi.number_entry; pglobal_info32->size_comment = s->gi.size_comment; return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easilty) */ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) { ZPOS64_T uDate; uDate = (ZPOS64_T)(ulDosDate>>16); ptm->tm_mday = (uInt)(uDate&0x1f) ; ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; } /* Get Info about the current file in the zipfile, with internal only info */ local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, unz_file_info64 *pfile_info, unz_file_info64_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); local int unz64local_GetCurrentFileInfoInternal (unzFile file, unz_file_info64 *pfile_info, unz_file_info64_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) { unz64_s* s; unz_file_info64 file_info; unz_file_info64_internal file_info_internal; int err=UNZ_OK; uLong uMagic; ZPOS64_T llSeek=0; uLong uL; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (ZSEEK64(s->z_filefunc, s->filestream, s->pos_in_central_dir+s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* we check the magic */ if (err==UNZ_OK) { if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; } if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) err=UNZ_ERRNO; unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info.compressed_size = uL; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info.uncompressed_size = uL; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) err=UNZ_ERRNO; /* relative offset of local header */ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info_internal.offset_curfile = uL; llSeek+=file_info.size_filename; if ((err==UNZ_OK) && (szFileName!=NULL)) { uLong uSizeRead ; if (file_info.size_filename0) && (fileNameBufferSize>0)) if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; llSeek -= uSizeRead; } /* Read extrafield */ if ((err==UNZ_OK) && (extraField!=NULL)) { ZPOS64_T uSizeRead ; if (file_info.size_file_extraz_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) llSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; llSeek += file_info.size_file_extra - (uLong)uSizeRead; } else llSeek += file_info.size_file_extra; if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) { uLong acc = 0; /* since lSeek now points to after the extra field we need to move back */ llSeek -= file_info.size_file_extra; if (llSeek!=0) { if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) llSeek=0; else err=UNZ_ERRNO; } while(acc < file_info.size_file_extra) { uLong headerId; uLong dataSize; if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) err=UNZ_ERRNO; /* ZIP64 extra fields */ if (headerId == 0x0001) { uLong uL; if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu) { if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) err=UNZ_ERRNO; } if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu) { if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) err=UNZ_ERRNO; } if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu) { /* Relative Header offset */ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) err=UNZ_ERRNO; } if(file_info.disk_num_start == 0xFFFFFFFFu) { /* Disk Start Number */ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; } } else { if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) err=UNZ_ERRNO; } acc += 2 + 2 + dataSize; } } if ((err==UNZ_OK) && (szComment!=NULL)) { uLong uSizeRead ; if (file_info.size_file_commentz_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) llSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; llSeek+=file_info.size_file_comment - uSizeRead; } else llSeek+=file_info.size_file_comment; if ((err==UNZ_OK) && (pfile_info!=NULL)) *pfile_info=file_info; if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) *pfile_info_internal=file_info_internal; return err; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, unz_file_info64 * pfile_info, char * szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize) { return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, szComment,commentBufferSize); } extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, unz_file_info * pfile_info, char * szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize) { int err; unz_file_info64 file_info64; err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, szComment,commentBufferSize); if (err==UNZ_OK && pfile_info != NULL) { pfile_info->version = file_info64.version; pfile_info->version_needed = file_info64.version_needed; pfile_info->flag = file_info64.flag; pfile_info->compression_method = file_info64.compression_method; pfile_info->dosDate = file_info64.dosDate; pfile_info->crc = file_info64.crc; pfile_info->size_filename = file_info64.size_filename; pfile_info->size_file_extra = file_info64.size_file_extra; pfile_info->size_file_comment = file_info64.size_file_comment; pfile_info->disk_num_start = file_info64.disk_num_start; pfile_info->internal_fa = file_info64.internal_fa; pfile_info->external_fa = file_info64.external_fa; pfile_info->tmu_date = file_info64.tmu_date, pfile_info->compressed_size = (uLong)file_info64.compressed_size; pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; } return err; } /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ extern int ZEXPORT unzGoToFirstFile (unzFile file) { int err=UNZ_OK; unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; s->pos_in_central_dir=s->offset_central_dir; s->num_file=0; err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ extern int ZEXPORT unzGoToNextFile (unzFile file) { unz64_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzipStringFileNameCompare return value : UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) { unz64_s* s; int err; /* We remember the 'current' position in the file so that we can jump * back there if we fail. */ unz_file_info64 cur_file_infoSaved; unz_file_info64_internal cur_file_info_internalSaved; ZPOS64_T num_fileSaved; ZPOS64_T pos_in_central_dirSaved; if (file==NULL) return UNZ_PARAMERROR; if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; /* Save the current state */ num_fileSaved = s->num_file; pos_in_central_dirSaved = s->pos_in_central_dir; cur_file_infoSaved = s->cur_file_info; cur_file_info_internalSaved = s->cur_file_info_internal; err = unzGoToFirstFile(file); while (err == UNZ_OK) { char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; err = unzGetCurrentFileInfo64(file,NULL, szCurrentFileName,sizeof(szCurrentFileName)-1, NULL,0,NULL,0); if (err == UNZ_OK) { if (unzStringFileNameCompare(szCurrentFileName, szFileName,iCaseSensitivity)==0) return UNZ_OK; err = unzGoToNextFile(file); } } /* We failed, so restore the state of the 'current file' to where we * were. */ s->num_file = num_fileSaved ; s->pos_in_central_dir = pos_in_central_dirSaved ; s->cur_file_info = cur_file_infoSaved; s->cur_file_info_internal = cur_file_info_internalSaved; return err; } /* /////////////////////////////////////////// // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) // I need random access // // Further optimization could be realized by adding an ability // to cache the directory in memory. The goal being a single // comprehensive file read to put the file I need in a memory. */ /* typedef struct unz_file_pos_s { ZPOS64_T pos_in_zip_directory; // offset in file ZPOS64_T num_of_file; // # of file } unz_file_pos; */ extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { unz64_s* s; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; file_pos->pos_in_zip_directory = s->pos_in_central_dir; file_pos->num_of_file = s->num_file; return UNZ_OK; } extern int ZEXPORT unzGetFilePos( unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; int err = unzGetFilePos64(file,&file_pos64); if (err==UNZ_OK) { file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; file_pos->num_of_file = (uLong)file_pos64.num_of_file; } return err; } extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { unz64_s* s; int err; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; /* jump to the right spot */ s->pos_in_central_dir = file_pos->pos_in_zip_directory; s->num_file = file_pos->num_of_file; /* set the current file */ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); /* return results */ s->current_file_ok = (err == UNZ_OK); return err; } extern int ZEXPORT unzGoToFilePos( unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; if (file_pos == NULL) return UNZ_PARAMERROR; file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; file_pos64.num_of_file = file_pos->num_of_file; return unzGoToFilePos64(file,&file_pos64); } /* Unzip Helper Functions - should be here? */ /*///////////////////////////////////////// */ /* Read the local header of the current zipfile Check the coherency of the local header and info in the end of central directory about this file store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, ZPOS64_T * poffset_local_extrafield, uInt * psize_local_extrafield) { uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (err==UNZ_OK) { if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x04034b50) err=UNZ_BADZIPFILE; } if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; /* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) err=UNZ_BADZIPFILE; */ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) err=UNZ_BADZIPFILE; if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ err=UNZ_ERRNO; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ err=UNZ_ERRNO; else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ err=UNZ_ERRNO; else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) err=UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) err=UNZ_ERRNO; *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; } /* Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, int* level, int raw, const char* password) { int err=UNZ_OK; uInt iSizeVar; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else if (password != NULL) return UNZ_PARAMERROR; -# endif if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_PARAMERROR; if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile(file); if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; pfile_in_zip_read_info->pos_local_extrafield=0; pfile_in_zip_read_info->raw=raw; if (pfile_in_zip_read_info->read_buffer==NULL) { TRYFREE(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } pfile_in_zip_read_info->stream_initialised=0; if (method!=NULL) *method = (int)s->cur_file_info.compression_method; if (level!=NULL) { *level = 6; switch (s->cur_file_info.flag & 0x06) { case 6 : *level = 1; break; case 4 : *level = 2; break; case 2 : *level = 9; break; } } if ((s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; pfile_in_zip_read_info->crc32=0; pfile_in_zip_read_info->total_out_64=0; pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; pfile_in_zip_read_info->filestream=s->filestream; pfile_in_zip_read_info->z_filefunc=s->z_filefunc; pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; pfile_in_zip_read_info->stream.total_out = 0; - if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) - { -#ifdef HAVE_BZIP2 - pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; - pfile_in_zip_read_info->bstream.bzfree = (free_func)0; - pfile_in_zip_read_info->bstream.opaque = (voidpf)0; - pfile_in_zip_read_info->bstream.state = (voidpf)0; - - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } -#else - pfile_in_zip_read_info->raw=1; -#endif - } - else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) { pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; pfile_in_zip_read_info->stream.zfree = (free_func)0; pfile_in_zip_read_info->stream.opaque = (voidpf)0; pfile_in_zip_read_info->stream.next_in = 0; pfile_in_zip_read_info->stream.avail_in = 0; err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); if (err == Z_OK) pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; else { TRYFREE(pfile_in_zip_read_info->read_buffer); TRYFREE(pfile_in_zip_read_info); return err; } /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. * In unzip, i don't wait absolutely Z_STREAM_END because I known the * size of both compressed and uncompressed data */ } pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size ; pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size ; pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; s->encrypted = 0; -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - return UNZ_OK; } extern int ZEXPORT unzOpenCurrentFile (unzFile file) { return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) { return unzOpenCurrentFile3(file, NULL, NULL, 0, password); } extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) { return unzOpenCurrentFile3(file, method, level, raw, NULL); } /** Addition for GDAL : START */ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; s=(unz64_s*)file; if (file==NULL) return 0; /*UNZ_PARAMERROR; */ pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return 0; /*UNZ_PARAMERROR; */ return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile; } /** Addition for GDAL : END */ /* Read bytes from the current file. buf contain buffer where data must be copied len the size of buf. return the number of byte copied if somes bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) { int err=UNZ_OK; uInt iRead = 0; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; pfile_in_zip_read_info->stream.avail_out = (uInt)len; if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw))) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; if ((len>pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw)) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in; while (pfile_in_zip_read_info->stream.avail_out>0) { if ((pfile_in_zip_read_info->stream.avail_in==0) && (pfile_in_zip_read_info->rest_read_compressed>0)) { uInt uReadThis = UNZ_BUFSIZE; if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; if (uReadThis == 0) return UNZ_EOF; if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis)!=uReadThis) return UNZ_ERRNO; -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; pfile_in_zip_read_info->rest_read_compressed-=uReadThis; pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer; pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; } if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) { uInt uDoCopy,i ; if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) return (iRead==0) ? UNZ_EOF : iRead; if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) uDoCopy = pfile_in_zip_read_info->stream.avail_out ; else uDoCopy = pfile_in_zip_read_info->stream.avail_in ; for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy); pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; pfile_in_zip_read_info->stream.next_out += uDoCopy; pfile_in_zip_read_info->stream.next_in += uDoCopy; pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } - else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) - { -#ifdef HAVE_BZIP2 - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - - pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; - pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; - pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; - pfile_in_zip_read_info->bstream.total_in_hi32 = 0; - pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; - pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; - pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; - pfile_in_zip_read_info->bstream.total_out_hi32 = 0; - - uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; - bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; - - err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); - - uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); - pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; - pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; - pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; - pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; - pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; - pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; - - if (err==BZ_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=BZ_OK) - break; -#endif - } /* end Z_BZIP2ED */ else { uInt uAvailOutBefore,uAvailOutAfter; const Bytef *bufBefore; uInt uOutThis; int flush=Z_SYNC_FLUSH; uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out; bufBefore = pfile_in_zip_read_info->stream.next_out; err=inflate(&pfile_in_zip_read_info->stream,flush); if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) err = Z_DATA_ERROR; uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out; uOutThis = uAvailOutBefore - uAvailOutAfter; pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis); pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; iRead += uAvailOutBefore - uAvailOutAfter; if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; if (err!=Z_OK) break; } } if (err==Z_OK) return iRead; return err; } /* Give the current position in uncompressed data */ extern z_off_t ZEXPORT unztell (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; return (z_off_t)pfile_in_zip_read_info->stream.total_out; } extern ZPOS64_T ZEXPORT unztell64 (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return (ZPOS64_T)-1; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return (ZPOS64_T)-1; return pfile_in_zip_read_info->total_out_64; } /* return 1 if the end of file was reached, 0 elsewhere */ extern int ZEXPORT unzeof (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if (pfile_in_zip_read_info->rest_read_uncompressed == 0) return 1; else return 0; } /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) if buf==NULL, it return the size of the local extra field that can be read if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. the return value is the number of bytes copied in buf, or (if <0) the error code */ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; uInt read_now; ZPOS64_T size_to_read; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); if (buf==NULL) return (int)size_to_read; if (len>size_to_read) read_now = (uInt)size_to_read; else read_now = (uInt)len ; if (read_now==0) return 0; if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf,read_now)!=read_now) return UNZ_ERRNO; return (int)read_now; } /* Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ extern int ZEXPORT unzCloseCurrentFile (unzFile file) { int err=UNZ_OK; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) { if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) err=UNZ_CRCERROR; } TRYFREE(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) inflateEnd(&pfile_in_zip_read_info->stream); -#ifdef HAVE_BZIP2 - else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) - BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); -#endif pfile_in_zip_read_info->stream_initialised = 0; TRYFREE(pfile_in_zip_read_info); s->pfile_in_zip_read=NULL; return err; } /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) { unz64_s* s; uLong uReadThis ; if (file==NULL) return (int)UNZ_PARAMERROR; s=(unz64_s*)file; uReadThis = uSizeBuf; if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (uReadThis>0) { *szComment='\0'; if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) return UNZ_ERRNO; } if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } /* Additions by RX '2004 */ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { unz64_s* s; if (file==NULL) return 0; /*UNZ_PARAMERROR; */ s=(unz64_s*)file; if (!s->current_file_ok) return 0; if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) if (s->num_file==s->gi.number_entry) return 0; return s->pos_in_central_dir; } extern uLong ZEXPORT unzGetOffset (unzFile file) { ZPOS64_T offset64; if (file==NULL) return 0; /*UNZ_PARAMERROR; */ offset64 = unzGetOffset64(file); return (uLong)offset64; } extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { unz64_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; s->pos_in_central_dir = pos; s->num_file = s->gi.number_entry; /* hack */ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) { return unzSetOffset64(file,pos); } int ZEXPORT unzSetFlags(unzFile file, unsigned flags) { unz64_s* s; if (file == NULL) return UNZ_PARAMERROR; s = (unz64_s*)file; s->flags |= flags; return UNZ_OK; } int ZEXPORT unzClearFlags(unzFile file, unsigned flags) { unz64_s* s; if (file == NULL) return UNZ_PARAMERROR; s = (unz64_s*)file; s->flags &= ~flags; return UNZ_OK; } diff --git a/quazip/unzip.h b/quazip/unzip.h --- a/quazip/unzip.h +++ b/quazip/unzip.h @@ -1,458 +1,452 @@ /* unzip.h -- IO for uncompress .zip files using zlib Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64 Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) For more info read MiniZip_info.txt --------------------------------------------------------------------------------- Condition of use and distribution are the same than zlib : This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------------------------------- Changes See header of unzip64.c --------------------------------------------------------------------------- As per the requirement above, this file is plainly marked as modified by Sergey A. Tachenov. Most modifications include the I/O API redesign to support QIODevice interface. Some improvements and small fixes were also made. */ #ifndef _unz64_H #define _unz64_H #ifdef __cplusplus extern "C" { #endif #ifndef _ZLIB_H #include "zlib.h" #endif #ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif -#ifdef HAVE_BZIP2 -#include "bzlib.h" -#endif - -#define Z_BZIP2ED 12 - #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ typedef struct TagunzFile__ { int unused; } unzFile__; typedef unzFile__ *unzFile; #else typedef voidp unzFile; #endif #define UNZ_OK (0) #define UNZ_END_OF_LIST_OF_FILE (-100) #define UNZ_ERRNO (Z_ERRNO) #define UNZ_EOF (0) #define UNZ_PARAMERROR (-102) #define UNZ_BADZIPFILE (-103) #define UNZ_INTERNALERROR (-104) #define UNZ_CRCERROR (-105) #define UNZ_AUTO_CLOSE 0x01u #define UNZ_DEFAULT_FLAGS UNZ_AUTO_CLOSE /* tm_unz contain date/time info */ typedef struct tm_unz_s { uInt tm_sec; /* seconds after the minute - [0,59] */ uInt tm_min; /* minutes after the hour - [0,59] */ uInt tm_hour; /* hours since midnight - [0,23] */ uInt tm_mday; /* day of the month - [1,31] */ uInt tm_mon; /* months since January - [0,11] */ uInt tm_year; /* years - [1980..2044] */ } tm_unz; /* unz_global_info structure contain global data about the ZIPfile These data comes from the end of central dir */ typedef struct unz_global_info64_s { ZPOS64_T number_entry; /* total number of entries in the central dir on this disk */ uLong size_comment; /* size of the global comment of the zipfile */ } unz_global_info64; typedef struct unz_global_info_s { uLong number_entry; /* total number of entries in the central dir on this disk */ uLong size_comment; /* size of the global comment of the zipfile */ } unz_global_info; /* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_info64_s { uLong version; /* version made by 2 bytes */ uLong version_needed; /* version needed to extract 2 bytes */ uLong flag; /* general purpose bit flag 2 bytes */ uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ ZPOS64_T compressed_size; /* compressed size 8 bytes */ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ uLong disk_num_start; /* disk number start 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; } unz_file_info64; typedef struct unz_file_info_s { uLong version; /* version made by 2 bytes */ uLong version_needed; /* version needed to extract 2 bytes */ uLong flag; /* general purpose bit flag 2 bytes */ uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ uLong compressed_size; /* compressed size 4 bytes */ uLong uncompressed_size; /* uncompressed size 4 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ uLong disk_num_start; /* disk number start 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; } unz_file_info; extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, const char* fileName2, int iCaseSensitivity)); /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) */ extern unzFile ZEXPORT unzOpen OF((voidpf file)); extern unzFile ZEXPORT unzOpen64 OF((voidpf file)); /* Open a Zip file. path contain the full pathname (by example, on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip". If the zipfile cannot be opened (file don't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. the "64" function take a const void* pointer, because the path is just the value passed to the open64_file_func callback. Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* does not describe the reality */ extern unzFile ZEXPORT unzOpen2 OF((voidpf file, zlib_filefunc_def* pzlib_filefunc_def)); /* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ extern unzFile ZEXPORT unzOpen2_64 OF((voidpf file, zlib_filefunc64_def* pzlib_filefunc_def)); /* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ /* * Exported by Sergey A. Tachenov to implement some QuaZIP features. This * function MAY change signature in order to implement even more features. * You have been warned! * */ extern unzFile unzOpenInternal (voidpf file, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, int is64bitOpenFunction, unsigned flags); extern int ZEXPORT unzClose OF((unzFile file)); /* Close a ZipFile opened with unzipOpen. If there is files inside the .Zip opened with unzOpenCurrentFile (see later), these files MUST be closed with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, unz_global_info *pglobal_info)); extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, unz_global_info64 *pglobal_info)); /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *szComment, uLong uSizeBuf)); /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ /***************************************************************************/ /* Unzip package allow you browse the directory of the zipfile */ extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ extern int ZEXPORT unzGoToNextFile OF((unzFile file)); /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ extern int ZEXPORT unzLocateFile OF((unzFile file, const char *szFileName, int iCaseSensitivity)); /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzStringFileNameCompare return value : UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ /* ****************************************** */ /* Ryan supplied functions */ /* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_pos_s { uLong pos_in_zip_directory; /* offset in zip file directory */ uLong num_of_file; /* # of file */ } unz_file_pos; extern int ZEXPORT unzGetFilePos( unzFile file, unz_file_pos* file_pos); extern int ZEXPORT unzGoToFilePos( unzFile file, unz_file_pos* file_pos); typedef struct unz64_file_pos_s { ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ ZPOS64_T num_of_file; /* # of file */ } unz64_file_pos; extern int ZEXPORT unzGetFilePos64( unzFile file, unz64_file_pos* file_pos); extern int ZEXPORT unzGoToFilePos64( unzFile file, const unz64_file_pos* file_pos); /* ****************************************** */ extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); /* Get Info about the current file if pfile_info!=NULL, the *pfile_info structure will contain somes info about the current file if szFileName!=NULL, the filemane string will be copied in szFileName (fileNameBufferSize is the size of the buffer) if extraField!=NULL, the extra field information will be copied in extraField (extraFieldBufferSize is the size of the buffer). This is the Central-header version of the extra field if szComment!=NULL, the comment string of the file will be copied in szComment (commentBufferSize is the size of the buffer) */ /** Addition for GDAL : START */ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); /** Addition for GDAL : END */ /***************************************************************************/ /* for reading the content of the current zipfile, you can open it, read data from it, and close it (you can close it before reading all the file) */ extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); /* Open for reading data the current file in the zipfile. If there is no error, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, const char* password)); /* Open for reading data the current file in the zipfile. password is a crypting password If there is no error, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, int* method, int* level, int raw)); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of compression note : you can set level parameter as NULL (if you did not want known level, but you CANNOT set method parameter as NULL */ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, int* method, int* level, int raw, const char* password)); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of compression note : you can set level parameter as NULL (if you did not want known level, but you CANNOT set method parameter as NULL */ extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); /* Close the file in zip opened with unzOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ extern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len)); /* Read bytes from the current file (opened by unzOpenCurrentFile) buf contain buffer where data must be copied len the size of buf. return the number of byte copied if somes bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ extern z_off_t ZEXPORT unztell OF((unzFile file)); extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); /* Give the current position in uncompressed data */ extern int ZEXPORT unzeof OF((unzFile file)); /* return 1 if the end of file was reached, 0 elsewhere */ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, voidp buf, unsigned len)); /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) if buf==NULL, it return the size of the local extra field if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. the return value is the number of bytes copied in buf, or (if <0) the error code */ /***************************************************************************/ /* Get the current file offset */ extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); extern uLong ZEXPORT unzGetOffset (unzFile file); /* Set the current file offset */ extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); extern int ZEXPORT unzSetFlags(unzFile file, unsigned flags); extern int ZEXPORT unzClearFlags(unzFile file, unsigned flags); #ifdef __cplusplus } #endif #endif /* _unz64_H */ diff --git a/quazip/zip.c b/quazip/zip.c --- a/quazip/zip.c +++ b/quazip/zip.c @@ -1,2107 +1,1955 @@ /* zip.c -- IO on .zip files using zlib Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) For more info read MiniZip_info.txt Modifications for QIODevice support and other QuaZIP fixes Copyright (C) 2005-2014 Sergey A. Tachenov Fixing static code analysis issues Copyright (C) 2016 Intel Deutschland GmbH Changes Oct-2009 - Mathias Svensson - Remove old C style function prototypes Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data It is used when recreting zip archive with RAW when deleting items from a zip. ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer */ #include #include #include #include #include "zlib.h" #if (ZLIB_VERNUM < 0x1270) typedef uLongf z_crc_t; #endif #include "zip.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef VERSIONMADEBY # define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */ #endif #ifndef Z_BUFSIZE #define Z_BUFSIZE (64*1024) /* (16384) */ #endif #ifndef Z_MAXFILENAMEINZIP #define Z_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE # define TRYFREE(p) {if (p) free(p);} #endif /* #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) */ /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ /* NOT sure that this work on ALL platform */ #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) #ifndef SEEK_CUR #define SEEK_CUR 1 #endif #ifndef SEEK_END #define SEEK_END 2 #endif #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifndef DEF_MEM_LEVEL #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; #define SIZEDATA_INDATABLOCK (4096-(4*4)) #define LOCALHEADERMAGIC (0x04034b50) #define DESCRIPTORHEADERMAGIC (0x08074b50) #define CENTRALHEADERMAGIC (0x02014b50) #define ENDHEADERMAGIC (0x06054b50) #define ZIP64ENDHEADERMAGIC (0x6064b50) #define ZIP64ENDLOCHEADERMAGIC (0x7064b50) #define FLAG_LOCALHEADER_OFFSET (0x06) #define CRC_LOCALHEADER_OFFSET (0x0e) #define SIZECENTRALHEADER (0x2e) /* 46 */ typedef struct linkedlist_datablock_internal_s { struct linkedlist_datablock_internal_s* next_datablock; uLong avail_in_this_block; uLong filled_in_this_block; uLong unused; /* for future use and alignement */ unsigned char data[SIZEDATA_INDATABLOCK]; } linkedlist_datablock_internal; typedef struct linkedlist_data_s { linkedlist_datablock_internal* first_block; linkedlist_datablock_internal* last_block; } linkedlist_data; typedef struct { z_stream stream; /* zLib stream structure for inflate */ -#ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ -#endif int stream_initialised; /* 1 is stream is initialised */ uInt pos_in_buffered_data; /* last written byte in buffered_data */ ZPOS64_T pos_local_header; /* offset of the local header of the file currenty writing */ char* central_header; /* central header data for the current file */ uLong size_centralExtra; uLong size_centralheader; /* size of the central header for cur file */ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ uLong flag; /* flag of the file currently writing */ int method; /* compression method of file currenty wr.*/ int raw; /* 1 for directly writing raw data */ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; int encrypt; int zip64; /* Add ZIP64 extened information in the extra field */ ZPOS64_T pos_zip64extrainfo; ZPOS64_T totalCompressedData; ZPOS64_T totalUncompressedData; -#ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const z_crc_t FAR * pcrc_32_tab; - int crypt_header_size; -#endif } curfile64_info; typedef struct { zlib_filefunc64_32_def z_filefunc; voidpf filestream; /* io structore of the zipfile */ linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ curfile64_info ci; /* info on the file curretly writing */ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ ZPOS64_T add_position_when_writting_offset; ZPOS64_T number_entry; #ifndef NO_ADDFILEINEXISTINGZIP char *globalcomment; #endif unsigned flags; } zip64_internal; -#ifndef NOCRYPT -#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#include "minizip_crypt.h" -#endif - local linkedlist_datablock_internal* allocate_new_datablock() { linkedlist_datablock_internal* ldi; ldi = (linkedlist_datablock_internal*) ALLOC(sizeof(linkedlist_datablock_internal)); if (ldi!=NULL) { ldi->next_datablock = NULL ; ldi->filled_in_this_block = 0 ; ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; } return ldi; } local void free_datablock(linkedlist_datablock_internal* ldi) { while (ldi!=NULL) { linkedlist_datablock_internal* ldinext = ldi->next_datablock; TRYFREE(ldi); ldi = ldinext; } } local void init_linkedlist(linkedlist_data* ll) { ll->first_block = ll->last_block = NULL; } local void free_linkedlist(linkedlist_data* ll) { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { linkedlist_datablock_internal* ldi; const unsigned char* from_copy; if (ll==NULL) return ZIP_INTERNALERROR; if (ll->last_block == NULL) { ll->first_block = ll->last_block = allocate_new_datablock(); if (ll->first_block == NULL) return ZIP_INTERNALERROR; } ldi = ll->last_block; from_copy = (unsigned char*)buf; while (len>0) { uInt copy_this; uInt i; unsigned char* to_copy; if (ldi->avail_in_this_block==0) { ldi->next_datablock = allocate_new_datablock(); if (ldi->next_datablock == NULL) return ZIP_INTERNALERROR; ldi = ldi->next_datablock ; ll->last_block = ldi; } if (ldi->avail_in_this_block < len) copy_this = (uInt)ldi->avail_in_this_block; else copy_this = (uInt)len; to_copy = &(ldi->data[ldi->filled_in_this_block]); for (i=0;ifilled_in_this_block += copy_this; ldi->avail_in_this_block -= copy_this; from_copy += copy_this ; len -= copy_this; } return ZIP_OK; } /****************************************************************************/ #ifndef NO_ADDFILEINEXISTINGZIP /* =========================================================================== Inputs a long in LSB order to the given file nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */ local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { unsigned char buf[8]; int n; for (n = 0; n < nbByte; n++) { buf[n] = (unsigned char)(x & 0xff); x >>= 8; } if (x != 0) { /* data overflow - hack for ZIP64 (X Roche) */ for (n = 0; n < nbByte; n++) { buf[n] = 0xff; } } if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else return ZIP_OK; } local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { unsigned char* buf=(unsigned char*)dest; int n; for (n = 0; n < nbByte; n++) { buf[n] = (unsigned char)(x & 0xff); x >>= 8; } if (x != 0) { /* data overflow - hack for ZIP64 */ for (n = 0; n < nbByte; n++) { buf[n] = 0xff; } } } /****************************************************************************/ local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { uLong year = (uLong)ptm->tm_year; if (year>=1980) year-=1980; else if (year>=80) year-=80; return (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); } /****************************************************************************/ local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) { unsigned char c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); if (err==1) { *pi = (int)c; return ZIP_OK; } else { if (ZERROR64(*pzlib_filefunc_def,filestream)) return ZIP_ERRNO; else return ZIP_EOF; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==ZIP_OK) *pX = x; else *pX = 0; return err; } local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<16; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<24; if (err==ZIP_OK) *pX = x; else *pX = 0; return err; } local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { ZPOS64_T x; int i = 0; int err; err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x = (ZPOS64_T)i; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<8; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<16; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<24; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<32; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<40; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<48; if (err==ZIP_OK) err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((ZPOS64_T)i)<<56; if (err==ZIP_OK) *pX = x; else *pX = 0; return err; } #ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;){ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound; } /* Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before the global comment) */ local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; uLong uL; ZPOS64_T relativeOffset; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) { /* Signature "0x07064b50" Zip64 end of central directory locater */ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) { uPosFound = uReadPos+i; break; } } if (uPosFound!=0) break; } TRYFREE(buf); if (uPosFound == 0) return 0; /* Zip64 end of central directory locator */ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature, already checked */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; /* number of the disk with the start of the zip64 end of central directory */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 0) return 0; /* relative offset of the zip64 end of central directory record */ if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) return 0; /* total number of disks */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 1) return 0; /* Goto Zip64 end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */ return 0; return relativeOffset; } int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int err=ZIP_OK; ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ZPOS64_T size_central_dir; /* size of the central directory */ ZPOS64_T offset_central_dir; /* offset of start of central directory */ ZPOS64_T central_pos; uLong uL; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ uLong VersionMadeBy; uLong VersionNeeded; uLong size_comment; int hasZIP64Record = 0; /* check first if we find a ZIP64 record */ central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); if(central_pos > 0) { hasZIP64Record = 1; } else if(central_pos == 0) { central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); } /* disable to allow appending to empty ZIP archive if (central_pos==0) err=ZIP_ERRNO; */ if(hasZIP64Record) { ZPOS64_T sizeEndOfCentralDirectory; if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; /* the signature, already checked */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) err=ZIP_ERRNO; /* size of zip64 end of central directory record */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) err=ZIP_ERRNO; /* version made by */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) err=ZIP_ERRNO; /* version needed to extract */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) err=ZIP_ERRNO; /* number of this disk */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) err=ZIP_ERRNO; /* number of the disk with the start of the central directory */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) err=ZIP_ERRNO; /* total number of entries in the central directory on this disk */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) err=ZIP_ERRNO; /* total number of entries in the central directory */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) err=ZIP_ERRNO; if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=ZIP_BADZIPFILE; /* size of the central directory */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) err=ZIP_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) err=ZIP_ERRNO; /* TODO.. */ /* read the comment from the standard central header. */ size_comment = 0; } else { /* Read End of central Directory info */ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=ZIP_ERRNO; /* the signature, already checked */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) err=ZIP_ERRNO; /* number of this disk */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) err=ZIP_ERRNO; /* number of the disk with the start of the central directory */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) err=ZIP_ERRNO; /* total number of entries in the central dir on this disk */ number_entry = 0; if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) err=ZIP_ERRNO; else number_entry = uL; /* total number of entries in the central dir */ number_entry_CD = 0; if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) err=ZIP_ERRNO; else number_entry_CD = uL; if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=ZIP_BADZIPFILE; /* size of the central directory */ size_central_dir = 0; if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) err=ZIP_ERRNO; else size_central_dir = uL; /* offset of start of central directory with respect to the starting disk number */ offset_central_dir = 0; if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) err=ZIP_ERRNO; else offset_central_dir = uL; /* zipfile global comment length */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) err=ZIP_ERRNO; } if ((central_posflags & ZIP_AUTO_CLOSE) != 0) { ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); } else { ZFAKECLOSE64(pziinit->z_filefunc, pziinit->filestream); } return ZIP_ERRNO; } if (size_comment>0) { pziinit->globalcomment = (char*)ALLOC(size_comment+1); if (pziinit->globalcomment) { size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); pziinit->globalcomment[size_comment]=0; } } byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); pziinit->add_position_when_writting_offset = byte_before_the_zipfile; { ZPOS64_T size_central_dir_to_read = size_central_dir; size_t buf_size = SIZEDATA_INDATABLOCK; void* buf_read = (void*)ALLOC(buf_size); if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; while ((size_central_dir_to_read>0) && (err==ZIP_OK)) { ZPOS64_T read_this = SIZEDATA_INDATABLOCK; if (read_this > size_central_dir_to_read) read_this = size_central_dir_to_read; if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) err=ZIP_ERRNO; if (err==ZIP_OK) err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); size_central_dir_to_read-=read_this; } TRYFREE(buf_read); } pziinit->begin_pos = byte_before_the_zipfile; pziinit->number_entry = number_entry_CD; if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; return err; } #endif /* !NO_ADDFILEINEXISTINGZIP*/ /************************************************************/ extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, unsigned flags) { zip64_internal ziinit; zip64_internal* zi; int err=ZIP_OK; ziinit.flags = flags; ziinit.z_filefunc.zseek32_file = NULL; ziinit.z_filefunc.ztell32_file = NULL; if (pzlib_filefunc64_32_def==NULL) fill_qiodevice64_filefunc(&ziinit.z_filefunc.zfile_func64); else ziinit.z_filefunc = *pzlib_filefunc64_32_def; ziinit.filestream = ZOPEN64(ziinit.z_filefunc, file, (append == APPEND_STATUS_CREATE) ? (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); if (ziinit.filestream == NULL) return NULL; if (append == APPEND_STATUS_CREATEAFTER) ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; ziinit.number_entry = 0; ziinit.add_position_when_writting_offset = 0; init_linkedlist(&(ziinit.central_dir)); zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); if (zi==NULL) { if ((ziinit.flags & ZIP_AUTO_CLOSE) != 0) { ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); } else { ZFAKECLOSE64(ziinit.z_filefunc,ziinit.filestream); } return NULL; } /* now we add file in a zipfile */ # ifndef NO_ADDFILEINEXISTINGZIP ziinit.globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP) { /* Read and Cache Central Directory Records */ err = LoadCentralDirectoryRecord(&ziinit); } if (globalcomment) { *globalcomment = ziinit.globalcomment; } # endif /* !NO_ADDFILEINEXISTINGZIP*/ if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(ziinit.globalcomment); # endif /* !NO_ADDFILEINEXISTINGZIP*/ TRYFREE(zi); return NULL; } else { *zi = ziinit; return (zipFile)zi; } } extern zipFile ZEXPORT zipOpen2 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) { if (pzlib_filefunc32_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS); } else return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS); } extern zipFile ZEXPORT zipOpen2_64 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) { if (pzlib_filefunc_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; zlib_filefunc64_32_def_fill.ztell32_file = NULL; zlib_filefunc64_32_def_fill.zseek32_file = NULL; return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS); } else return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS); } extern zipFile ZEXPORT zipOpen (voidpf file, int append) { return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS); } extern zipFile ZEXPORT zipOpen64 (voidpf file, int append) { return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS); } int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local, uLong version_to_extract) { /* write the local header */ int err; uInt size_filename = (uInt)strlen(filename); uInt size_extrafield = size_extrafield_local; err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); if (err==ZIP_OK) { if(zi->ci.zip64) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2); } if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */ if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ if (err==ZIP_OK) { if(zi->ci.zip64) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ } if (err==ZIP_OK) { if(zi->ci.zip64) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ } if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); if(zi->ci.zip64) { size_extrafield += 20; } if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); if ((err==ZIP_OK) && (size_filename > 0)) { if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) err = ZIP_ERRNO; } if ((err==ZIP_OK) && (size_extrafield_local > 0)) { if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) err = ZIP_ERRNO; } if ((err==ZIP_OK) && (zi->ci.zip64)) { /* write the Zip64 extended info */ short HeaderID = 1; short DataSize = 16; ZPOS64_T CompressedSize = 0; ZPOS64_T UncompressedSize = 0; /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */ zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); } return err; } /* NOTE. When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped before calling this function it can be done with zipRemoveExtraInfoBlock It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize unnecessary allocations. */ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64) { + crcForCrypting = crcForCrypting; zip64_internal* zi; uInt size_filename; uInt size_comment; uInt i; int err = ZIP_OK; uLong version_to_extract; -# ifdef NOCRYPT if (password != NULL) return ZIP_PARAMERROR; -# endif if (file == NULL) return ZIP_PARAMERROR; -#ifdef HAVE_BZIP2 - if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) - return ZIP_PARAMERROR; -#else if ((method!=0) && (method!=Z_DEFLATED)) return ZIP_PARAMERROR; -#endif zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) { err = zipCloseFileInZip (file); if (err != ZIP_OK) return err; } if (method == 0 && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) && (zi->flags & ZIP_SEQUENTIAL) == 0) { version_to_extract = 10; } else { version_to_extract = 20; } if (filename==NULL) filename="-"; if (comment==NULL) size_comment = 0; else size_comment = (uInt)strlen(comment); size_filename = (uInt)strlen(filename); if (zipfi == NULL) zi->ci.dosDate = 0; else { if (zipfi->dosDate != 0) zi->ci.dosDate = zipfi->dosDate; else zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); } zi->ci.flag = flagBase; if ((level==8) || (level==9)) zi->ci.flag |= 2; if (level==2) zi->ci.flag |= 4; if (level==1) zi->ci.flag |= 6; if (password != NULL) zi->ci.flag |= 1; if (version_to_extract >= 20 && ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0 || (zi->flags & ZIP_SEQUENTIAL) != 0)) zi->ci.flag |= 8; zi->ci.crc32 = 0; zi->ci.method = method; zi->ci.encrypt = 0; zi->ci.stream_initialised = 0; zi->ci.pos_in_buffered_data = 0; zi->ci.raw = raw; zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); if(!zi->ci.central_header) { return (Z_MEM_ERROR); } zi->ci.size_centralExtra = size_extrafield_global; zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); /* version info */ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2); zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ if (zipfi==NULL) zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); else zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); if (zipfi==NULL) zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); else zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); if(zi->ci.pos_local_header >= 0xffffffff) zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); else zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = *(((const char*)extrafield_global)+i); for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ size_extrafield_global+i) = *(comment+i); if (zi->ci.central_header == NULL) return ZIP_INTERNALERROR; zi->ci.zip64 = zip64; zi->ci.totalCompressedData = 0; zi->ci.totalUncompressedData = 0; zi->ci.pos_zip64extrainfo = 0; err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local, version_to_extract); -#ifdef HAVE_BZIP2 - zi->ci.bstream.avail_in = (uInt)0; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - zi->ci.bstream.total_in_hi32 = 0; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_out_hi32 = 0; - zi->ci.bstream.total_out_lo32 = 0; -#endif - zi->ci.stream.avail_in = (uInt)0; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; zi->ci.stream.total_in = 0; zi->ci.stream.total_out = 0; zi->ci.stream.data_type = Z_BINARY; -#ifdef HAVE_BZIP2 - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) -#else if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) -#endif { if(zi->ci.method == Z_DEFLATED) { zi->ci.stream.zalloc = (alloc_func)0; zi->ci.stream.zfree = (free_func)0; zi->ci.stream.opaque = (voidpf)0; if (windowBits>0) windowBits = -windowBits; err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); if (err==Z_OK) zi->ci.stream_initialised = Z_DEFLATED; } - else if(zi->ci.method == Z_BZIP2ED) - { -#ifdef HAVE_BZIP2 - /* Init BZip stuff here */ - zi->ci.bstream.bzalloc = 0; - zi->ci.bstream.bzfree = 0; - zi->ci.bstream.opaque = (voidpf)0; - - err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); - if(err == BZ_OK) - zi->ci.stream_initialised = Z_BZIP2ED; -#endif - } } -# ifndef NOCRYPT - zi->ci.crypt_header_size = 0; - if ((err==Z_OK) && (password != NULL)) - { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; - zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = get_crc_table(); - /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ - if (crcForCrypting == 0) { - crcForCrypting = (uLong)zi->ci.dosDate << 16; /* ATTANTION! Without this row, you don't unpack your password protected archive in other app. */ - } - sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); - zi->ci.crypt_header_size = sizeHead; - - if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) - err = ZIP_ERRNO; - } -# endif - if (err==Z_OK) zi->in_opened_file_inzip = 1; return err; } extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy, password, crcForCrypting, versionMadeBy, flagBase, 0); } extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, const char* password, uLong crcForCrypting) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy, password, crcForCrypting, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, const char* password, uLong crcForCrypting, int zip64) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy, password, crcForCrypting, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int zip64) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void*extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int zip64) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void*extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level) { return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0); } local int zip64FlushWriteBuffer(zip64_internal* zi) { int err=ZIP_OK; if (zi->ci.encrypt != 0) { -#ifndef NOCRYPT - uInt i; - int t; - for (i=0;ici.pos_in_buffered_data;i++) - zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); -#endif } if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) err = ZIP_ERRNO; zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; - -#ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED) - { - zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_in_hi32 = 0; - } - else -#endif - { - zi->ci.totalUncompressedData += zi->ci.stream.total_in; - zi->ci.stream.total_in = 0; - } + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; zi->ci.pos_in_buffered_data = 0; return err; } extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) { zip64_internal* zi; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); -#ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) - { - zi->ci.bstream.next_in = (void*)buf; - zi->ci.bstream.avail_in = len; - err = BZ_RUN_OK; + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; - while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) - { - if (zi->ci.bstream.avail_out == 0) + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; } - if(err != BZ_RUN_OK) - break; - - if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; -/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */ - err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; - } - } - - if(err == BZ_RUN_OK) - err = ZIP_OK; - } - else -#endif - { - zi->ci.stream.next_in = (Bytef*)buf; - zi->ci.stream.avail_in = len; - - while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) - { - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - + if(err != ZIP_OK) + break; - if(err != ZIP_OK) - break; + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uInt uAvailOutBefore = zi->ci.stream.avail_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - uInt uAvailOutBefore = zi->ci.stream.avail_out; - err=deflate(&zi->ci.stream, Z_NO_FLUSH); - zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; - } - else - { - uInt copy_this,i; - if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) - copy_this = zi->ci.stream.avail_in; - else - copy_this = zi->ci.stream.avail_out; - - for (i = 0; i < copy_this; i++) - *(((char*)zi->ci.stream.next_out)+i) = - *(((const char*)zi->ci.stream.next_in)+i); - { - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out-= copy_this; - zi->ci.stream.next_in+= copy_this; - zi->ci.stream.next_out+= copy_this; - zi->ci.stream.total_in+= copy_this; - zi->ci.stream.total_out+= copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - }/* while(...) */ - } + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }/* while(...) */ return err; } extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) { return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); } extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { zip64_internal* zi; ZPOS64_T compressed_size; uLong invalidValue = 0xffffffff; short datasize = 0; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.stream.avail_in = 0; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { while (err==ZIP_OK) { uLong uAvailOutBefore; if (zi->ci.stream.avail_out == 0) { if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } uAvailOutBefore = zi->ci.stream.avail_out; err=deflate(&zi->ci.stream, Z_FINISH); zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; } } - else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { -#ifdef HAVE_BZIP2 - err = BZ_FINISH_OK; - while (err==BZ_FINISH_OK) - { - uLong uTotalOutBefore; - if (zi->ci.bstream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.bstream.total_out_lo32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); - if(err == BZ_STREAM_END) - err = Z_STREAM_END; - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); - } - - if(err == BZ_FINISH_OK) - err = ZIP_OK; -#endif - } if (err==Z_STREAM_END) err=ZIP_OK; /* this is normal */ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) { if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) err = ZIP_ERRNO; } if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { int tmp_err = deflateEnd(&zi->ci.stream); if (err == ZIP_OK) err = tmp_err; zi->ci.stream_initialised = 0; } #ifdef HAVE_BZIP2 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) { int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); if (err==ZIP_OK) err = tmperr; zi->ci.stream_initialised = 0; } #endif if (!zi->ci.raw) { crc32 = (uLong)zi->ci.crc32; uncompressed_size = zi->ci.totalUncompressedData; } compressed_size = zi->ci.totalCompressedData; -# ifndef NOCRYPT - compressed_size += zi->ci.crypt_header_size; -# endif - /* update Current Item crc and sizes, */ if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) { /*version Made by*/ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); /*version needed*/ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); } zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ if(compressed_size >= 0xffffffff) zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ else zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ /* set internal file attributes field */ if (zi->ci.stream.data_type == Z_ASCII) zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); if(uncompressed_size >= 0xffffffff) zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ else zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ /* Add ZIP64 extra info field for uncompressed size */ if(uncompressed_size >= 0xffffffff) datasize += 8; /* Add ZIP64 extra info field for compressed size */ if(compressed_size >= 0xffffffff) datasize += 8; /* Add ZIP64 extra info field for relative offset to local file header of current file */ if(zi->ci.pos_local_header >= 0xffffffff) datasize += 8; if(datasize > 0) { char* p = NULL; if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) { /* we can not write more data to the buffer that we have room for. */ return ZIP_BADZIPFILE; } p = zi->ci.central_header + zi->ci.size_centralheader; /* Add Extra Information Header for 'ZIP64 information' */ zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */ p += 2; zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */ p += 2; if(uncompressed_size >= 0xffffffff) { zip64local_putValue_inmemory(p, uncompressed_size, 8); p += 8; } if(compressed_size >= 0xffffffff) { zip64local_putValue_inmemory(p, compressed_size, 8); p += 8; } if(zi->ci.pos_local_header >= 0xffffffff) { zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); p += 8; } /* Update how much extra free space we got in the memory buffer */ /* and increase the centralheader size so the new ZIP64 fields are included */ /* ( 4 below is the size of HeaderID and DataSize field ) */ zi->ci.size_centralExtraFree -= datasize + 4; zi->ci.size_centralheader += datasize + 4; /* Update the extra info size field */ zi->ci.size_centralExtra += datasize + 4; zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); } if (err==ZIP_OK) err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); free(zi->ci.central_header); if (err==ZIP_OK) { if ((zi->flags & ZIP_SEQUENTIAL) == 0) { /* Update the LocalFileHeader with the new values. */ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) { if(zi->ci.pos_zip64extrainfo > 0) { /* Update the size in the ZIP64 extended field. */ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; if (err==ZIP_OK) /* compressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); if (err==ZIP_OK) /* uncompressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); } } else { if (err==ZIP_OK) /* compressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); } if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; } if ((zi->ci.flag & 8) != 0) { /* Write local Descriptor after file data */ if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4); if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if (zi->ci.zip64) { if (err==ZIP_OK) /* compressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,8); if (err==ZIP_OK) /* uncompressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,8); } else { if (err==ZIP_OK) /* compressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); } } } zi->number_entry ++; zi->in_opened_file_inzip = 0; return err; } extern int ZEXPORT zipCloseFileInZip (zipFile file) { return zipCloseFileInZipRaw (file,0,0); } int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { int err = ZIP_OK; ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); /*num disks*/ if (err==ZIP_OK) /* number of the disk with the start of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /*relative offset*/ if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ if (err==ZIP_OK) /* number of the disk with the start of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); return err; } int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; uLong Zip64DataSize = 44; err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */ if (err==ZIP_OK) /* version made by */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); if (err==ZIP_OK) /* version needed */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); if (err==ZIP_OK) /* number of this disk */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); if (err==ZIP_OK) /* number of the disk with the start of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); if (err==ZIP_OK) /* total number of entries in the central dir */ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); if (err==ZIP_OK) /* size of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ { ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); } return err; } int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; /*signature*/ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); if (err==ZIP_OK) /* number of this disk */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* number of the disk with the start of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ { { if(zi->number_entry >= 0xFFFF) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); } } if (err==ZIP_OK) /* total number of entries in the central dir */ { if(zi->number_entry >= 0xFFFF) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); } if (err==ZIP_OK) /* size of the central directory */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ { ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; if(pos >= 0xffffffff) { err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); } else err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); } return err; } int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { int err = ZIP_OK; uInt size_global_comment = 0; if(global_comment != NULL) size_global_comment = (uInt)strlen(global_comment); err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); if (err == ZIP_OK && size_global_comment > 0) { if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) err = ZIP_ERRNO; } return err; } extern int ZEXPORT zipClose (zipFile file, const char* global_comment) { zip64_internal* zi; int err = 0; uLong size_centraldir = 0; ZPOS64_T centraldir_pos_inzip; ZPOS64_T pos; if (file == NULL) return ZIP_PARAMERROR; zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) { err = zipCloseFileInZip (file); } #ifndef NO_ADDFILEINEXISTINGZIP if (global_comment==NULL) global_comment = zi->globalcomment; #endif centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); if (err==ZIP_OK) { linkedlist_datablock_internal* ldi = zi->central_dir.first_block; while (ldi!=NULL) { if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) { if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) err = ZIP_ERRNO; } size_centraldir += ldi->filled_in_this_block; ldi = ldi->next_datablock; } } free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); } if (err==ZIP_OK) err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); if(err == ZIP_OK) err = Write_GlobalComment(zi, global_comment); if ((zi->flags & ZIP_AUTO_CLOSE) != 0) { if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) { if (err == ZIP_OK) err = ZIP_ERRNO; } } else { if (ZFAKECLOSE64(zi->z_filefunc,zi->filestream) != 0) { if (err == ZIP_OK) err = ZIP_ERRNO; } } #ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(zi->globalcomment); #endif TRYFREE(zi); return err; } extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) { char* p = pData; int size = 0; char* pNewHeader; char* pTmp; short header; short dataSize; int retVal = ZIP_OK; if(pData == NULL || *dataLen < 4) return ZIP_PARAMERROR; pNewHeader = (char*)ALLOC(*dataLen); if(!pNewHeader) { return Z_MEM_ERROR; } pTmp = pNewHeader; while(p < (pData + *dataLen)) { header = *(short*)p; dataSize = *(((short*)p)+1); if( header == sHeader ) /* Header found. */ { p += dataSize + 4; /* skip it. do not copy to temp buffer */ } else { /* Extra Info block should not be removed, So copy it to the temp buffer. */ memcpy(pTmp, p, dataSize + 4); p += dataSize + 4; size += dataSize + 4; } } if(size < *dataLen) { /* clean old extra info block. */ memset(pData,0, *dataLen); /* copy the new extra info block over the old */ if(size > 0) memcpy(pData, pNewHeader, size); /* set the new extra info size */ *dataLen = size; retVal = ZIP_OK; } else retVal = ZIP_ERRNO; TRYFREE(pNewHeader); return retVal; } int ZEXPORT zipSetFlags(zipFile file, unsigned flags) { zip64_internal* zi; if (file == NULL) return ZIP_PARAMERROR; zi = (zip64_internal*)file; zi->flags |= flags; // If the output is non-seekable, the data descriptor is needed. if ((zi->flags & ZIP_SEQUENTIAL) != 0) { zi->flags |= ZIP_WRITE_DATA_DESCRIPTOR; } return ZIP_OK; } int ZEXPORT zipClearFlags(zipFile file, unsigned flags) { zip64_internal* zi; if (file == NULL) return ZIP_PARAMERROR; zi = (zip64_internal*)file; zi->flags &= ~flags; // If the data descriptor is not written, we can't use a non-seekable output. if ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) { zi->flags &= ~ZIP_SEQUENTIAL; } return ZIP_OK; } diff --git a/quazip/zip.h b/quazip/zip.h --- a/quazip/zip.h +++ b/quazip/zip.h @@ -1,390 +1,382 @@ /* zip.h -- IO on .zip files using zlib Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) For more info read MiniZip_info.txt --------------------------------------------------------------------------- Condition of use and distribution are the same than zlib : This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------------------------- Changes See header of zip.h --------------------------------------------------------------------------- As per the requirement above, this file is plainly marked as modified by Sergey A. Tachenov. Most modifications include the I/O API redesign to support QIODevice interface. Some improvements and small fixes were also made. */ #ifndef _zip12_H #define _zip12_H #ifdef __cplusplus extern "C" { #endif -//#define HAVE_BZIP2 - #ifndef _ZLIB_H #include "zlib.h" #endif #ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif -#ifdef HAVE_BZIP2 -#include "bzlib.h" -#endif - -#define Z_BZIP2ED 12 - #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ typedef struct TagzipFile__ { int unused; } zipFile__; typedef zipFile__ *zipFile; #else typedef voidp zipFile; #endif #define ZIP_OK (0) #define ZIP_EOF (0) #define ZIP_ERRNO (Z_ERRNO) #define ZIP_PARAMERROR (-102) #define ZIP_BADZIPFILE (-103) #define ZIP_INTERNALERROR (-104) #define ZIP_WRITE_DATA_DESCRIPTOR 0x8u #define ZIP_AUTO_CLOSE 0x1u #define ZIP_SEQUENTIAL 0x2u #define ZIP_DEFAULT_FLAGS (ZIP_AUTO_CLOSE | ZIP_WRITE_DATA_DESCRIPTOR) #ifndef DEF_MEM_LEVEL # if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 # else # define DEF_MEM_LEVEL MAX_MEM_LEVEL # endif #endif /* default memLevel */ /* tm_zip contain date/time info */ typedef struct tm_zip_s { uInt tm_sec; /* seconds after the minute - [0,59] */ uInt tm_min; /* minutes after the hour - [0,59] */ uInt tm_hour; /* hours since midnight - [0,23] */ uInt tm_mday; /* day of the month - [1,31] */ uInt tm_mon; /* months since January - [0,11] */ uInt tm_year; /* years - [1980..2044] */ } tm_zip; typedef struct { tm_zip tmz_date; /* date in understandable format */ uLong dosDate; /* if dos_date == 0, tmu_date is used */ /* uLong flag; */ /* general purpose bit flag 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ } zip_fileinfo; typedef const char* zipcharpc; #define APPEND_STATUS_CREATE (0) #define APPEND_STATUS_CREATEAFTER (1) #define APPEND_STATUS_ADDINZIP (2) extern zipFile ZEXPORT zipOpen OF((voidpf file, int append)); extern zipFile ZEXPORT zipOpen64 OF((voidpf file, int append)); /* Create a zipfile. the file argument depends on the API used, for QuaZIP it's a QIODevice pointer. if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip will be created at the end of the file. (useful if the file contain a self extractor code) if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will add files in existing zip (be sure you don't add file that doesn't exist) If the zipfile cannot be opened, the return value is NULL. Else, the return value is a zipFile Handle, usable with other function of this zip package. */ /* Note : there is no delete function into a zipfile. If you want delete file into a zipfile, you must open a zipfile, and create another Of couse, you can use RAW reading and writing to copy the file you did not want delte */ extern zipFile ZEXPORT zipOpen2 OF((voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc_def)); extern zipFile ZEXPORT zipOpen2_64 OF((voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)); /* * Exported by Sergey A. Tachenov to suit the needs of QuaZIP. * Note that this function MAY change signature in order to * provide new QuaZIP features. You have been warned! * */ extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, unsigned flags); extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level)); extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int zip64)); /* Open a file in the ZIP for writing. filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local contains the extrafield data the the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global contains the extrafield data the the local header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) zip64 is set to 1 if a zip64 extended information block should be added to the local file header. this MUST be '1' if the uncompressed size is >= 0xffffffff. */ extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw)); extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int zip64)); /* Same than zipOpenNewFileInZip, except if raw=1, we write raw file */ extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, uLong crcForCrypting)); extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, uLong crcForCrypting, int zip64 )); /* Same than zipOpenNewFileInZip2, except windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 password : crypting password (NULL for no crypting) crcForCrypting : crc of file to compress (needed for crypting) */ extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase )); extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64 )); /* Same than zipOpenNewFileInZip4, except versionMadeBy : value for Version made by field flag : value for flag field (compression level info will be added) */ extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void* buf, unsigned len)); /* Write data in the zipfile */ extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); /* Close the current file in the zipfile */ extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, ZPOS64_T uncompressed_size, uLong crc32)); /* Close the current file in the zipfile, for file opened with parameter raw=1 in zipOpenNewFileInZip2 uncompressed_size and crc32 are value for the uncompressed size */ extern int ZEXPORT zipClose OF((zipFile file, const char* global_comment)); /* Close the zipfile */ extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); /* zipRemoveExtraInfoBlock - Added by Mathias Svensson Remove extra information block from a extra information data for the local file header or central directory header It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. 0x0001 is the signature header for the ZIP64 extra information blocks usage. Remove ZIP64 Extra information from a central director extra field data zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); Remove ZIP64 Extra information from a Local File Header extra field data zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); */ /* Added by Sergey A. Tachenov to tweak zipping behaviour. */ extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags); extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags); #ifdef __cplusplus } #endif #endif /* _zip64_H */ diff --git a/quazip/JlCompress.cpp b/qztest/JlCompress.cpp rename from quazip/JlCompress.cpp rename to qztest/JlCompress.cpp diff --git a/quazip/JlCompress.h b/qztest/JlCompress.h rename from quazip/JlCompress.h rename to qztest/JlCompress.h --- a/quazip/JlCompress.h +++ b/qztest/JlCompress.h @@ -1,197 +1,197 @@ #ifndef JLCOMPRESSFOLDER_H_ #define JLCOMPRESSFOLDER_H_ /* Copyright (C) 2010 Roberto Pompermaier Copyright (C) 2005-2016 Sergey A. Tachenov This file is part of QuaZIP. QuaZIP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. QuaZIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with QuaZIP. If not, see . See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant and contributors, see quazip/(un)zip.h files for details. Basically it's the zlib license. */ -#include "quazip.h" -#include "quazipfile.h" -#include "quazipfileinfo.h" +#include "quazip/quazip.h" +#include "quazip/quazipfile.h" +#include "quazip/quazipfileinfo.h" #include #include #include #include /// Utility class for typical operations. /** This class contains a number of useful static functions to perform simple operations, such as mass ZIP packing or extraction. */ class QUAZIP_EXPORT JlCompress { private: static QStringList extractDir(QuaZip &zip, const QString &dir); static QStringList getFileList(QuaZip *zip); static QString extractFile(QuaZip &zip, QString fileName, QString fileDest); static QStringList extractFiles(QuaZip &zip, const QStringList &files, const QString &dir); /// Compress a single file. /** \param zip Opened zip to compress the file to. \param fileName The full path to the source file. \param fileDest The full name of the file inside the archive. \return true if success, false otherwise. */ static bool compressFile(QuaZip* zip, QString fileName, QString fileDest); /// Compress a subdirectory. /** \param parentZip Opened zip containing the parent directory. \param dir The full path to the directory to pack. \param parentDir The full path to the directory corresponding to the root of the ZIP. \param recursive Whether to pack sub-directories as well or only files. \return true if success, false otherwise. */ static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive, QDir::Filters filters); /// Extract a single file. /** \param zip The opened zip archive to extract from. \param fileName The full name of the file to extract. \param fileDest The full path to the destination file. \return true if success, false otherwise. */ static bool extractFile(QuaZip* zip, QString fileName, QString fileDest); /// Remove some files. /** \param listFile The list of files to remove. \return true if success, false otherwise. */ static bool removeFile(QStringList listFile); public: /// Compress a single file. /** \param fileCompressed The name of the archive. \param file The file to compress. \return true if success, false otherwise. */ static bool compressFile(QString fileCompressed, QString file); /// Compress a list of files. /** \param fileCompressed The name of the archive. \param files The file list to compress. \return true if success, false otherwise. */ static bool compressFiles(QString fileCompressed, QStringList files); /// Compress a whole directory. /** Does not compress hidden files. See compressDir(QString, QString, bool, QDir::Filters). \param fileCompressed The name of the archive. \param dir The directory to compress. \param recursive Whether to pack the subdirectories as well, or just regular files. \return true if success, false otherwise. */ static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true); /** * @brief Compress a whole directory. * * Unless filters are specified explicitly, packs * only regular non-hidden files (and subdirs, if @c recursive is true). * If filters are specified, they are OR-combined with * %QDir::AllDirs|%QDir::NoDotAndDotDot when searching for dirs * and with QDir::Files when searching for files. * * @param fileCompressed path to the resulting archive * @param dir path to the directory being compressed * @param recursive if true, then the subdirectories are packed as well * @param filters what to pack, filters are applied both when searching * for subdirs (if packing recursively) and when looking for files to pack * @return true on success, false otherwise */ static bool compressDir(QString fileCompressed, QString dir, bool recursive, QDir::Filters filters); public: /// Extract a single file. /** \param fileCompressed The name of the archive. \param fileName The file to extract. \param fileDest The destination file, assumed to be identical to \a file if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString()); /// Extract a list of files. /** \param fileCompressed The name of the archive. \param files The file list to extract. \param dir The directory to put the files to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString()); /// Extract a whole archive. /** \param fileCompressed The name of the archive. \param dir The directory to extract to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractDir(QString fileCompressed, QString dir = QString()); /// Get the file list. /** \return The list of the files in the archive, or, more precisely, the list of the entries, including both files and directories if they are present separately. */ static QStringList getFileList(QString fileCompressed); /// Extract a single file. /** \param ioDevice pointer to device with compressed data. \param fileName The file to extract. \param fileDest The destination file, assumed to be identical to \a file if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QString extractFile(QIODevice *ioDevice, QString fileName, QString fileDest = QString()); /// Extract a list of files. /** \param ioDevice pointer to device with compressed data. \param files The file list to extract. \param dir The directory to put the files to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractFiles(QIODevice *ioDevice, QStringList files, QString dir = QString()); /// Extract a whole archive. /** \param ioDevice pointer to device with compressed data. \param dir The directory to extract to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractDir(QIODevice *ioDevice, QString dir = QString()); /// Get the file list. /** \return The list of the files in the archive, or, more precisely, the list of the entries, including both files and directories if they are present separately. */ static QStringList getFileList(QIODevice *ioDevice); }; #endif /* JLCOMPRESSFOLDER_H_ */ diff --git a/qztest/qztest.cpp b/qztest/qztest.cpp --- a/qztest/qztest.cpp +++ b/qztest/qztest.cpp @@ -1,237 +1,217 @@ /* Copyright (C) 2005-2014 Sergey A. Tachenov This file is part of QuaZIP test suite. QuaZIP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. QuaZIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with QuaZIP. If not, see . See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant and contributors, see quazip/(un)zip.h files for details. Basically it's the zlib license. */ #include "qztest.h" #include "testquazip.h" #include "testquazipfile.h" -#include "testquachecksum32.h" -#include "testjlcompress.h" -#include "testquazipdir.h" -#include "testquagzipfile.h" #include "testquaziodevice.h" #include "testquazipnewinfo.h" #include "testquazipfileinfo.h" #include #include #include #include #include #include #include bool createTestFiles(const QStringList &fileNames, int size, const QString &dir) { QDir curDir; foreach (QString fileName, fileNames) { QString filePath = QDir(dir).filePath(fileName); QDir testDir = QFileInfo(filePath).dir(); if (!testDir.exists()) { if (!curDir.mkpath(testDir.path())) { qWarning("Couldn't mkpath %s", testDir.path().toUtf8().constData()); return false; } } if (fileName.endsWith('/')) { if (!curDir.mkpath(filePath)) { qWarning("Couldn't mkpath %s", fileName.toUtf8().constData()); return false; } } else { QFile testFile(filePath); if (!testFile.open(QIODevice::WriteOnly | QIODevice::Text)) { qWarning("Couldn't create %s", fileName.toUtf8().constData()); return false; } if (size == -1) { QTextStream testStream(&testFile); testStream << "This is a test file named " << fileName << endl; } else { for (int i = 0; i < size; ++i) { testFile.putChar(static_cast('0' + i % 10)); } } } } return true; } bool createTestArchive(QuaZip &zip, const QString &zipName, const QStringList &fileNames, QTextCodec *codec, const QString &dir) { if (codec != NULL) { zip.setFileNameCodec(codec); } if (!zip.open(QuaZip::mdCreate)) { qWarning("Couldn't open %s", zipName.toUtf8().constData()); return false; } int i = 0; QDateTime dt1; foreach (QString fileName, fileNames) { QuaZipFile zipFile(&zip); QString filePath = QDir(dir).filePath(fileName); QFileInfo fileInfo(filePath); QuaZipNewInfo newInfo(fileName, filePath); if (i == 0) // to test code that needs different timestamps newInfo.dateTime = newInfo.dateTime.addSecs(-60); else if (i == 1) // will use for the next file too dt1 = newInfo.dateTime; else if (i == 2) // to test identical timestamps newInfo.dateTime = dt1; if (!zipFile.open(QIODevice::WriteOnly, newInfo, NULL, 0, fileInfo.isDir() ? 0 : 8)) { qWarning("Couldn't open %s in %s", fileName.toUtf8() .constData(), zipName.toUtf8().constData()); return false; } if (!fileInfo.isDir()) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { qWarning("Couldn't open %s", filePath.toUtf8() .constData()); return false; } while (!file.atEnd()) { char buf[4096]; qint64 l = file.read(buf, 4096); if (l <= 0) { qWarning("Couldn't read %s", filePath.toUtf8() .constData()); return false; } if (zipFile.write(buf, l) != l) { qWarning("Couldn't write to %s in %s", filePath.toUtf8().constData(), zipName.toUtf8().constData()); return false; } } file.close(); } zipFile.close(); ++i; } zip.setComment(QString("This is the test archive")); zip.close(); if (zipName.startsWith("<")) { // something like "" return true; } else { return QFileInfo(zipName).exists(); } } bool createTestArchive(const QString &zipName, const QStringList &fileNames, const QString &dir) { return createTestArchive(zipName, fileNames, NULL, dir); } bool createTestArchive(QIODevice *ioDevice, const QStringList &fileNames, QTextCodec *codec, const QString &dir) { QuaZip zip(ioDevice); return createTestArchive(zip, "", fileNames, codec, dir); } bool createTestArchive(const QString &zipName, const QStringList &fileNames, QTextCodec *codec, const QString &dir) { QuaZip zip(zipName); return createTestArchive(zip, zipName, fileNames, codec, dir); } void removeTestFiles(const QStringList &fileNames, const QString &dir) { QDir curDir; foreach (QString fileName, fileNames) { curDir.remove(QDir(dir).filePath(fileName)); } foreach (QString fileName, fileNames) { QDir fileDir = QFileInfo(QDir(dir).filePath(fileName)).dir(); if (fileDir.exists()) { // Non-empty dirs won't get removed, and that's good. curDir.rmpath(fileDir.path()); } } } int main(int argc, char **argv) { QCoreApplication app(argc, argv); int err = 0; { TestQuaZip testQuaZip; err = qMax(err, QTest::qExec(&testQuaZip, app.arguments())); } { TestQuaZipFile testQuaZipFile; err = qMax(err, QTest::qExec(&testQuaZipFile, app.arguments())); } { - TestQuaChecksum32 testQuaChecksum32; - err = qMax(err, QTest::qExec(&testQuaChecksum32, app.arguments())); - } - { - TestJlCompress testJlCompress; - err = qMax(err, QTest::qExec(&testJlCompress, app.arguments())); - } - { - TestQuaZipDir testQuaZipDir; - err = qMax(err, QTest::qExec(&testQuaZipDir, app.arguments())); - } - { TestQuaZIODevice testQuaZIODevice; err = qMax(err, QTest::qExec(&testQuaZIODevice, app.arguments())); } { - TestQuaGzipFile testQuaGzipFile; - err = qMax(err, QTest::qExec(&testQuaGzipFile, app.arguments())); - } - { TestQuaZipNewInfo testQuaZipNewInfo; err = qMax(err, QTest::qExec(&testQuaZipNewInfo, app.arguments())); } { TestQuaZipFileInfo testQuaZipFileInfo; err = qMax(err, QTest::qExec(&testQuaZipFileInfo, app.arguments())); } if (err == 0) { qDebug("All tests executed successfully"); } else { qWarning("There were errors in some of the tests above."); } return err; } diff --git a/qztest/qztest.pro b/qztest/qztest.pro --- a/qztest/qztest.pro +++ b/qztest/qztest.pro @@ -1,49 +1,45 @@ TEMPLATE = app QT -= gui QT += network CONFIG += qtestlib CONFIG += console CONFIG -= app_bundle DEPENDPATH += . INCLUDEPATH += . !win32: LIBS += -lz win32 { # workaround for qdatetime.h macro bug DEFINES += NOMINMAX } CONFIG(staticlib): DEFINES += QUAZIP_STATIC # Input HEADERS += qztest.h \ +JlCompress.h \ testjlcompress.h \ -testquachecksum32.h \ -testquagzipfile.h \ testquaziodevice.h \ -testquazipdir.h \ testquazipfile.h \ testquazip.h \ testquazipnewinfo.h \ testquazipfileinfo.h SOURCES += qztest.cpp \ +JlCompress.cpp \ testjlcompress.cpp \ -testquachecksum32.cpp \ -testquagzipfile.cpp \ testquaziodevice.cpp \ testquazip.cpp \ -testquazipdir.cpp \ testquazipfile.cpp \ testquazipnewinfo.cpp \ testquazipfileinfo.cpp OBJECTS_DIR = .obj MOC_DIR = .moc win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../quazip/release/ -lquazip else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../quazip/debug/ -lquazipd else:mac:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../quazip/ -lquazip_debug else:unix: LIBS += -L$$OUT_PWD/../quazip/ -lquazip INCLUDEPATH += $$PWD/.. DEPENDPATH += $$PWD/../quazip diff --git a/qztest/testjlcompress.cpp b/qztest/testjlcompress.cpp --- a/qztest/testjlcompress.cpp +++ b/qztest/testjlcompress.cpp @@ -1,392 +1,392 @@ /* Copyright (C) 2005-2014 Sergey A. Tachenov This file is part of QuaZIP test suite. QuaZIP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. QuaZIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with QuaZIP. If not, see . See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant and contributors, see quazip/(un)zip.h files for details. Basically it's the zlib license. */ #include "testjlcompress.h" #include "qztest.h" #include #include #include -#include +#include "JlCompress.h" #ifdef Q_OS_WIN #include #endif void TestJlCompress::compressFile_data() { QTest::addColumn("zipName"); QTest::addColumn("fileName"); QTest::newRow("simple") << "jlsimplefile.zip" << "test0.txt"; } void TestJlCompress::compressFile() { QFETCH(QString, zipName); QFETCH(QString, fileName); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(QStringList() << fileName)) { QFAIL("Can't create test file"); } QVERIFY(JlCompress::compressFile(zipName, "tmp/" + fileName)); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); QCOMPARE(fileList.count(), 1); QVERIFY(fileList[0] == fileName); // now test the QIODevice* overload of getFileList() QFile zipFile(zipName); QVERIFY(zipFile.open(QIODevice::ReadOnly)); fileList = JlCompress::getFileList(zipName); QCOMPARE(fileList.count(), 1); QVERIFY(fileList[0] == fileName); zipFile.close(); removeTestFiles(QStringList() << fileName); curDir.remove(zipName); } void TestJlCompress::compressFiles_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "jlsimplefiles.zip" << (QStringList() << "test0.txt" << "test00.txt"); QTest::newRow("different subdirs") << "jlsubdirfiles.zip" << (QStringList() << "subdir1/test1.txt" << "subdir2/test2.txt"); } void TestJlCompress::compressFiles() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test files"); } QStringList realNamesList, shortNamesList; foreach (QString fileName, fileNames) { QString realName = "tmp/" + fileName; realNamesList += realName; shortNamesList += QFileInfo(realName).fileName(); } QVERIFY(JlCompress::compressFiles(zipName, realNamesList)); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); QCOMPARE(fileList, shortNamesList); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::compressDir_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("expected"); QTest::newRow("simple") << "jldir.zip" << (QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << (QStringList() << "test0.txt" << "testdir1/" << "testdir1/test1.txt" << "testdir2/" << "testdir2/test2.txt" << "testdir2/subdir/" << "testdir2/subdir/test2sub.txt"); QTest::newRow("empty dirs") << "jldir_empty.zip" << (QStringList() << "testdir1/" << "testdir2/testdir3/") << (QStringList() << "testdir1/" << "testdir2/" << "testdir2/testdir3/"); QTest::newRow("hidden files") << "jldir_hidden.zip" << (QStringList() << ".test0.txt" << "test1.txt") << (QStringList() << ".test0.txt" << "test1.txt"); } void TestJlCompress::compressDir() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QStringList, expected); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames, -1, "compressDir_tmp")) { QFAIL("Can't create test files"); } #ifdef Q_OS_WIN for (int i = 0; i < fileNames.size(); ++i) { if (fileNames.at(i).startsWith(".")) { QString fn = "compressDir_tmp\\" + fileNames.at(i); SetFileAttributesW(reinterpret_cast(fn.utf16()), FILE_ATTRIBUTE_HIDDEN); } } #endif QVERIFY(JlCompress::compressDir(zipName, "compressDir_tmp", true, QDir::Hidden)); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); qSort(fileList); qSort(expected); QCOMPARE(fileList, expected); removeTestFiles(fileNames, "compressDir_tmp"); curDir.remove(zipName); } void TestJlCompress::extractFile_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("fileToExtract"); QTest::addColumn("destName"); QTest::addColumn("encoding"); QTest::newRow("simple") << "jlextfile.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << "testdir2/test2.txt" << "test2.txt" << QByteArray(); QTest::newRow("russian") << "jlextfilerus.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << QString::fromUtf8("testdir2/тест2.txt") << "testdir2/subdir/test2sub.txt") << QString::fromUtf8("testdir2/тест2.txt") << QString::fromUtf8("тест2.txt") << QByteArray("IBM866"); QTest::newRow("extract dir") << "jlextdir.zip" << ( QStringList() << "testdir1/") << "testdir1/" << "testdir1/" << QByteArray(); } void TestJlCompress::extractFile() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QString, fileToExtract); QFETCH(QString, destName); QFETCH(QByteArray, encoding); QDir curDir; if (!curDir.mkpath("jlext/jlfile")) { QFAIL("Couldn't mkpath jlext/jlfile"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } QFile srcFile("tmp/" + fileToExtract); QFile::Permissions srcPerm = srcFile.permissions(); // Invert the "write other" flag so permissions // are NOT default any more. Otherwise it's impossible // to figure out whether the permissions were set correctly // or JlCompress failed to set them completely, // thus leaving them at the default setting. srcPerm ^= QFile::WriteOther; QVERIFY(srcFile.setPermissions(srcPerm)); if (!createTestArchive(zipName, fileNames, QTextCodec::codecForName(encoding))) { QFAIL("Can't create test archive"); } QuaZip::setDefaultFileNameCodec(encoding); QVERIFY(!JlCompress::extractFile(zipName, fileToExtract, "jlext/jlfile/" + destName).isEmpty()); QFileInfo destInfo("jlext/jlfile/" + destName), srcInfo("tmp/" + fileToExtract); QCOMPARE(destInfo.size(), srcInfo.size()); QCOMPARE(destInfo.permissions(), srcInfo.permissions()); curDir.remove("jlext/jlfile/" + destName); // now test the QIODevice* overload QFile zipFile(zipName); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QVERIFY(!JlCompress::extractFile(&zipFile, fileToExtract, "jlext/jlfile/" + destName).isEmpty()); destInfo = QFileInfo("jlext/jlfile/" + destName); QCOMPARE(destInfo.size(), srcInfo.size()); QCOMPARE(destInfo.permissions(), srcInfo.permissions()); curDir.remove("jlext/jlfile/" + destName); if (!fileToExtract.endsWith("/")) { // If we aren't extracting a directory, we need to check // that extractFile() fails if there is a directory // with the same name as the file being extracted. curDir.mkdir("jlext/jlfile/" + destName); QVERIFY(JlCompress::extractFile(zipName, fileToExtract, "jlext/jlfile/" + destName).isEmpty()); } zipFile.close(); // Here we either delete the target dir or the dir created in the // test above. curDir.rmpath("jlext/jlfile/" + destName); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::extractFiles_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("filesToExtract"); QTest::newRow("simple") << "jlextfiles.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << (QStringList() << "testdir2/test2.txt" << "testdir1/test1.txt"); } void TestJlCompress::extractFiles() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QStringList, filesToExtract); QDir curDir; if (!curDir.mkpath("jlext/jlfiles")) { QFAIL("Couldn't mkpath jlext/jlfiles"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QVERIFY(!JlCompress::extractFiles(zipName, filesToExtract, "jlext/jlfiles").isEmpty()); foreach (QString fileName, filesToExtract) { QFileInfo fileInfo("jlext/jlfiles/" + fileName); QFileInfo extInfo("tmp/" + fileName); QCOMPARE(fileInfo.size(), extInfo.size()); QCOMPARE(fileInfo.permissions(), extInfo.permissions()); curDir.remove("jlext/jlfiles/" + fileName); curDir.rmpath(fileInfo.dir().path()); } // now test the QIODevice* overload QFile zipFile(zipName); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QVERIFY(!JlCompress::extractFiles(&zipFile, filesToExtract, "jlext/jlfiles").isEmpty()); foreach (QString fileName, filesToExtract) { QFileInfo fileInfo("jlext/jlfiles/" + fileName); QFileInfo extInfo("tmp/" + fileName); QCOMPARE(fileInfo.size(), extInfo.size()); QCOMPARE(fileInfo.permissions(), extInfo.permissions()); curDir.remove("jlext/jlfiles/" + fileName); curDir.rmpath(fileInfo.dir().path()); } zipFile.close(); curDir.rmpath("jlext/jlfiles"); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::extractDir_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("expectedExtracted"); QTest::newRow("simple") << "jlextdir.zip" << (QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << (QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); QTest::newRow("separate dir") << "sepdir.zip" << (QStringList() << "laj/" << "laj/lajfile.txt") << (QStringList() << "laj/" << "laj/lajfile.txt"); QTest::newRow("Zip Slip") << "zipslip.zip" << (QStringList() << "test0.txt" << "../zipslip.txt") << (QStringList() << "test0.txt"); } void TestJlCompress::extractDir() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QStringList, expectedExtracted); QDir curDir; if (!curDir.mkpath("jlext/jldir")) { QFAIL("Couldn't mkpath jlext/jldir"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Couldn't create test archive"); } QStringList extracted; QCOMPARE((extracted = JlCompress::extractDir(zipName, "jlext/jldir")) .count(), expectedExtracted.count()); const QString dir = "jlext/jldir/"; foreach (QString fileName, expectedExtracted) { QString fullName = dir + fileName; QFileInfo fileInfo(fullName); QFileInfo extInfo("tmp/" + fileName); if (!fileInfo.isDir()) QCOMPARE(fileInfo.size(), extInfo.size()); QCOMPARE(fileInfo.permissions(), extInfo.permissions()); curDir.remove(fullName); curDir.rmpath(fileInfo.dir().path()); QString absolutePath = QDir(dir).absoluteFilePath(fileName); if (fileInfo.isDir() && !absolutePath.endsWith('/')) absolutePath += '/'; QVERIFY(extracted.contains(absolutePath)); } // now test the QIODevice* overload QFile zipFile(zipName); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE((extracted = JlCompress::extractDir(&zipFile, "jlext/jldir")) .count(), expectedExtracted.count()); foreach (QString fileName, expectedExtracted) { QString fullName = dir + fileName; QFileInfo fileInfo(fullName); QFileInfo extInfo("tmp/" + fileName); if (!fileInfo.isDir()) QCOMPARE(fileInfo.size(), extInfo.size()); QCOMPARE(fileInfo.permissions(), extInfo.permissions()); curDir.remove(fullName); curDir.rmpath(fileInfo.dir().path()); QString absolutePath = QDir(dir).absoluteFilePath(fileName); if (fileInfo.isDir() && !absolutePath.endsWith('/')) absolutePath += '/'; QVERIFY(extracted.contains(absolutePath)); } zipFile.close(); curDir.rmpath("jlext/jldir"); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::zeroPermissions() { QuaZip zipCreator("zero.zip"); QVERIFY(zipCreator.open(QuaZip::mdCreate)); QuaZipFile zeroFile(&zipCreator); QuaZipNewInfo newInfo("zero.txt"); newInfo.externalAttr = 0; // should be zero anyway, but just in case QVERIFY(zeroFile.open(QIODevice::WriteOnly, newInfo)); zeroFile.close(); zipCreator.close(); QVERIFY(!JlCompress::extractFile("zero.zip", "zero.txt").isEmpty()); QVERIFY(QFile("zero.txt").permissions() != 0); QDir curDir; curDir.remove("zero.zip"); curDir.remove("zero.txt"); } diff --git a/qztest/testquachecksum32.cpp b/qztest/testquachecksum32.cpp deleted file mode 100644 --- a/qztest/testquachecksum32.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "testquachecksum32.h" - -#include -#include - -#include - -void TestQuaChecksum32::calculate() -{ - QuaCrc32 crc32; - QCOMPARE(crc32.calculate("Wikipedia"), 0xADAAC02Eu); - QuaAdler32 adler32; - QCOMPARE(adler32.calculate("Wikipedia"), 0x11E60398u); -} - -void TestQuaChecksum32::update() -{ - QuaCrc32 crc32; - crc32.update("Wiki"); - crc32.update("pedia"); - QCOMPARE(crc32.value(), 0xADAAC02Eu); - QuaAdler32 adler32; - adler32.update("Wiki"); - adler32.update("pedia"); - QCOMPARE(adler32.value(), 0x11E60398u); -} diff --git a/qztest/testquachecksum32.h b/qztest/testquachecksum32.h deleted file mode 100644 --- a/qztest/testquachecksum32.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef QUAZIP_TEST_QUACHECKSUM32_H -#define QUAZIP_TEST_QUACHECKSUM32_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -class TestQuaChecksum32: public QObject { - Q_OBJECT -private slots: - void calculate(); - void update(); -}; - -#endif // QUAZIP_TEST_QUACHECKSUM32_H diff --git a/qztest/testquagzipfile.cpp b/qztest/testquagzipfile.cpp deleted file mode 100644 --- a/qztest/testquagzipfile.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "testquagzipfile.h" -#include -#include -#include -#include - -void TestQuaGzipFile::read() -{ - QDir curDir; - curDir.mkpath("tmp"); - gzFile file = gzopen("tmp/test.gz", "wb"); - gzwrite(file, "test", 4); - gzclose(file); - QuaGzipFile testFile("tmp/test.gz"); - QVERIFY(testFile.open(QIODevice::ReadOnly)); - char buf[5]; - buf[4] = '\0'; - QCOMPARE(testFile.read(buf, 5), static_cast(4)); - testFile.close(); - QVERIFY(!testFile.isOpen()); - QCOMPARE(static_cast(buf), "test"); - curDir.remove("tmp/test.gz"); - curDir.rmdir("tmp"); -} - -void TestQuaGzipFile::write() -{ - QDir curDir; - curDir.mkpath("tmp"); - QuaGzipFile testFile; - testFile.setFileName("tmp/test.gz"); - QCOMPARE(testFile.getFileName(), QString::fromLatin1("tmp/test.gz")); - QVERIFY(testFile.open(QIODevice::WriteOnly)); - QCOMPARE(testFile.write("test", 4), static_cast(4)); - QVERIFY(testFile.flush()); - testFile.close(); - QVERIFY(!testFile.isOpen()); - gzFile file = gzopen("tmp/test.gz", "rb"); - char buf[5]; - buf[4] = '\0'; - QCOMPARE(gzread(file, buf, 5), 4); - gzclose(file); - QCOMPARE(static_cast(buf), "test"); - curDir.remove("tmp/test.gz"); - curDir.rmdir("tmp"); -} - -void TestQuaGzipFile::constructorDestructor() -{ - QuaGzipFile *f1 = new QuaGzipFile(); - delete f1; // D0 destructor - QObject parent; - QuaGzipFile f2(&parent); - QuaGzipFile f3("test.gz", &parent); -} diff --git a/qztest/testquagzipfile.h b/qztest/testquagzipfile.h deleted file mode 100644 --- a/qztest/testquagzipfile.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef QUAZIP_TEST_QUAGZIPFILE_H -#define QUAZIP_TEST_QUAGZIPFILE_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -class TestQuaGzipFile: public QObject { - Q_OBJECT -private slots: - void read(); - void write(); - void constructorDestructor(); -}; - -#endif // QUAZIP_TEST_QUAGZIPFILE_H diff --git a/qztest/testquazip.cpp b/qztest/testquazip.cpp --- a/qztest/testquazip.cpp +++ b/qztest/testquazip.cpp @@ -1,441 +1,441 @@ /* Copyright (C) 2005-2014 Sergey A. Tachenov This file is part of QuaZIP test suite. QuaZIP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. QuaZIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with QuaZIP. If not, see . See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant and contributors, see quazip/(un)zip.h files for details. Basically it's the zlib license. */ #include "testquazip.h" #include "qztest.h" #include #include #include #include #ifdef QUAZIP_TEST_QSAVEFILE #include #endif #include #include #include #include #include -#include +#include "JlCompress.h" void TestQuaZip::getFileList_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "qzfilelist.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); QTest::newRow("russian") << QString::fromUtf8("файл.zip") << ( QStringList() << QString::fromUtf8("test0.txt") << QString::fromUtf8("test1/test1.txt") << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); QTest::newRow("japanese") << QString::fromUtf8("テスト.zip") << ( QStringList() << QString::fromUtf8("test.txt")); QTest::newRow("hebrew") << QString::fromUtf8("פתח תקווה.zip") << ( QStringList() << QString::fromUtf8("test.txt")); } void TestQuaZip::getFileList() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); qSort(fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test file"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Can't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); QVERIFY(testZip.goToFirstFile()); QString firstFile = testZip.getCurrentFileName(); QStringList fileList = testZip.getFileNameList(); qSort(fileList); QCOMPARE(fileList, fileNames); QHash srcInfo; foreach (QString fileName, fileNames) { srcInfo[fileName] = QFileInfo("tmp/" + fileName); } QList destList = testZip.getFileInfoList(); QCOMPARE(destList.size(), srcInfo.size()); for (int i = 0; i < destList.size(); i++) { QCOMPARE(static_cast(destList[i].uncompressedSize), srcInfo[destList[i].name].size()); } // Now test zip64 QList destList64 = testZip.getFileInfoList64(); QCOMPARE(destList64.size(), srcInfo.size()); for (int i = 0; i < destList64.size(); i++) { QCOMPARE(static_cast(destList64[i].uncompressedSize), srcInfo[destList64[i].name].size()); } // test that we didn't mess up the current file QCOMPARE(testZip.getCurrentFileName(), firstFile); testZip.close(); // clean up removeTestFiles(fileNames); curDir.remove(zipName); } void TestQuaZip::add_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("fileNamesToAdd"); QTest::newRow("simple") << "qzadd.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << (QStringList() << "testAdd.txt"); } void TestQuaZip::add() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QStringList, fileNamesToAdd); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test file"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Can't create test archive"); } if (!createTestFiles(fileNamesToAdd)) { QFAIL("Can't create test files to add"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); // according to the bug #3485459 the global is lost, so we test it QString globalComment = testZip.getComment(); testZip.close(); QVERIFY(testZip.open(QuaZip::mdAdd)); foreach (QString fileName, fileNamesToAdd) { QuaZipFile testFile(&testZip); QVERIFY(testFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName, "tmp/" + fileName))); QFile inFile("tmp/" + fileName); QVERIFY(inFile.open(QIODevice::ReadOnly)); testFile.write(inFile.readAll()); inFile.close(); testFile.close(); } testZip.close(); QVERIFY(testZip.open(QuaZip::mdUnzip)); QStringList allNames = fileNames + fileNamesToAdd; QCOMPARE(testZip.getEntriesCount(), allNames.size()); QCOMPARE(testZip.getFileNameList(), allNames); QCOMPARE(testZip.getComment(), globalComment); testZip.close(); removeTestFiles(fileNames); removeTestFiles(fileNamesToAdd); curDir.remove(zipName); } void TestQuaZip::setFileNameCodec_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("encoding"); QTest::newRow("russian") << QString::fromUtf8("russian.zip") << ( QStringList() << QString::fromUtf8("тест.txt")) << QByteArray("IBM866"); } void TestQuaZip::setFileNameCodec() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QByteArray, encoding); qSort(fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test file"); } if (!createTestArchive(zipName, fileNames, QTextCodec::codecForName(encoding))) { QFAIL("Can't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); QStringList fileList = testZip.getFileNameList(); qSort(fileList); QVERIFY(fileList[0] != fileNames[0]); testZip.close(); testZip.setFileNameCodec(encoding); QVERIFY(testZip.open(QuaZip::mdUnzip)); fileList = testZip.getFileNameList(); qSort(fileList); QCOMPARE(fileList, fileNames); testZip.close(); // clean up removeTestFiles(fileNames); curDir.remove(zipName); } void TestQuaZip::setDataDescriptorWritingEnabled() { QString zipName = "zip10.zip"; QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } QuaZip testZip(zipName); testZip.setDataDescriptorWritingEnabled(false); QVERIFY(testZip.open(QuaZip::mdCreate)); QuaZipFile testZipFile(&testZip); QVERIFY(testZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("vegetation_info.xml"), NULL, 0, 0)); QByteArray contents = "\n"; testZipFile.write(contents); testZipFile.close(); testZip.close(); QuaZipFile readZipFile(zipName, "vegetation_info.xml"); QVERIFY(readZipFile.open(QIODevice::ReadOnly)); // Test that file is not compressed. QCOMPARE(readZipFile.csize(), static_cast(contents.size())); readZipFile.close(); QCOMPARE(QFileInfo(zipName).size(), static_cast(171)); QFile zipFile(zipName); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QDataStream zipData(&zipFile); zipData.setByteOrder(QDataStream::LittleEndian); quint32 magic = 0; quint16 versionNeeded = 0; zipData >> magic; zipData >> versionNeeded; QCOMPARE(magic, static_cast(0x04034b50)); QCOMPARE(versionNeeded, static_cast(10)); zipFile.close(); curDir.remove(zipName); // now test 2.0 zipName = "zip20.zip"; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } QuaZip testZip20(zipName); QVERIFY(testZip20.open(QuaZip::mdCreate)); QuaZipFile testZipFile20(&testZip20); QVERIFY(testZipFile20.open(QIODevice::WriteOnly, QuaZipNewInfo("vegetation_info.xml"), NULL, 0, 0)); testZipFile20.write("\n"); testZipFile20.close(); testZip20.close(); QCOMPARE(QFileInfo(zipName).size(), static_cast(171 + 16)); // 16 bytes = data descriptor QFile zipFile20(zipName); QVERIFY(zipFile20.open(QIODevice::ReadOnly)); QDataStream zipData20(&zipFile20); zipData20.setByteOrder(QDataStream::LittleEndian); magic = 0; versionNeeded = 0; zipData20 >> magic; zipData20 >> versionNeeded; QCOMPARE(magic, static_cast(0x04034b50)); QCOMPARE(versionNeeded, static_cast(20)); zipFile20.close(); curDir.remove(zipName); } void TestQuaZip::testQIODeviceAPI() { QString zipName = "qiodevice_api.zip"; QStringList fileNames; fileNames << "test.txt"; QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test file"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Can't create test archive"); } QBuffer buffer; if (!createTestArchive(&buffer, fileNames, NULL)) { QFAIL("Can't create test archive"); } QFile diskFile(zipName); QVERIFY(diskFile.open(QIODevice::ReadOnly)); QByteArray bufferArray = buffer.buffer(); QByteArray fileArray = diskFile.readAll(); diskFile.close(); QCOMPARE(bufferArray.size(), fileArray.size()); QCOMPARE(bufferArray, fileArray); curDir.remove(zipName); } void TestQuaZip::setZipName() { QuaZip zip; zip.setZipName("testSetZipName.zip"); zip.open(QuaZip::mdCreate); zip.close(); QVERIFY(QFileInfo(zip.getZipName()).exists()); QDir().remove(zip.getZipName()); } void TestQuaZip::setIoDevice() { QuaZip zip; QFile file("testSetIoDevice.zip"); zip.setIoDevice(&file); QCOMPARE(zip.getIoDevice(), &file); zip.open(QuaZip::mdCreate); QVERIFY(file.isOpen()); zip.close(); QVERIFY(!file.isOpen()); QVERIFY(file.exists()); QDir().remove(file.fileName()); } void TestQuaZip::setCommentCodec() { QuaZip zip("commentCodec.zip"); QVERIFY(zip.open(QuaZip::mdCreate)); zip.setCommentCodec("WINDOWS-1251"); zip.setComment(QString::fromUtf8("Вопрос")); QuaZipFile zipFile(&zip); QVERIFY(zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("test.txt"))); zipFile.close(); zip.close(); QVERIFY(zip.open(QuaZip::mdUnzip)); zip.setCommentCodec(QTextCodec::codecForName("KOI8-R")); QCOMPARE(zip.getComment(), QString::fromUtf8("бНОПНЯ")); zip.close(); QDir().remove(zip.getZipName()); } void TestQuaZip::setAutoClose() { { QBuffer buf; QuaZip zip(&buf); QVERIFY(zip.isAutoClose()); QVERIFY(zip.open(QuaZip::mdCreate)); QVERIFY(buf.isOpen()); zip.close(); QVERIFY(!buf.isOpen()); QVERIFY(zip.open(QuaZip::mdCreate)); } { QBuffer buf; QuaZip zip(&buf); QVERIFY(zip.isAutoClose()); zip.setAutoClose(false); QVERIFY(!zip.isAutoClose()); QVERIFY(zip.open(QuaZip::mdCreate)); QVERIFY(buf.isOpen()); zip.close(); QVERIFY(buf.isOpen()); QVERIFY(zip.open(QuaZip::mdCreate)); } } #ifdef QUAZIP_TEST_QSAVEFILE void TestQuaZip::saveFileBug() { QDir curDir; QString zipName = "testSaveFile.zip"; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) { QFAIL("Can't remove testSaveFile.zip"); } } QuaZip zip; QSaveFile saveFile(zipName); zip.setIoDevice(&saveFile); QCOMPARE(zip.getIoDevice(), &saveFile); zip.open(QuaZip::mdCreate); zip.close(); QVERIFY(QFileInfo(saveFile.fileName()).exists()); curDir.remove(saveFile.fileName()); } #endif void TestQuaZip::testSequential() { QTcpServer server; QVERIFY(server.listen(QHostAddress(QHostAddress::LocalHost))); quint16 port = server.serverPort(); QTcpSocket socket; socket.connectToHost(QHostAddress(QHostAddress::LocalHost), port); QVERIFY(socket.waitForConnected()); QVERIFY(server.waitForNewConnection(30000)); QTcpSocket *client = server.nextPendingConnection(); QuaZip zip(&socket); zip.setAutoClose(false); QVERIFY(zip.open(QuaZip::mdCreate)); QVERIFY(socket.isOpen()); QuaZipFile zipFile(&zip); QuaZipNewInfo info("test.txt"); QVERIFY(zipFile.open(QIODevice::WriteOnly, info, NULL, 0, 0)); QCOMPARE(zipFile.write("test"), static_cast(4)); zipFile.close(); zip.close(); QVERIFY(socket.isOpen()); socket.disconnectFromHost(); QVERIFY(socket.waitForDisconnected()); QVERIFY(client->waitForReadyRead()); QByteArray received = client->readAll(); #ifdef QUAZIP_QZTEST_QUAZIP_DEBUG_SOCKET QFile debug("testSequential.zip"); debug.open(QIODevice::WriteOnly); debug.write(received); debug.close(); #endif client->close(); QBuffer buffer(&received); QuaZip receivedZip(&buffer); QVERIFY(receivedZip.open(QuaZip::mdUnzip)); QVERIFY(receivedZip.goToFirstFile()); QuaZipFileInfo64 receivedInfo; QVERIFY(receivedZip.getCurrentFileInfo(&receivedInfo)); QCOMPARE(receivedInfo.name, QString::fromLatin1("test.txt")); QCOMPARE(receivedInfo.uncompressedSize, static_cast(4)); QuaZipFile receivedFile(&receivedZip); QVERIFY(receivedFile.open(QIODevice::ReadOnly)); QByteArray receivedText = receivedFile.readAll(); QCOMPARE(receivedText, QByteArray("test")); receivedFile.close(); receivedZip.close(); } diff --git a/qztest/testquazipdir.cpp b/qztest/testquazipdir.cpp deleted file mode 100644 --- a/qztest/testquazipdir.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "testquazipdir.h" -#include "qztest.h" -#include -#include -#include - -void TestQuaZipDir::entryList_data() -{ - QTest::addColumn("zipName"); - QTest::addColumn("fileNames"); - QTest::addColumn("dirName"); - QTest::addColumn("nameFilters"); - // QDir::Filters type breaks Qt meta type system on MSVC - QTest::addColumn("filter"); - QTest::addColumn("sort"); - QTest::addColumn("entries"); - QTest::addColumn("caseSensitivity"); - QTest::newRow("simple") << "simple.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "testdir2" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Unsorted) - << (QStringList() << "test2.txt" << "subdir/") << -1; - QTest::newRow("separate dir") << "sepdir.zip" << ( - QStringList() << "laj/" << "laj/lajfile.txt") - << "" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Unsorted) - << (QStringList() << "laj/") << -1; - QTest::newRow("separate dir (subdir listing)") << "sepdirsub.zip" << ( - QStringList() << "laj/" << "laj/lajfile.txt") - << "laj" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Unsorted) - << (QStringList() << "lajfile.txt") << -1; - QTest::newRow("dirs only") << "dirsonly.zip" << ( - QStringList() << "file" << "dir/") - << "" << QStringList() - << static_cast(QDir::Dirs) - << static_cast(QDir::Unsorted) - << (QStringList() << "dir/") << -1; - QTest::newRow("files only") << "filesonly.zip" << ( - QStringList() << "file1" << "parent/dir/" << "parent/file2") - << "parent" << QStringList() - << static_cast(QDir::Files) - << static_cast(QDir::Unsorted) - << (QStringList() << "file2") << -1; - QTest::newRow("sorted") << "sorted.zip" << ( - QStringList() << "file1" << "parent/subdir/" << "parent/subdir2/file3" << "parent/file2" << "parent/file0") - << "parent" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name) - << (QStringList() << "file0" << "file2" << "subdir/" << "subdir2/") - << -1; - QTest::newRow("sorted dirs first") << "sorted-dirs.zip" << ( - QStringList() << "file1" << "parent/subdir/" << "parent/subdir2/file3" << "parent/file2" << "parent/file0") - << "parent" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name | QDir::DirsFirst) - << (QStringList() << "subdir/" << "subdir2/" << "file0" << "file2") - << -1; - QTest::newRow("sorted dirs first reversed") << "sorted-reverse.zip" << ( - QStringList() << "file1" << "parent/subdir/" << "parent/subdir2/file3" << "parent/file2" << "parent/file0") - << "parent" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name | QDir::DirsFirst | QDir::Reversed) - << (QStringList() << "subdir2/" << "subdir/" << "file2" << "file0") - << -1; - QTest::newRow("sorted by size") << "sorted-size.zip" << ( - QStringList() << "file000" << "file10") - << "/" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Size) - << (QStringList() << "file10" << "file000") << -1; - QTest::newRow("sorted by time") << "sorted-time.zip" << ( - QStringList() << "file04" << "file03" << "file02" << "subdir/subfile") - << "/" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Time) - << (QStringList() << "subdir/" << "file04" << "file02" << "file03") - << -1; - QTest::newRow("sorted by type") << "sorted-type.zip" << ( - QStringList() << "file1.txt" << "file2.dat") - << "/" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Type) - << (QStringList() << "file2.dat" << "file1.txt") << -1; - QTest::newRow("name filter") << "name-filter.zip" << ( - QStringList() << "file01" << "file02" << "laj") - << "/" << QStringList("file*") - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name) - << (QStringList() << "file01" << "file02") << -1; - QTest::newRow("case sensitive") << "case-sensitive.zip" << ( - QStringList() << "a" << "B") - << "/" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name) - << (QStringList() << "B" << "a") - << static_cast(QuaZip::csSensitive); - QTest::newRow("case insensitive") << "case-insensitive.zip" << ( - QStringList() << "B" << "a") - << "/" << QStringList() - << static_cast(QDir::NoFilter) - << static_cast(QDir::Name) - << (QStringList() << "a" << "B") - << static_cast(QuaZip::csInsensitive); -} - -void TestQuaZipDir::entryList() -{ - QFETCH(QString, zipName); - QFETCH(QStringList, fileNames); - QFETCH(QString, dirName); - QFETCH(QStringList, nameFilters); - QFETCH(int, filter); - QFETCH(int, sort); - QDir::Filters filters = static_cast(filter); - QDir::SortFlags sorting = static_cast(sort); - QFETCH(QStringList, entries); - QFETCH(int, caseSensitivity); - QDir curDir; - if (!createTestFiles(fileNames)) { - QFAIL("Couldn't create test files"); - } - if (!createTestArchive(zipName, fileNames)) { - QFAIL("Couldn't create test archive"); - } - removeTestFiles(fileNames); - QuaZip zip(zipName); - QVERIFY(zip.open(QuaZip::mdUnzip)); - QuaZipDir dir(&zip, dirName); - QVERIFY(dir.exists()); - if (caseSensitivity != -1) { - dir.setCaseSensitivity(static_cast( - caseSensitivity)); - QCOMPARE(dir.caseSensitivity(), static_cast( - caseSensitivity)); - } - QCOMPARE(dir.entryList(nameFilters, filters, sorting), entries); - // Test default sorting setting. - dir.setSorting(sorting); - QCOMPARE(dir.sorting(), sorting); - QCOMPARE(dir.entryList(nameFilters, filters), entries); - // Test default name filter setting. - dir.setNameFilters(nameFilters); - QCOMPARE(dir.nameFilters(), nameFilters); - QCOMPARE(dir.entryList(filters), entries); - // Test default filters. - dir.setFilter(filters); - QCOMPARE(dir.filter(), filters); - QCOMPARE(dir.entryList(), entries); - QCOMPARE(dir.entryList().count(), static_cast(dir.count())); - zip.close(); - curDir.remove(zipName); -} - -void TestQuaZipDir::cd_data() -{ - QTest::addColumn("zipName"); - QTest::addColumn("fileNames"); - QTest::addColumn("dirName"); - QTest::addColumn("targetDirName"); - QTest::addColumn("result"); - QTest::newRow("cdDown") << "simple.zip" << ( - QStringList() << "cddown.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "" << "testdir1" << "testdir1"; - QTest::newRow("cdUp") << "cdup.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "testdir1" << ".." << ""; - QTest::newRow("cdSide") << "cdside.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "testdir1" << "../testdir2" << "testdir2"; - QTest::newRow("cdDownUp") << "cdside.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "" << "testdir1/.." << ""; - QTest::newRow("cdDeep") << "cdside.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "" << "testdir2/subdir" << "testdir2/subdir"; - QTest::newRow("cdDeeper") << "cdside.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/subdir2/subdir3/test2sub.txt") - << "testdir2/subdir" << "subdir2/subdir3" << "testdir2/subdir/subdir2/subdir3"; - QTest::newRow("cdRoot") << "cdup.zip" << ( - QStringList() << "test0.txt" << "testdir1/test1.txt" - << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") - << "testdir1" << "/" << ""; -} - -void TestQuaZipDir::cd() -{ - QFETCH(QString, zipName); - QFETCH(QStringList, fileNames); - QFETCH(QString, dirName); - QFETCH(QString, targetDirName); - QFETCH(QString, result); - QDir curDir; - if (!createTestFiles(fileNames)) { - QFAIL("Couldn't create test files"); - } - if (!createTestArchive(zipName, fileNames)) { - QFAIL("Couldn't create test archive"); - } - removeTestFiles(fileNames); - QuaZip zip(zipName); - QVERIFY(zip.open(QuaZip::mdUnzip)); - QuaZipDir dir(&zip, dirName); - if (dirName.startsWith('/')) { - dirName = dirName.mid(1); - } - if (dirName.endsWith('/')) { - dirName.chop(1); - } - QCOMPARE(dir.path(), dirName); - { - int lastSlash = dirName.lastIndexOf('/'); - if (lastSlash == -1) { - // dirName is just a single name - if (dirName.isEmpty()) { - QCOMPARE(dir.dirName(), QString::fromLatin1(".")); - } else { - QCOMPARE(dir.dirName(), dirName); - } - } else { - // dirName is a sequence - QCOMPARE(dir.dirName(), dirName.mid(lastSlash + 1)); - } - } - if (targetDirName == "..") { - QVERIFY(dir.cdUp()); - } else { - QVERIFY(dir.cd(targetDirName)); - } - QCOMPARE(dir.path(), result); - // Try to go back - dir.setPath(dirName); - QCOMPARE(dir.path(), dirName); - zip.close(); - curDir.remove(zipName); -} - -void TestQuaZipDir::entryInfoList() -{ - QString zipName = "entryInfoList.zip"; - QStringList fileNames; - fileNames << "test.txt"; - if (!createTestFiles(fileNames)) { - QFAIL("Couldn't create test files"); - } - if (!createTestArchive(zipName, fileNames)) { - QFAIL("Couldn't create test archive"); - } - removeTestFiles(fileNames); - QuaZip zip(zipName); - QDir curDir; - QVERIFY(zip.open(QuaZip::mdUnzip)); - QuaZipDir dir(&zip, "/"); - QCOMPARE(dir.entryInfoList().size(), 1); - QCOMPARE(dir.entryInfoList64().size(), 1); - zip.close(); - curDir.remove(zipName); -} - -void TestQuaZipDir::operators() -{ - QString zipName = "zipDirOperators.zip"; - QStringList fileNames; - fileNames << "dir/test.txt" << "root.txt"; - if (!createTestFiles(fileNames)) { - QFAIL("Couldn't create test files"); - } - if (!createTestArchive(zipName, fileNames)) { - QFAIL("Couldn't create test archive"); - } - removeTestFiles(fileNames); - QuaZip zip(zipName); - QDir curDir; - QVERIFY(zip.open(QuaZip::mdUnzip)); - QuaZipDir dir(&zip, "dir"); - QuaZipDir dir2 = dir; // Copy constructor - QCOMPARE(dir2.path(), QString::fromLatin1("dir")); - dir2.cdUp(); - QCOMPARE(dir2.path(), QString::fromLatin1("")); - QCOMPARE(dir.path(), QString::fromLatin1("dir")); - dir2 = dir; // operator=() - QCOMPARE(dir2.path(), QString::fromLatin1("dir")); - QVERIFY(dir2 == dir); // opertor== - dir.cd("/"); - QCOMPARE(dir[0], QString::fromLatin1("dir/")); - QCOMPARE(dir[1], QString::fromLatin1("root.txt")); - zip.close(); - curDir.remove(zipName); -} - -void TestQuaZipDir::filePath() -{ - QString zipName = "entryInfoList.zip"; - QStringList fileNames; - fileNames << "root.txt" << "dir/test.txt"; - if (!createTestFiles(fileNames)) { - QFAIL("Couldn't create test files"); - } - if (!createTestArchive(zipName, fileNames)) { - QFAIL("Couldn't create test archive"); - } - removeTestFiles(fileNames); - QuaZip zip(zipName); - QDir curDir; - QVERIFY(zip.open(QuaZip::mdUnzip)); - QuaZipDir dir(&zip); - QVERIFY(dir.cd("dir")); - QCOMPARE(dir.relativeFilePath("/root.txt"), - QString::fromLatin1("../root.txt")); - QCOMPARE(dir.filePath("test.txt"), - QString::fromLatin1("dir/test.txt")); - zip.close(); - curDir.remove(zipName); -} diff --git a/qztest/testquazipdir.h b/qztest/testquazipdir.h deleted file mode 100644 --- a/qztest/testquazipdir.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef QUAZIP_TEST_QUAZIPDIR_H -#define QUAZIP_TEST_QUAZIPDIR_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZIP test suite. - -QuaZIP is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZIP is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZIP. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -class TestQuaZipDir: public QObject { - Q_OBJECT -private slots: - void entryList_data(); - void entryList(); - void cd_data(); - void cd(); - void entryInfoList(); - void operators(); - void filePath(); -}; - -#endif // QUAZIP_TEST_QUAZIPDIR_H diff --git a/qztest/testquazipfile.cpp b/qztest/testquazipfile.cpp --- a/qztest/testquazipfile.cpp +++ b/qztest/testquazipfile.cpp @@ -1,575 +1,572 @@ /* Copyright (C) 2005-2014 Sergey A. Tachenov This file is part of QuaZIP test suite. QuaZIP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. QuaZIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with QuaZIP. If not, see . See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant and contributors, see quazip/(un)zip.h files for details. Basically it's the zlib license. */ #include "testquazipfile.h" #include "qztest.h" -#include +#include "JlCompress.h" #include #include #include #include #include #include void TestQuaZipFile::zipUnzip_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("fileNameCodec"); QTest::addColumn("password"); QTest::addColumn("zip64"); QTest::addColumn("size"); QTest::newRow("simple") << "simple.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << QByteArray() << QByteArray() << false << -1; QTest::newRow("Cyrillic") << "cyrillic.zip" << ( QStringList() << QString::fromUtf8("русское имя файла с пробелами.txt")) << QByteArray("IBM866") << QByteArray() << false << -1; - QTest::newRow("password") << "password.zip" << ( - QStringList() << "test.txt") - << QByteArray() << QByteArray("PassPass") << false << -1; QTest::newRow("zip64") << "zip64.zip" << ( QStringList() << "test64.txt") << QByteArray() << QByteArray() << true << -1; QTest::newRow("large enough to flush") << "flush.zip" << ( QStringList() << "flush.txt") << QByteArray() << QByteArray() << true << 65536 * 2; } void TestQuaZipFile::zipUnzip() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QByteArray, fileNameCodec); QFETCH(QByteArray, password); QFETCH(bool, zip64); QFETCH(int, size); QFile testFile(zipName); if (testFile.exists()) { if (!testFile.remove()) { QFAIL("Couldn't remove existing archive to create a new one"); } } if (!createTestFiles(fileNames, size)) { QFAIL("Couldn't create test files for zipping"); } QuaZip testZip(&testFile); testZip.setZip64Enabled(zip64); if (!fileNameCodec.isEmpty()) testZip.setFileNameCodec(fileNameCodec); QVERIFY(testZip.open(QuaZip::mdCreate)); QString comment = "Test comment"; testZip.setComment(comment); foreach (QString fileName, fileNames) { QFile inFile("tmp/" + fileName); if (!inFile.open(QIODevice::ReadOnly)) { qDebug("File name: %s", fileName.toUtf8().constData()); QFAIL("Couldn't open input file"); } QuaZipFile outFile(&testZip); QVERIFY(outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName, inFile.fileName()), password.isEmpty() ? NULL : password.constData())); for (qint64 pos = 0, len = inFile.size(); pos < len; ) { char buf[4096]; qint64 readSize = qMin(static_cast(4096), len - pos); qint64 l; if ((l = inFile.read(buf, readSize)) != readSize) { qDebug("Reading %ld bytes from %s at %ld returned %ld", static_cast(readSize), fileName.toUtf8().constData(), static_cast(pos), static_cast(l)); QFAIL("Read failure"); } QVERIFY(outFile.write(buf, readSize)); pos += readSize; } inFile.close(); outFile.close(); QCOMPARE(outFile.getZipError(), ZIP_OK); } testZip.close(); QCOMPARE(testZip.getZipError(), ZIP_OK); // now test unzip QuaZip testUnzip(&testFile); if (!fileNameCodec.isEmpty()) testUnzip.setFileNameCodec(fileNameCodec); QVERIFY(testUnzip.open(QuaZip::mdUnzip)); QCOMPARE(testUnzip.getComment(), comment); QVERIFY(testUnzip.goToFirstFile()); foreach (QString fileName, fileNames) { QuaZipFileInfo64 info; QVERIFY(testUnzip.getCurrentFileInfo(&info)); QCOMPARE(info.name, fileName); QCOMPARE(info.isEncrypted(), !password.isEmpty()); QFile original("tmp/" + fileName); QVERIFY(original.open(QIODevice::ReadOnly)); QuaZipFile archived(&testUnzip); QVERIFY(archived.open(QIODevice::ReadOnly, password.isEmpty() ? NULL : password.constData())); QByteArray originalData = original.readAll(); QByteArray archivedData = archived.readAll(); QCOMPARE(archivedData, originalData); testUnzip.goToNextFile(); } if (!password.isEmpty()) { QVERIFY(testUnzip.goToFirstFile()); QuaZipFileInfo64 info; QVERIFY(testUnzip.getCurrentFileInfo(&info)); QFile original("tmp/" + info.name); QVERIFY(original.open(QIODevice::ReadOnly)); QuaZipFile archived(&testUnzip); QVERIFY(archived.open(QIODevice::ReadOnly, "WrongPassword")); QByteArray originalData = original.readAll(); QByteArray archivedData = archived.readAll(); QVERIFY(archivedData != originalData); } testUnzip.close(); QCOMPARE(testUnzip.getZipError(), UNZ_OK); // clean up removeTestFiles(fileNames); testFile.remove(); } void TestQuaZipFile::bytesAvailable_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("size"); QTest::newRow("simple") << "test.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << -1; QTest::newRow("large enough to flush") << "flush.zip" << (QStringList() << "test.txt") << 65536 * 4; } void TestQuaZipFile::bytesAvailable() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(int, size); QDir curDir; if (!createTestFiles(fileNames, size)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.bytesAvailable(), fileInfo.size()); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.bytesAvailable(), fileInfo.size() - 1); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.bytesAvailable(), (qint64) 0); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::atEnd_data() { bytesAvailable_data(); } void TestQuaZipFile::atEnd() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(int, size); QDir curDir; if (!createTestFiles(fileNames, size)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.atEnd(), false); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.atEnd(), false); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.atEnd(), true); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::posRead_data() { bytesAvailable_data(); } void TestQuaZipFile::posRead() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(int, size); QDir curDir; if (!createTestFiles(fileNames, size)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.pos(), (qint64) 0); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.pos(), (qint64) 1); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.pos(), fileInfo.size()); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::posWrite_data() { posRead_data(); } void TestQuaZipFile::posWrite() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(int, size); if (size == -1) size = 20; QDir curDir; QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdCreate)); foreach (QString fileName, fileNames) { QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName))); QCOMPARE(zipFile.pos(), (qint64) 0); zipFile.putChar('0'); QCOMPARE(zipFile.pos(), (qint64) 1); QByteArray buffer(size / 2 - 1, '\0'); for (int i = 0; i < buffer.size(); ++i) buffer[i] = static_cast(qrand()); zipFile.write(buffer); QCOMPARE(zipFile.pos(), qint64(size / 2)); for (int i = 0; i < size - size / 2; ++i) { zipFile.putChar(static_cast(qrand())); } QCOMPARE(zipFile.pos(), qint64(size)); } testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::getZip() { QuaZip testZip; QuaZipFile f1(&testZip); QCOMPARE(f1.getZip(), &testZip); QuaZipFile f2("doesntexist.zip", "someFile"); QCOMPARE(f2.getZip(), static_cast(NULL)); f2.setZip(&testZip); QCOMPARE(f2.getZip(), &testZip); } void TestQuaZipFile::setZipName() { QString testFileName = "testZipName.txt"; QString testZipName = "testZipName.zip"; QVERIFY(createTestFiles(QStringList() << testFileName)); QVERIFY(createTestArchive(testZipName, QStringList() << testFileName)); QuaZipFile testFile; testFile.setZipName(testZipName); QCOMPARE(testFile.getZipName(), testZipName); testFile.setFileName(testFileName); QVERIFY(testFile.open(QIODevice::ReadOnly)); testFile.close(); removeTestFiles(QStringList() << testFileName); QDir curDir; curDir.remove(testZipName); } void TestQuaZipFile::getFileInfo() { QuaZipFileInfo info32; QuaZipFileInfo64 info64; QString testFileName = "testZipName.txt"; QStringList testFiles; testFiles << testFileName; QString testZipName = "testZipName.zip"; QVERIFY(createTestFiles(testFiles)); QVERIFY(createTestArchive(testZipName, testFiles)); QuaZipFile testFile; testFile.setZipName(testZipName); testFile.setFileName(testFileName); QVERIFY(testFile.open(QIODevice::ReadOnly)); QVERIFY(testFile.getFileInfo(&info32)); QVERIFY(testFile.getFileInfo(&info64)); QCOMPARE(info32.name, info64.name); QCOMPARE(info32.versionCreated, info64.versionCreated); QCOMPARE(info32.versionNeeded, info64.versionNeeded); QCOMPARE(info32.flags, info64.flags); QCOMPARE(info32.method, info64.method); QCOMPARE(info32.dateTime, info64.dateTime); QCOMPARE(info32.crc, info64.crc); QCOMPARE(info32.compressedSize, static_cast(info64.compressedSize)); QCOMPARE(info32.uncompressedSize, static_cast(info64.uncompressedSize)); QCOMPARE(info32.diskNumberStart, info64.diskNumberStart); QCOMPARE(info32.internalAttr, info64.internalAttr); QCOMPARE(info32.externalAttr, info64.externalAttr); QCOMPARE(info32.comment, info64.comment); QCOMPARE(info32.extra, info64.extra); testFile.close(); removeTestFiles(testFiles); QDir curDir; curDir.remove(testZipName); } void TestQuaZipFile::setFileName() { QString testFileName = "testZipName.txt"; QString testZipName = "testZipName.zip"; QVERIFY(createTestFiles(QStringList() << testFileName)); QVERIFY(createTestArchive(testZipName, QStringList() << testFileName)); QuaZipFile testFile(testZipName); testFile.setFileName(testFileName.toUpper()); #ifdef Q_OS_WIN QVERIFY(testFile.open(QIODevice::ReadOnly)); testFile.close(); #else QVERIFY(!testFile.open(QIODevice::ReadOnly)); #endif testFile.setFileName(testFileName.toUpper(), QuaZip::csInsensitive); QCOMPARE(testFile.getCaseSensitivity(), QuaZip::csInsensitive); QVERIFY(testFile.open(QIODevice::ReadOnly)); QCOMPARE(testFile.getActualFileName(), testFileName); testFile.close(); testFile.setFileName(testFileName.toUpper(), QuaZip::csSensitive); QCOMPARE(testFile.getFileName(), testFileName.toUpper()); QCOMPARE(testFile.getActualFileName(), QString()); QVERIFY(!testFile.open(QIODevice::ReadOnly)); testFile.setFileName(testFileName); removeTestFiles(QStringList() << testFileName); QDir curDir; curDir.remove(testZipName); } void TestQuaZipFile::constructorDestructor() { // Just test that all constructors and destructors are available. // (So there are none that are declared but not defined.) QuaZip testZip; QuaZipFile *f1 = new QuaZipFile(); delete f1; // test D0 destructor QObject parent; QuaZipFile f2(&testZip, &parent); QuaZipFile f3(&parent); QuaZipFile f4("zipName.zip"); QuaZipFile f5("zipName.zip", "fileName.txt", QuaZip::csDefault, &parent); } void TestQuaZipFile::setFileAttrs() { QuaZip testZip("setFileAttrs.zip"); QVERIFY(testZip.open(QuaZip::mdCreate)); QuaZipFile zipFile(&testZip); QuaZipNewInfo newInfo("testPerm.txt"); newInfo.setPermissions(QFile::ReadOwner); QVERIFY(zipFile.open(QIODevice::WriteOnly, newInfo)); zipFile.close(); QString fileTestAttr = "testAttr.txt"; QStringList fileNames; fileNames << fileTestAttr; QVERIFY(createTestFiles(fileNames)); newInfo.name = fileTestAttr; newInfo.setFileDateTime("tmp/" + fileTestAttr); newInfo.setFilePermissions("tmp/" + fileTestAttr); QVERIFY(zipFile.open(QIODevice::WriteOnly, newInfo)); zipFile.close(); testZip.close(); QuaZipFileInfo64 info; { QuaZipFile readFilePerm("setFileAttrs.zip", "testPerm.txt"); QVERIFY(readFilePerm.open(QIODevice::ReadOnly)); QVERIFY(readFilePerm.getFileInfo(&info)); QCOMPARE(info.getPermissions(), QFile::ReadOwner); readFilePerm.close(); } { QuaZipFile readFileAttrs("setFileAttrs.zip", "testAttr.txt"); QVERIFY(readFileAttrs.open(QIODevice::ReadOnly)); QVERIFY(readFileAttrs.getFileInfo(&info)); QFileInfo srcInfo("tmp/" + fileTestAttr); QFile::Permissions usedPermissions = QFile::WriteOwner | QFile::ReadOwner | QFile::ExeOwner | QFile::WriteGroup | QFile::ReadGroup | QFile::ExeGroup | QFile::WriteOther | QFile::ReadOther | QFile::ExeOther; QCOMPARE(info.getPermissions() & usedPermissions, srcInfo.permissions() & usedPermissions); // I really hope Qt 6 will use quint64 for time_t! quint64 newTime = info.dateTime.toTime_t(); quint64 oldTime = srcInfo.lastModified().toTime_t(); // ZIP uses weird format with 2 second precision QCOMPARE(newTime / 2, oldTime / 2); readFileAttrs.close(); } removeTestFiles(fileNames); QDir().remove(testZip.getZipName()); } void TestQuaZipFile::largeFile() { QDir curDir; QVERIFY(curDir.mkpath("tmp")); QFile fakeLargeFile("tmp/large.zip"); QVERIFY(fakeLargeFile.open(QIODevice::WriteOnly)); QDataStream ds(&fakeLargeFile); ds.setByteOrder(QDataStream::LittleEndian); QList localOffsets; const int numFiles = 2; // name fixed to 5 bytes, so MAX 10 FILES!!! for (int i = 0; i < numFiles; ++i) { localOffsets.append(fakeLargeFile.pos()); QBuffer extra; extra.open(QIODevice::WriteOnly); QDataStream es(&extra); es.setByteOrder(QDataStream::LittleEndian); // prepare extra es << static_cast(0x0001u); // zip64 es << static_cast(16); // extra data size es << static_cast(0); // uncompressed size es << static_cast(0); // compressed size // now the local header ds << static_cast(0x04034b50u); // local magic ds << static_cast(45); // version needed ds << static_cast(0); // flags ds << static_cast(0); // method ds << static_cast(0); // time 00:00:00 ds << static_cast(0x21); // date 1980-01-01 ds << static_cast(0); // CRC-32 ds << static_cast(0xFFFFFFFFu); // compressed size ds << static_cast(0xFFFFFFFFu); // uncompressed size ds << static_cast(5); // name length ds << static_cast(extra.size()); // extra length ds.writeRawData("file", 4); // name ds << static_cast('0' + i); // name (contd.) ds.writeRawData(extra.buffer(), extra.size()); } // central dir: qint64 centralStart = fakeLargeFile.pos(); for (int i = 0; i < numFiles; ++i) { QBuffer extra; extra.open(QIODevice::WriteOnly); QDataStream es(&extra); es.setByteOrder(QDataStream::LittleEndian); // prepare extra es << static_cast(0x0001u); // zip64 es << static_cast(24); // extra data size es << static_cast(0); // uncompressed size es << static_cast(0); // compressed size es << static_cast(localOffsets[i]); // now the central dir header ds << static_cast(0x02014b50u); // central magic ds << static_cast(45); // version made by ds << static_cast(45); // version needed ds << static_cast(0); // flags ds << static_cast(0); // method ds << static_cast(0); // time 00:00:00 ds << static_cast(0x21); // date 1980-01-01 ds << static_cast(0); // CRC-32 ds << static_cast(0xFFFFFFFFu); // compressed size ds << static_cast(0xFFFFFFFFu); // uncompressed size ds << static_cast(5); // name length ds << static_cast(extra.size()); // extra length ds << static_cast(0); // comment length ds << static_cast(0); // disk number ds << static_cast(0); // internal attrs ds << static_cast(0); // external attrs ds << static_cast(0xFFFFFFFFu); // local offset ds.writeRawData("file", 4); // name ds << static_cast('0' + i); // name (contd.) ds.writeRawData(extra.buffer(), extra.size()); } qint64 centralEnd = fakeLargeFile.pos(); // zip64 end ds << static_cast(0x06064b50); // zip64 end magic ds << static_cast(44); // size of the zip64 end ds << static_cast(45); // version made by ds << static_cast(45); // version needed ds << static_cast(0); // disk number ds << static_cast(0); // central dir disk number ds << static_cast(2); // number of entries on disk ds << static_cast(2); // total number of entries ds << static_cast(centralEnd - centralStart); // size ds << static_cast(centralStart); // offset // zip64 locator ds << static_cast(0x07064b50); // zip64 locator magic ds << static_cast(0); // disk number ds << static_cast(centralEnd); // offset ds << static_cast(1); // number of disks // zip32 end ds << static_cast(0x06054b50); // end magic ds << static_cast(0); // disk number ds << static_cast(0); // central dir disk number ds << static_cast(2); // number of entries ds << static_cast(0xFFFFFFFFu); // central dir size ds << static_cast(0xFFFFFFFFu); // central dir offset ds << static_cast(0); // comment length fakeLargeFile.close(); QuaZip fakeLargeZip("tmp/large.zip"); QVERIFY(fakeLargeZip.open(QuaZip::mdUnzip)); QCOMPARE(fakeLargeZip.getFileInfoList().size(), numFiles); QCOMPARE(fakeLargeZip.getFileInfoList()[0].uncompressedSize, static_cast(0)); fakeLargeZip.close(); curDir.remove("tmp/large.zip"); } diff --git a/readme-lite.md b/readme-lite.md new file mode 100644 --- /dev/null +++ b/readme-lite.md @@ -0,0 +1,53 @@ +# Удаление избыточных функций из библиотеки QuaZip + +После выполнения перечисленных ниже действий в билиотеке останется всё необходимоё. +Будут успешно проходить все тесты, кроме связанных с удалёнными функциями. + +## Удалить файлы + +В каталоге `quazip`: + + minizip_crypt.h + quaadler32.cpp + quaadler32.h + quachecksum32.h + quacrc32.cpp + quacrc32.h + quagzipfile.cpp + quagzipfile.h + quazipdir.cpp + quazipdir.h + +В каталоге `qztest`: + + testquachecksum32.cpp + testquachecksum32.h + testquagzipfile.cpp + testquagzipfile.h + testquazipdir.cpp + testquazipdir.h + +## Переместить файлы + +Переместить файлы в каталог `qztest`. +Они не нужны в библиотеке, но используются в тестах, поэтому не удаляем. + + JlCompress.cpp + JlCompress.h + +## Изменить файлы проектов + +Выполнить `patch -p1 < project.diff`. +Файлы `quazip.pri` и `qztest.pro` будут обновлены с учётом удаления и перемещения исходных файлов + +## Изменить исходные тексты + +Выполнить `patch -p1 < zip.diff`. +Из файлов `zip.h`, `zip.cpp`, `unzip.h`, `unzip.cpp` будут удалены: + +* строки, реализующие функции _crypt_, в блоках условной компиляции `NOCRYPT` и `NOUNCRYPT`. + +* строки, реализующие сжатие _bzip2_, в блоках условной компиляции `HAVE_BZIP2`. + +Выполнить `patch -p1 < test.diff` +Будут удалены ставшие избыточными тесты, внесены изменения в исходные тексты с учётом перемещения файлов. diff --git a/test.diff b/test.diff new file mode 100644 --- /dev/null +++ b/test.diff @@ -0,0 +1,98 @@ +--- a/qztest/qztest.cpp 2019-09-12 12:50:50.956633046 +0300 ++++ b/qztest/qztest.cpp 2019-09-12 13:29:17.661408359 +0300 +@@ -25,10 +25,6 @@ + #include "qztest.h" + #include "testquazip.h" + #include "testquazipfile.h" +-#include "testquachecksum32.h" +-#include "testjlcompress.h" +-#include "testquazipdir.h" +-#include "testquagzipfile.h" + #include "testquaziodevice.h" + #include "testquazipnewinfo.h" + #include "testquazipfileinfo.h" +@@ -201,26 +197,10 @@ + err = qMax(err, QTest::qExec(&testQuaZipFile, app.arguments())); + } + { +- TestQuaChecksum32 testQuaChecksum32; +- err = qMax(err, QTest::qExec(&testQuaChecksum32, app.arguments())); +- } +- { +- TestJlCompress testJlCompress; +- err = qMax(err, QTest::qExec(&testJlCompress, app.arguments())); +- } +- { +- TestQuaZipDir testQuaZipDir; +- err = qMax(err, QTest::qExec(&testQuaZipDir, app.arguments())); +- } +- { + TestQuaZIODevice testQuaZIODevice; + err = qMax(err, QTest::qExec(&testQuaZIODevice, app.arguments())); + } + { +- TestQuaGzipFile testQuaGzipFile; +- err = qMax(err, QTest::qExec(&testQuaGzipFile, app.arguments())); +- } +- { + TestQuaZipNewInfo testQuaZipNewInfo; + err = qMax(err, QTest::qExec(&testQuaZipNewInfo, app.arguments())); + } +--- a/qztest/testquazip.cpp 2019-09-12 12:50:50.964633035 +0300 ++++ b/qztest/testquazip.cpp 2019-09-11 17:33:09.456429269 +0300 +@@ -40,7 +40,7 @@ + #include + + #include +-#include ++#include "JlCompress.h" + + void TestQuaZip::getFileList_data() + { +--- a/qztest/testquazipfile.cpp 2019-09-12 12:50:50.968633030 +0300 ++++ b/qztest/testquazipfile.cpp 2019-09-11 17:58:58.330810048 +0300 +@@ -26,7 +26,7 @@ + + #include "qztest.h" + +-#include ++#include "JlCompress.h" + #include + #include + +@@ -52,9 +52,6 @@ + QStringList() + << QString::fromUtf8("русское имя файла с пробелами.txt")) + << QByteArray("IBM866") << QByteArray() << false << -1; +- QTest::newRow("password") << "password.zip" << ( +- QStringList() << "test.txt") +- << QByteArray() << QByteArray("PassPass") << false << -1; + QTest::newRow("zip64") << "zip64.zip" << ( + QStringList() << "test64.txt") + << QByteArray() << QByteArray() << true << -1; +--- a/qztest/testjlcompress.cpp 2019-09-12 13:53:25.487271597 +0300 ++++ b/qztest/testjlcompress.cpp 2019-09-12 12:50:50.960633041 +0300 +@@ -31,7 +31,7 @@ + + #include + +-#include ++#include "JlCompress.h" + + #ifdef Q_OS_WIN + #include +--- a/qztest/JlCompress.h 2019-09-12 12:50:50.908633109 +0300 ++++ b/qztest/JlCompress.h 2019-09-12 13:49:44.951605835 +0300 +@@ -26,9 +26,9 @@ + see quazip/(un)zip.h files for details. Basically it's the zlib license. + */ + +-#include "quazip.h" +-#include "quazipfile.h" +-#include "quazipfileinfo.h" ++#include "quazip/quazip.h" ++#include "quazip/quazipfile.h" ++#include "quazip/quazipfileinfo.h" + #include + #include + #include diff --git a/zip.diff b/zip.diff new file mode 100644 --- /dev/null +++ b/zip.diff @@ -0,0 +1,591 @@ +--- a/quazip/zip.c 2019-09-12 14:17:24.629118214 +0300 ++++ b/quazip/zip.c 2019-09-12 14:19:04.885102347 +0300 +@@ -140,9 +140,6 @@ + typedef struct + { + z_stream stream; /* zLib stream structure for inflate */ +-#ifdef HAVE_BZIP2 +- bz_stream bstream; /* bzLib stream structure for bziped */ +-#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ +@@ -165,11 +162,6 @@ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +-#ifndef NOCRYPT +- unsigned long keys[3]; /* keys defining the pseudo-random sequence */ +- const z_crc_t FAR * pcrc_32_tab; +- int crypt_header_size; +-#endif + } curfile64_info; + + typedef struct +@@ -193,11 +185,6 @@ + } zip64_internal; + + +-#ifndef NOCRYPT +-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +-#include "minizip_crypt.h" +-#endif +- + local linkedlist_datablock_internal* allocate_new_datablock() + { + linkedlist_datablock_internal* ldi; +@@ -1086,6 +1073,7 @@ + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) + { ++ crcForCrypting = crcForCrypting; + zip64_internal* zi; + uInt size_filename; + uInt size_comment; +@@ -1093,21 +1081,14 @@ + int err = ZIP_OK; + uLong version_to_extract; + +-# ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +-# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +-#ifdef HAVE_BZIP2 +- if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) +- return ZIP_PARAMERROR; +-#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +-#endif + + zi = (zip64_internal*)file; + +@@ -1231,16 +1212,6 @@ + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, + extrafield_local, version_to_extract); + +-#ifdef HAVE_BZIP2 +- zi->ci.bstream.avail_in = (uInt)0; +- zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; +- zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; +- zi->ci.bstream.total_in_hi32 = 0; +- zi->ci.bstream.total_in_lo32 = 0; +- zi->ci.bstream.total_out_hi32 = 0; +- zi->ci.bstream.total_out_lo32 = 0; +-#endif +- + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; +@@ -1248,11 +1219,7 @@ + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +-#ifdef HAVE_BZIP2 +- if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +-#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +-#endif + { + if(zi->ci.method == Z_DEFLATED) + { +@@ -1268,41 +1235,8 @@ + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } +- else if(zi->ci.method == Z_BZIP2ED) +- { +-#ifdef HAVE_BZIP2 +- /* Init BZip stuff here */ +- zi->ci.bstream.bzalloc = 0; +- zi->ci.bstream.bzfree = 0; +- zi->ci.bstream.opaque = (voidpf)0; +- +- err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); +- if(err == BZ_OK) +- zi->ci.stream_initialised = Z_BZIP2ED; +-#endif +- } +- +- } +- +-# ifndef NOCRYPT +- zi->ci.crypt_header_size = 0; +- if ((err==Z_OK) && (password != NULL)) +- { +- unsigned char bufHead[RAND_HEAD_LEN]; +- unsigned int sizeHead; +- zi->ci.encrypt = 1; +- zi->ci.pcrc_32_tab = get_crc_table(); +- /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ +- if (crcForCrypting == 0) { +- crcForCrypting = (uLong)zi->ci.dosDate << 16; /* ATTANTION! Without this row, you don't unpack your password protected archive in other app. */ +- } +- sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); +- zi->ci.crypt_header_size = sizeHead; + +- if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) +- err = ZIP_ERRNO; + } +-# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; +@@ -1413,32 +1347,14 @@ + + if (zi->ci.encrypt != 0) + { +-#ifndef NOCRYPT +- uInt i; +- int t; +- for (i=0;ici.pos_in_buffered_data;i++) +- zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +-#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; +- +-#ifdef HAVE_BZIP2 +- if(zi->ci.method == Z_BZIP2ED) +- { +- zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; +- zi->ci.bstream.total_in_lo32 = 0; +- zi->ci.bstream.total_in_hi32 = 0; +- } +- else +-#endif +- { +- zi->ci.totalUncompressedData += zi->ci.stream.total_in; +- zi->ci.stream.total_in = 0; +- } ++ zi->ci.totalUncompressedData += zi->ci.stream.total_in; ++ zi->ci.stream.total_in = 0; + + + zi->ci.pos_in_buffered_data = 0; +@@ -1460,89 +1376,51 @@ + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +-#ifdef HAVE_BZIP2 +- if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) +- { +- zi->ci.bstream.next_in = (void*)buf; +- zi->ci.bstream.avail_in = len; +- err = BZ_RUN_OK; ++ zi->ci.stream.next_in = (Bytef*)buf; ++ zi->ci.stream.avail_in = len; + +- while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) +- { +- if (zi->ci.bstream.avail_out == 0) ++ while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) ++ { ++ if (zi->ci.stream.avail_out == 0) + { +- if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) +- err = ZIP_ERRNO; +- zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; +- zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; ++ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) ++ err = ZIP_ERRNO; ++ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; ++ zi->ci.stream.next_out = zi->ci.buffered_data; + } + + +- if(err != BZ_RUN_OK) +- break; ++ if(err != ZIP_OK) ++ break; + +- if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) ++ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { +- uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +-/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */ +- err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); +- +- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; ++ uInt uAvailOutBefore = zi->ci.stream.avail_out; ++ err=deflate(&zi->ci.stream, Z_NO_FLUSH); ++ zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; + } +- } +- +- if(err == BZ_RUN_OK) +- err = ZIP_OK; +- } +- else +-#endif +- { +- zi->ci.stream.next_in = (Bytef*)buf; +- zi->ci.stream.avail_in = len; +- +- while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) +- { +- if (zi->ci.stream.avail_out == 0) +- { +- if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) +- err = ZIP_ERRNO; +- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; +- zi->ci.stream.next_out = zi->ci.buffered_data; +- } +- +- +- if(err != ZIP_OK) +- break; +- +- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +- { +- uInt uAvailOutBefore = zi->ci.stream.avail_out; +- err=deflate(&zi->ci.stream, Z_NO_FLUSH); +- zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; +- } +- else +- { +- uInt copy_this,i; +- if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) +- copy_this = zi->ci.stream.avail_in; +- else +- copy_this = zi->ci.stream.avail_out; +- +- for (i = 0; i < copy_this; i++) +- *(((char*)zi->ci.stream.next_out)+i) = +- *(((const char*)zi->ci.stream.next_in)+i); +- { +- zi->ci.stream.avail_in -= copy_this; +- zi->ci.stream.avail_out-= copy_this; +- zi->ci.stream.next_in+= copy_this; +- zi->ci.stream.next_out+= copy_this; +- zi->ci.stream.total_in+= copy_this; +- zi->ci.stream.total_out+= copy_this; +- zi->ci.pos_in_buffered_data += copy_this; +- } +- } +- }/* while(...) */ +- } ++ else ++ { ++ uInt copy_this,i; ++ if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) ++ copy_this = zi->ci.stream.avail_in; ++ else ++ copy_this = zi->ci.stream.avail_out; ++ ++ for (i = 0; i < copy_this; i++) ++ *(((char*)zi->ci.stream.next_out)+i) = ++ *(((const char*)zi->ci.stream.next_in)+i); ++ { ++ zi->ci.stream.avail_in -= copy_this; ++ zi->ci.stream.avail_out-= copy_this; ++ zi->ci.stream.next_in+= copy_this; ++ zi->ci.stream.next_out+= copy_this; ++ zi->ci.stream.total_in+= copy_this; ++ zi->ci.stream.total_out+= copy_this; ++ zi->ci.pos_in_buffered_data += copy_this; ++ } ++ } ++ }/* while(...) */ + + return err; + } +@@ -1585,32 +1463,6 @@ + zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; + } + } +- else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +- { +-#ifdef HAVE_BZIP2 +- err = BZ_FINISH_OK; +- while (err==BZ_FINISH_OK) +- { +- uLong uTotalOutBefore; +- if (zi->ci.bstream.avail_out == 0) +- { +- if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) +- err = ZIP_ERRNO; +- zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; +- zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; +- } +- uTotalOutBefore = zi->ci.bstream.total_out_lo32; +- err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); +- if(err == BZ_STREAM_END) +- err = Z_STREAM_END; +- +- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); +- } +- +- if(err == BZ_FINISH_OK) +- err = ZIP_OK; +-#endif +- } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ +@@ -1645,10 +1497,6 @@ + } + compressed_size = zi->ci.totalCompressedData; + +-# ifndef NOCRYPT +- compressed_size += zi->ci.crypt_header_size; +-# endif +- + /* update Current Item crc and sizes, */ + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { +--- a/quazip/zip.h 2019-09-12 12:50:50.952633051 +0300 ++++ b/quazip/zip.h 2019-09-11 17:53:44.063138337 +0300 +@@ -50,8 +50,6 @@ + extern "C" { + #endif + +-//#define HAVE_BZIP2 +- + #ifndef _ZLIB_H + #include "zlib.h" + #endif +@@ -60,12 +58,6 @@ + #include "ioapi.h" + #endif + +-#ifdef HAVE_BZIP2 +-#include "bzlib.h" +-#endif +- +-#define Z_BZIP2ED 12 +- + #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +--- a/quazip/unzip.c 2019-09-12 12:50:50.952633051 +0300 ++++ b/quazip/unzip.c 2019-09-11 18:01:02.330680525 +0300 +@@ -140,10 +140,6 @@ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +-#ifdef HAVE_BZIP2 +- bz_stream bstream; /* bzLib stream structure for bziped */ +-#endif +- + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + +@@ -191,17 +187,9 @@ + int isZip64; + unsigned flags; + +-# ifndef NOUNCRYPT +- unsigned long keys[3]; /* keys defining the pseudo-random sequence */ +- const z_crc_t FAR * pcrc_32_tab; +-# endif + } unz64_s; + + +-#ifndef NOUNCRYPT +-#include "minizip_crypt.h" +-#endif +- + /* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. +@@ -1433,9 +1421,6 @@ + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +-/* #ifdef HAVE_BZIP2 */ +- (s->cur_file_info.compression_method!=Z_BZIP2ED) && +-/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + +@@ -1488,12 +1473,8 @@ + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +-# ifndef NOUNCRYPT +- char source[12]; +-# else + if (password != NULL) + return UNZ_PARAMERROR; +-# endif + + if (file==NULL) + return UNZ_PARAMERROR; +@@ -1540,9 +1521,6 @@ + } + + if ((s->cur_file_info.compression_method!=0) && +-/* #ifdef HAVE_BZIP2 */ +- (s->cur_file_info.compression_method!=Z_BZIP2ED) && +-/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; +@@ -1557,33 +1535,7 @@ + + pfile_in_zip_read_info->stream.total_out = 0; + +- if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) +- { +-#ifdef HAVE_BZIP2 +- pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; +- pfile_in_zip_read_info->bstream.bzfree = (free_func)0; +- pfile_in_zip_read_info->bstream.opaque = (voidpf)0; +- pfile_in_zip_read_info->bstream.state = (voidpf)0; +- +- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; +- pfile_in_zip_read_info->stream.zfree = (free_func)0; +- pfile_in_zip_read_info->stream.opaque = (voidpf)0; +- pfile_in_zip_read_info->stream.next_in = (voidpf)0; +- pfile_in_zip_read_info->stream.avail_in = 0; +- +- err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); +- if (err == Z_OK) +- pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; +- else +- { +- TRYFREE(pfile_in_zip_read_info); +- return err; +- } +-#else +- pfile_in_zip_read_info->raw=1; +-#endif +- } +- else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) ++ if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; +@@ -1623,29 +1575,6 @@ + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +-# ifndef NOUNCRYPT +- if (password != NULL) +- { +- int i; +- s->pcrc_32_tab = get_crc_table(); +- init_keys(password,s->keys,s->pcrc_32_tab); +- if (ZSEEK64(s->z_filefunc, s->filestream, +- s->pfile_in_zip_read->pos_in_zipfile + +- s->pfile_in_zip_read->byte_before_the_zipfile, +- SEEK_SET)!=0) +- return UNZ_INTERNALERROR; +- if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) +- return UNZ_INTERNALERROR; +- +- for (i = 0; i<12; i++) +- zdecode(s->keys,s->pcrc_32_tab,source[i]); +- +- s->pfile_in_zip_read->pos_in_zipfile+=12; +- s->encrypted=1; +- } +-# endif +- +- + return UNZ_OK; + } + +@@ -1751,18 +1680,6 @@ + return UNZ_ERRNO; + + +-# ifndef NOUNCRYPT +- if(s->encrypted) +- { +- uInt i; +- for(i=0;iread_buffer[i] = +- zdecode(s->keys,s->pcrc_32_tab, +- pfile_in_zip_read_info->read_buffer[i]); +- } +-# endif +- +- + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; +@@ -1803,49 +1720,6 @@ + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } +- else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) +- { +-#ifdef HAVE_BZIP2 +- uLong uTotalOutBefore,uTotalOutAfter; +- const Bytef *bufBefore; +- uLong uOutThis; +- +- pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; +- pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; +- pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; +- pfile_in_zip_read_info->bstream.total_in_hi32 = 0; +- pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; +- pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; +- pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; +- pfile_in_zip_read_info->bstream.total_out_hi32 = 0; +- +- uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; +- bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; +- +- err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); +- +- uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; +- uOutThis = uTotalOutAfter-uTotalOutBefore; +- +- pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; +- +- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); +- pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; +- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); +- +- pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; +- pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; +- pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; +- pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; +- pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; +- pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; +- +- if (err==BZ_STREAM_END) +- return (iRead==0) ? UNZ_EOF : iRead; +- if (err!=BZ_OK) +- break; +-#endif +- } /* end Z_BZIP2ED */ + else + { + uInt uAvailOutBefore,uAvailOutAfter; +@@ -2031,10 +1905,6 @@ + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +-#ifdef HAVE_BZIP2 +- else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) +- BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +-#endif + + + pfile_in_zip_read_info->stream_initialised = 0; +--- a/quazip/unzip.h 2019-09-12 12:50:50.952633051 +0300 ++++ b/quazip/unzip.h 2019-09-11 18:01:04.066678712 +0300 +@@ -60,12 +60,6 @@ + #include "ioapi.h" + #endif + +-#ifdef HAVE_BZIP2 +-#include "bzlib.h" +-#endif +- +-#define Z_BZIP2ED 12 +- + #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */