Skip to content

Commit

Permalink
Add support for specifying the OS code for new files
Browse files Browse the repository at this point in the history
New functions:
QuaZip::get/setOsCode() gets/sets OS code for new files
QuaZip::get/setDefaultOsCode() gets/sets global default
  • Loading branch information
stachenov committed May 7, 2019
1 parent 6f6c67d commit 982ea5e
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 6 deletions.
3 changes: 3 additions & 0 deletions NEWS.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
QuaZIP changes

* Current
* get/setOsCode(), get/setDefaultOsCode()

* 2018-06-13 0.7.6
* Fixed the Zip Slip vulnerability in JlCompress
* Renamed crypt.h to minizip_crypt.h to avoid conflicts
Expand Down
37 changes: 33 additions & 4 deletions quazip/quazip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ quazip/(un)zip.h files for details, basically it's zlib license.

#include "quazip.h"

#define QUAZIP_OS_UNIX 3u

/// All the internal stuff for the QuaZip class.
/**
\internal
Expand Down Expand Up @@ -72,6 +74,8 @@ class QuaZipPrivate {
bool autoClose;
/// The UTF-8 flag.
bool utf8;
/// The OS code.
uint osCode;
inline QTextCodec *getDefaultFileNameCodec()
{
if (defaultFileNameCodec == NULL) {
Expand All @@ -92,7 +96,8 @@ class QuaZipPrivate {
dataDescriptorWritingEnabled(true),
zip64(false),
autoClose(true),
utf8(false)
utf8(false),
osCode(defaultOsCode)
{
unzFile_f = NULL;
zipFile_f = NULL;
Expand All @@ -112,7 +117,8 @@ class QuaZipPrivate {
dataDescriptorWritingEnabled(true),
zip64(false),
autoClose(true),
utf8(false)
utf8(false),
osCode(defaultOsCode)
{
unzFile_f = NULL;
zipFile_f = NULL;
Expand All @@ -131,7 +137,8 @@ class QuaZipPrivate {
dataDescriptorWritingEnabled(true),
zip64(false),
autoClose(true),
utf8(false)
utf8(false),
osCode(defaultOsCode)
{
unzFile_f = NULL;
zipFile_f = NULL;
Expand All @@ -150,9 +157,11 @@ class QuaZipPrivate {
QHash<QString, unz64_file_pos> directoryCaseInsensitive;
unz64_file_pos lastMappedDirectoryEntry;
static QTextCodec *defaultFileNameCodec;
static uint defaultOsCode;
};

QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL;
uint QuaZipPrivate::defaultOsCode = QUAZIP_OS_UNIX;

void QuaZipPrivate::clearDirectoryMap()
{
Expand Down Expand Up @@ -595,7 +604,17 @@ void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)

void QuaZip::setFileNameCodec(const char *fileNameCodecName)
{
p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
}

void QuaZip::setOsCode(uint osCode)
{
p->osCode = osCode;
}

uint QuaZip::getOsCode() const
{
return p->osCode;
}

QTextCodec *QuaZip::getFileNameCodec()const
Expand Down Expand Up @@ -786,6 +805,16 @@ void QuaZip::setDefaultFileNameCodec(const char *codecName)
setDefaultFileNameCodec(QTextCodec::codecForName(codecName));
}

void QuaZip::setDefaultOsCode(uint osCode)
{
QuaZipPrivate::defaultOsCode = osCode;
}

uint QuaZip::getDefaultOsCode()
{
return QuaZipPrivate::defaultOsCode;
}

void QuaZip::setZip64Enabled(bool zip64)
{
p->zip64 = zip64;
Expand Down
20 changes: 19 additions & 1 deletion quazip/quazip.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ class QUAZIP_EXPORT QuaZip {
* Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName));
**/
void setFileNameCodec(const char *fileNameCodecName);
/// Sets the OS code (highest 8 bits of the “version made by” field) for new files.
/** There is currently no way to specify this for each file individually,
except by calling this function before opening each file. If this function is not called,
then the default OS code will be used. The default code is set by calling
setDefaultOsCode(). The default value at the moment of QuaZip creation will be used. */
void setOsCode(uint osCode);
/// Returns the OS code for new files.
uint getOsCode() const;
/// Returns the codec used to encode/decode comments inside archive.
QTextCodec* getFileNameCodec() const;
/// Sets the codec used to encode/decode comments inside archive.
Expand Down Expand Up @@ -585,9 +593,19 @@ class QUAZIP_EXPORT QuaZip {
/**
* @overload
* Equivalent to calling
* setDefltFileNameCodec(QTextCodec::codecForName(codecName)).
* setDefaultFileNameCodec(QTextCodec::codecForName(codecName)).
*/
static void setDefaultFileNameCodec(const char *codecName);
/// Sets default OS code.
/**
* @sa setOsCode()
*/
static void setDefaultOsCode(uint osCode);
/// Returns default OS code.
/**
* @sa getOsCode()
*/
static uint getDefaultOsCode();
};

