[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 "qzipreader_p.h"
#include "qzipwriter_p.h" #include "qzipwriter_p.h"
#include <qdatetime.h> #include <qdatetime.h>
#include <qplatformdefs.h>
#include <qendian.h> #include <qendian.h>
#include <qdebug.h> #include <qdebug.h>
#include <qdir.h> #include <qdir.h>
@ -49,44 +48,6 @@
// (actually, the only basic support of this version is implemented but it is enough for now) // (actually, the only basic support of this version is implemented but it is enough for now)
#define ZIP_VERSION 20 #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 #if 0
#define ZDEBUG qDebug #define ZDEBUG qDebug
#else #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) static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
{ {
z_stream stream; z_stream stream;
@ -247,30 +184,86 @@ static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sour
return err; 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) static QFile::Permissions modeToPermissions(quint32 mode)
{ {
QFile::Permissions ret; QFile::Permissions ret;
if (mode & S_IRUSR) if (mode & UnixFileAttributes::ReadUser)
ret |= QFile::ReadOwner | QFile::ReadUser; ret |= QFile::ReadOwner | QFile::ReadUser;
if (mode & S_IWUSR) if (mode & UnixFileAttributes::WriteUser)
ret |= QFile::WriteOwner | QFile::WriteUser; ret |= QFile::WriteOwner | QFile::WriteUser;
if (mode & S_IXUSR) if (mode & UnixFileAttributes::ExeUser)
ret |= QFile::ExeOwner | QFile::ExeUser; ret |= QFile::ExeOwner | QFile::ExeUser;
if (mode & S_IRGRP) if (mode & UnixFileAttributes::ReadGroup)
ret |= QFile::ReadGroup; ret |= QFile::ReadGroup;
if (mode & S_IWGRP) if (mode & UnixFileAttributes::WriteGroup)
ret |= QFile::WriteGroup; ret |= QFile::WriteGroup;
if (mode & S_IXGRP) if (mode & UnixFileAttributes::ExeGroup)
ret |= QFile::ExeGroup; ret |= QFile::ExeGroup;
if (mode & S_IROTH) if (mode & UnixFileAttributes::ReadOther)
ret |= QFile::ReadOther; ret |= QFile::ReadOther;
if (mode & S_IWOTH) if (mode & UnixFileAttributes::WriteOther)
ret |= QFile::WriteOther; ret |= QFile::WriteOther;
if (mode & S_IXOTH) if (mode & UnixFileAttributes::ExeOther)
ret |= QFile::ExeOther; ret |= QFile::ExeOther;
return ret; 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) static QDateTime readMSDosDate(const uchar *src)
{ {
uint dosDate = readUInt(src); uint dosDate = readUInt(src);
@ -474,27 +467,38 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
switch (hostOS) { switch (hostOS) {
case HostUnix: case HostUnix:
mode = (mode >> 16) & 0xffff; mode = (mode >> 16) & 0xffff;
if (S_ISDIR(mode)) switch (mode & UnixFileAttributes::TypeMask) {
fileInfo.isDir = true; case UnixFileAttributes::SymLink:
else if (S_ISREG(mode))
fileInfo.isFile = true;
else if (S_ISLNK(mode))
fileInfo.isSymLink = true; 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); fileInfo.permissions = modeToPermissions(mode);
break; break;
case HostFAT: case HostFAT:
case HostNTFS: case HostNTFS:
case HostHPFS: case HostHPFS:
case HostVFAT: case HostVFAT:
fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther; switch (mode & WindowsFileAttributes::TypeMask) {
if ((mode & FILE_ATTRIBUTE_READONLY) == 0) case WindowsFileAttributes::Dir:
fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
if ((mode & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
fileInfo.isDir = true; fileInfo.isDir = true;
fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther; break;
} else { case WindowsFileAttributes::File:
default:
fileInfo.isFile = true; 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; break;
default: default:
qWarning("QZip: Zip entry format at %d is not supported.", index); 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]; //uchar external_file_attributes[4];
quint32 mode = permissionsToMode(permissions); quint32 mode = permissionsToMode(permissions);
switch (type) { switch (type) {
case File: mode |= S_IFREG; break; case Symlink:
case Directory: mode |= S_IFDIR; break; mode |= UnixFileAttributes::SymLink;
case Symlink: mode |= S_IFLNK; break; 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.external_file_attributes, mode << 16);
writeUInt(header.h.offset_local_header, start_of_directory); writeUInt(header.h.offset_local_header, start_of_directory);