[QZip] Do not depend on platform definitions

Guarantee the values are exactly the same on all platforms
and avoid the macro redefinition(s) on a newer MinGW.

This also fixes a typo in #define S_IFLNK 020000 (<-- must be 0120000).

Change-Id: I4993d2a9bdb4b0871af110b89c137ce0ac0e953a
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This commit is contained in:
Konstantin Ritt 2015-04-07 18:53:41 +04:00
parent e1b7c55a43
commit 12b36aec2b

View File

@ -38,7 +38,6 @@
#include "qzipreader_p.h"
#include "qzipwriter_p.h"
#include <qdatetime.h>
#include <qplatformdefs.h>
#include <qendian.h>
#include <qdebug.h>
#include <qdir.h>
@ -49,44 +48,6 @@
// (actually, the only basic support of this version is implemented but it is enough for now)
#define ZIP_VERSION 20
#if defined(Q_OS_WIN)
# undef S_IFREG
# define S_IFREG 0100000
# ifndef S_IFDIR
# define S_IFDIR 0040000
# endif
# ifndef S_ISDIR
# define S_ISDIR(x) ((x) & S_IFDIR) > 0
# endif
# ifndef S_ISREG
# define S_ISREG(x) ((x) & 0170000) == S_IFREG
# endif
# define S_IFLNK 020000
# define S_ISLNK(x) ((x) & S_IFLNK) > 0
# ifndef S_IRUSR
# define S_IRUSR 0400
# endif
# ifndef S_IWUSR
# define S_IWUSR 0200
# endif
# ifndef S_IXUSR
# define S_IXUSR 0100
# endif
# define S_IRGRP 0040
# define S_IWGRP 0020
# define S_IXGRP 0010
# define S_IROTH 0004
# define S_IWOTH 0002
# define S_IXOTH 0001
#endif
#ifndef FILE_ATTRIBUTE_READONLY
# define FILE_ATTRIBUTE_READONLY 0x1
#endif
#ifndef FILE_ATTRIBUTE_DIRECTORY
# define FILE_ATTRIBUTE_DIRECTORY 0x10
#endif
#if 0
#define ZDEBUG qDebug
#else
@ -159,30 +120,6 @@ static void writeMSDosDate(uchar *dest, const QDateTime& dt)
}
}
static quint32 permissionsToMode(QFile::Permissions perms)
{
quint32 mode = 0;
if (perms & (QFile::ReadOwner | QFile::ReadUser))
mode |= S_IRUSR;
if (perms & (QFile::WriteOwner | QFile::WriteUser))
mode |= S_IWUSR;
if (perms & (QFile::ExeOwner | QFile::ExeUser))
mode |= S_IXUSR;
if (perms & QFile::ReadGroup)
mode |= S_IRGRP;
if (perms & QFile::WriteGroup)
mode |= S_IWGRP;
if (perms & QFile::ExeGroup)
mode |= S_IXGRP;
if (perms & QFile::ReadOther)
mode |= S_IROTH;
if (perms & QFile::WriteOther)
mode |= S_IWOTH;
if (perms & QFile::ExeOther)
mode |= S_IXOTH;
return mode;
}
static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
{
z_stream stream;
@ -247,30 +184,86 @@ static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sour
return err;
}
namespace WindowsFileAttributes {
enum {
Dir = 0x10, // FILE_ATTRIBUTE_DIRECTORY
File = 0x80, // FILE_ATTRIBUTE_NORMAL
TypeMask = 0x90,
ReadOnly = 0x01, // FILE_ATTRIBUTE_READONLY
PermMask = 0x01
};
}
namespace UnixFileAttributes {
enum {
Dir = 0040000, // __S_IFDIR
File = 0100000, // __S_IFREG
SymLink = 0120000, // __S_IFLNK
TypeMask = 0170000, // __S_IFMT
ReadUser = 0400, // __S_IRUSR
WriteUser = 0200, // __S_IWUSR
ExeUser = 0100, // __S_IXUSR
ReadGroup = 0040, // __S_IRGRP
WriteGroup = 0020, // __S_IWGRP
ExeGroup = 0010, // __S_IXGRP
ReadOther = 0004, // __S_IROTH
WriteOther = 0002, // __S_IWOTH
ExeOther = 0001, // __S_IXOTH
PermMask = 0777
};
}
static QFile::Permissions modeToPermissions(quint32 mode)
{
QFile::Permissions ret;
if (mode & S_IRUSR)
if (mode & UnixFileAttributes::ReadUser)
ret |= QFile::ReadOwner | QFile::ReadUser;
if (mode & S_IWUSR)
if (mode & UnixFileAttributes::WriteUser)
ret |= QFile::WriteOwner | QFile::WriteUser;
if (mode & S_IXUSR)
if (mode & UnixFileAttributes::ExeUser)
ret |= QFile::ExeOwner | QFile::ExeUser;
if (mode & S_IRGRP)
if (mode & UnixFileAttributes::ReadGroup)
ret |= QFile::ReadGroup;
if (mode & S_IWGRP)
if (mode & UnixFileAttributes::WriteGroup)
ret |= QFile::WriteGroup;
if (mode & S_IXGRP)
if (mode & UnixFileAttributes::ExeGroup)
ret |= QFile::ExeGroup;
if (mode & S_IROTH)
if (mode & UnixFileAttributes::ReadOther)
ret |= QFile::ReadOther;
if (mode & S_IWOTH)
if (mode & UnixFileAttributes::WriteOther)
ret |= QFile::WriteOther;
if (mode & S_IXOTH)
if (mode & UnixFileAttributes::ExeOther)
ret |= QFile::ExeOther;
return ret;
}
static quint32 permissionsToMode(QFile::Permissions perms)
{
quint32 mode = 0;
if (mode & (QFile::ReadOwner | QFile::ReadUser))
mode |= UnixFileAttributes::ReadUser;
if (mode & (QFile::WriteOwner | QFile::WriteUser))
mode |= UnixFileAttributes::WriteUser;
if (mode & (QFile::ExeOwner | QFile::ExeUser))
mode |= UnixFileAttributes::WriteUser;
if (perms & QFile::ReadGroup)
mode |= UnixFileAttributes::ReadGroup;
if (perms & QFile::WriteGroup)
mode |= UnixFileAttributes::WriteGroup;
if (perms & QFile::ExeGroup)
mode |= UnixFileAttributes::ExeGroup;
if (perms & QFile::ReadOther)
mode |= UnixFileAttributes::ReadOther;
if (perms & QFile::WriteOther)
mode |= UnixFileAttributes::WriteOther;
if (perms & QFile::ExeOther)
mode |= UnixFileAttributes::ExeOther;
return mode;
}
static QDateTime readMSDosDate(const uchar *src)
{
uint dosDate = readUInt(src);
@ -474,27 +467,38 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
switch (hostOS) {
case HostUnix:
mode = (mode >> 16) & 0xffff;
if (S_ISDIR(mode))
fileInfo.isDir = true;
else if (S_ISREG(mode))
fileInfo.isFile = true;
else if (S_ISLNK(mode))
switch (mode & UnixFileAttributes::TypeMask) {
case UnixFileAttributes::SymLink:
fileInfo.isSymLink = true;
break;
case UnixFileAttributes::Dir:
fileInfo.isDir = true;
break;
case UnixFileAttributes::File:
default: // ### just for the case; should we warn?
fileInfo.isFile = true;
break;
}
fileInfo.permissions = modeToPermissions(mode);
break;
case HostFAT:
case HostNTFS:
case HostHPFS:
case HostVFAT:
fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther;
if ((mode & FILE_ATTRIBUTE_READONLY) == 0)
fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
if ((mode & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
switch (mode & WindowsFileAttributes::TypeMask) {
case WindowsFileAttributes::Dir:
fileInfo.isDir = true;
fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther;
} else {
break;
case WindowsFileAttributes::File:
default:
fileInfo.isFile = true;
break;
}
fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther;
if ((mode & WindowsFileAttributes::ReadOnly) == 0)
fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
if (fileInfo.isDir)
fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther;
break;
default:
qWarning("QZip: Zip entry format at %d is not supported.", index);
@ -741,9 +745,18 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
//uchar external_file_attributes[4];
quint32 mode = permissionsToMode(permissions);
switch (type) {
case File: mode |= S_IFREG; break;
case Directory: mode |= S_IFDIR; break;
case Symlink: mode |= S_IFLNK; break;
case Symlink:
mode |= UnixFileAttributes::SymLink;
break;
case Directory:
mode |= UnixFileAttributes::Dir;
break;
case File:
mode |= UnixFileAttributes::File;
break;
default:
Q_UNREACHABLE();
break;
}
writeUInt(header.h.external_file_attributes, mode << 16);
writeUInt(header.h.offset_local_header, start_of_directory);