#endif
6 changes: 5 additions & 1 deletion quazip/quazipfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ quazip/(un)zip.h files for details, basically it's zlib license.

using namespace std;

#define QUAZIP_VERSION_MADE_BY 0x1Eu

/// The implementation class for QuaZip.
/**
\internal
Expand Down Expand Up @@ -339,7 +341,7 @@ bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
else
zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
p->setZipError(zipOpenNewFileInZip3_64(p->zip->getZipFile(),
p->setZipError(zipOpenNewFileInZip4_64(p->zip->getZipFile(),
p->zip->isUtf8Enabled()
? info.name.toUtf8().constData()
: p->zip->getFileNameCodec()->fromUnicode(info.name).constData(),
Expand All @@ -352,6 +354,8 @@ bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
method, level, (int)raw,
windowBits, memLevel, strategy,
password, (uLong)crc,
(p->zip->getOsCode() << 8) | QUAZIP_VERSION_MADE_BY,
0,
p->zip->isZip64Enabled()));
if(p->zipError==UNZ_OK) {
p->writePos=0;
Expand Down
28 changes: 28 additions & 0 deletions qztest/testquazip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,34 @@ void TestQuaZip::setFileNameCodec()
curDir.remove(zipName);
}

void TestQuaZip::setOsCode_data()
{
QTest::addColumn<QString>("zipName");
QTest::addColumn<uint>("osCode");
QTest::newRow("unix") << "unix.zip" << 3u;
QTest::newRow("dos") << "dos.zip" << 0u;
}

void TestQuaZip::setOsCode()
{
QFETCH(QString, zipName);
QFETCH(uint, osCode);
QuaZip testZip(zipName);
testZip.setOsCode(osCode);
testZip.open(QuaZip::mdCreate);
QCOMPARE(testZip.getOsCode(), osCode);
QuaZipFile testZipFile(&testZip);
testZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("test.txt"));
testZipFile.close();
testZip.close();
QuaZip checkZip(zipName);
checkZip.open(QuaZip::mdUnzip);
checkZip.goToFirstFile();
QuaZipFileInfo64 fi;
QVERIFY(checkZip.getCurrentFileInfo(&fi));
QCOMPARE(fi.versionCreated >> 8, static_cast<quint16>(osCode));
}

void TestQuaZip::setDataDescriptorWritingEnabled()
{
QString zipName = "zip10.zip";
Expand Down
2 changes: 2 additions & 0 deletions qztest/testquazip.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ private slots:
void add();
void setFileNameCodec_data();
void setFileNameCodec();
void setOsCode_data();
void setOsCode();
void setDataDescriptorWritingEnabled();
void testQIODeviceAPI();
void setZipName();
Expand Down

0 comments on commit 982ea5e

Please sign in to comment.