Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 89ca2e569932992934ff6d296993ab9a341744c1 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:30:32 +0200
- Subject: [PATCH 01/14] Modulus of negative dividends is undefined or negative
- ... depending on who you ask. Since it is possible for applicationPid to
- return negative values this means we would introduce garbage ['()*+,-./]
- in the generated filenames.
- Reviewed-by: Denis Dzyubenko
- ---
- src/corelib/io/qtemporaryfile.cpp | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 0855d93..5bc07cb 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -118,7 +118,7 @@ static int createFileFromTemplate(char *const path,
- char *rIter = placeholderEnd;
- #if defined(QT_BUILD_CORE_LIB)
- - qint64 pid = QCoreApplication::applicationPid();
- + quint64 pid = quint64(QCoreApplication::applicationPid());
- do {
- *--rIter = (pid % 10) + '0';
- pid /= 10;
- --
- 1.7.5.2
- From e96177cf94dad186a0fdc683338f10048617a9ee Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:32:08 +0200
- Subject: [PATCH 02/14] Changed if/if/else/if/eleven chain to switch
- Inlined isdigit in switch statement. Removed unused #includes.
- Documented unreachable segment with code (Q_ASSERT).
- Reviewed-by: Denis Dzyubenko
- ---
- src/corelib/io/qtemporaryfile.cpp | 37 ++++++++++++++++++++++---------------
- 1 files changed, 22 insertions(+), 15 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 5bc07cb..9753332 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -53,10 +53,6 @@
- # include <errno.h>
- #endif
- -#include <stdlib.h>
- -#include <time.h>
- -#include <ctype.h>
- -
- #if defined(Q_OS_UNIX)
- # include "private/qcore_unix_p.h" // overrides QT_OPEN
- #endif
- @@ -153,23 +149,34 @@ static int createFileFromTemplate(char *const path,
- for (char *iter = placeholderStart;;) {
- // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z'
- // String progression: "ZZaiC" => "aabiC"
- - if (*iter == 'Z') {
- - *iter++ = 'a';
- - if (iter == placeholderEnd)
- - return -1;
- - } else {
- - if (isdigit(*iter))
- + switch (*iter) {
- + case 'Z':
- + // Rollover, advance next character
- *iter = 'a';
- - else if (*iter == 'z') /* inc from z to A */
- + if (++iter == placeholderEnd)
- + return -1;
- +
- + continue;
- +
- + case '0': case '1': case '2': case '3': case '4':
- + case '5': case '6': case '7': case '8': case '9':
- + *iter = 'a';
- + break;
- +
- + case 'z':
- + // increment 'z' to 'A'
- *iter = 'A';
- - else {
- + break;
- +
- + default:
- ++*iter;
- - }
- - break;
- + break;
- }
- + break;
- }
- }
- - /*NOTREACHED*/
- +
- + Q_ASSERT(false);
- }
- //************* QTemporaryFileEngine
- --
- 1.7.5.2
- From 5f87b94a0d58eba01401d17c97c38b13a739a2b2 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:32:25 +0200
- Subject: [PATCH 03/14] Don't convert template's path separators again
- ---
- src/corelib/io/qtemporaryfile.cpp | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 9753332..aae3eb6 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -330,7 +330,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- return true;
- }
- - d->fileEntry = QFileSystemEntry(template_);
- + d->fileEntry = QFileSystemEntry(template_, QFileSystemEntry::FromInternalPath());
- return false;
- #endif
- }
- --
- 1.7.5.2
- From f11956ba7806e648b461ce74ac2e332300ef1338 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:32:51 +0200
- Subject: [PATCH 04/14] Use fromLocal8Bit for reversing toLocal8Bit
- path is converted to 8-bit encoding using toLocal8Bit in
- QTemporaryFileEngine::open. The reverse operation should be used here.
- ---
- src/corelib/io/qtemporaryfile.cpp | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index aae3eb6..d457601 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -141,7 +141,7 @@ static int createFileFromTemplate(char *const path,
- return -1;
- }
- #else
- - if (!QFileInfo(QLatin1String(path)).exists())
- + if (!QFileInfo(QString::fromLocal8Bit(path)).exists())
- return 1;
- #endif
- --
- 1.7.5.2
- From 4403413edc7dcd2cb7c238efb3ea7d7797cc386f Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:35:55 +0200
- Subject: [PATCH 05/14] Encapsulate pointer manipulations to
- createFileTemplate function
- , where we actually control how we use the pointers. Reduce some code
- duplication in #ifdefs.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 33 ++++++++++++++++++---------------
- 1 files changed, 18 insertions(+), 15 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index d457601..9228f94 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -96,18 +96,22 @@ QT_BEGIN_NAMESPACE
- \internal
- Generates a unique file path and returns a native handle to the open file.
- - \a path is used as a template when generating unique paths,
- - \a placeholderStart and \a placeholderEnd delimit the sub-string that will
- - be randomized.
- + \a path is used as a template when generating unique paths, \a pos
- + identifies the position of the first character that will be replaced in the
- + template and \a length the number of characters that may be substituted.
- Returns an open handle to the newly created file if successful, an invalid
- handle otherwise. In both cases, the string in \a path will be changed and
- contain the generated path name.
- */
- -static int createFileFromTemplate(char *const path,
- - char *const placeholderStart, char *const placeholderEnd)
- +static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- {
- - Q_ASSERT(placeholderEnd > placeholderStart);
- + Q_ASSERT(length != 0);
- + Q_ASSERT(pos < size_t(path.length()));
- + Q_ASSERT(length < size_t(path.length()) - pos);
- +
- + char *const placeholderStart = path.data() + pos;
- + char *const placeholderEnd = placeholderStart + length;
- // Initialize placeholder with random chars + PID.
- {
- @@ -134,14 +138,16 @@ static int createFileFromTemplate(char *const path,
- // Atomically create file and obtain handle
- #ifndef Q_OS_WIN
- {
- - int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
- + int fd = QT_OPEN(path.constData(),
- + QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
- + 0600);
- if (fd != -1)
- return fd;
- if (errno != EEXIST)
- return -1;
- }
- #else
- - if (!QFileInfo(QString::fromLocal8Bit(path)).exists())
- + if (!QFileInfo(QString::fromLocal8Bit(path.constData(), path.length())).exists())
- return 1;
- #endif
- @@ -295,10 +301,9 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- else
- filename.insert(phPos + phLength, suffix.toLocal8Bit());
- - char *path = filename.data();
- + int fd = createFileFromTemplate(filename, phPos, phLength);
- #ifndef Q_OS_WIN
- - int fd = createFileFromTemplate(path, path + phPos, path + phPos + phLength);
- if (fd != -1) {
- // First open the fd as an external file descriptor to
- // initialize the engine properly.
- @@ -308,7 +313,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- d->closeFileHandle = true;
- // Restore the file names (open() resets them).
- - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(path, filename.length())); //note that filename is NOT a native path
- + d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length())); //note that filename is NOT a native path
- filePathIsTemplate = false;
- return true;
- }
- @@ -318,13 +323,11 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- return false;
- #else
- - if (createFileFromTemplate(path, path + phPos, path + phPos + phLength) == -1) {
- + if (fd == -1)
- return false;
- - }
- QString template_ = d->fileEntry.filePath();
- - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(path, filename.length()));
- -
- + d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
- if (QFSFileEngine::open(openMode)) {
- filePathIsTemplate = false;
- return true;
- --
- 1.7.5.2
- From 8fc58dbb80f7d9d1a3782c90a2cda4efa5787ff0 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:57:19 +0200
- Subject: [PATCH 06/14] Use QStringBuilder when copying template for
- modification
- This avoids modifying the original string in the case where a
- placeholder marker is not found. By marking the variable const we
- further avoid checks on the reference count and detaches, also allowing
- us to safely reuse it later in the function.
- The new approach also fixes an issue where suffix wasn't empty, but the
- toLocal8Bit conversion would be. This resulted in a buffer overflow
- inside createFileFromTemplate.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 62 ++++++++++++++++++++++++++++---------
- 1 files changed, 47 insertions(+), 15 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 9228f94..1d3f7ca 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -45,6 +45,7 @@
- #include "qplatformdefs.h"
- #include "qabstractfileengine.h"
- +#include "qstringbuilder.h"
- #include "private/qfile_p.h"
- #include "private/qabstractfileengine_p.h"
- #include "private/qfsfileengine_p.h"
- @@ -63,6 +64,38 @@
- QT_BEGIN_NAMESPACE
- +struct Placeholder
- +{
- + Placeholder(int size)
- + : size_(size)
- + {
- + }
- +
- + int size() const
- + {
- + return size_;
- + }
- +
- +private:
- + int size_;
- +};
- +
- +template <>
- +struct QConcatenable<Placeholder>
- +{
- + typedef Placeholder type;
- + typedef QByteArray ConvertTo;
- + enum { ExactSize = true };
- + static int size(const Placeholder &p) { return p.size(); }
- +
- + template <class CharT>
- + static inline void appendTo(const Placeholder &p, CharT *&out)
- + {
- + // Uninitialized
- + out += p.size();
- + }
- +};
- +
- /*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- @@ -261,7 +294,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (!filePathIsTemplate)
- return QFSFileEngine::open(openMode);
- - QString qfilename = d->fileEntry.filePath();
- + const QString qfilename = d->fileEntry.filePath();
- // Find placeholder string.
- uint phPos = qfilename.length();
- @@ -284,22 +317,22 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- phLength = 0;
- }
- - QStringRef prefix, suffix;
- + QByteArray filename;
- +
- if (phLength < 6) {
- - qfilename += QLatin1Char('.');
- - prefix = QStringRef(&qfilename);
- + filename = qfilename.toLocal8Bit();
- +
- + phPos = filename.length() + 1; // Account for added dot in prefix
- phLength = 6;
- + filename = filename % '.' % Placeholder(phLength);
- } else {
- - prefix = qfilename.leftRef(phPos);
- - suffix = qfilename.midRef(phPos + phLength);
- - }
- + QByteArray prefix, suffix;
- + prefix = qfilename.leftRef(phPos).toLocal8Bit();
- + suffix = qfilename.midRef(phPos + phLength).toLocal8Bit();
- - QByteArray filename = prefix.toLocal8Bit();
- - phPos = filename.length();
- - if (suffix.isEmpty())
- - filename.resize(phPos + phLength);
- - else
- - filename.insert(phPos + phLength, suffix.toLocal8Bit());
- + phPos = prefix.length();
- + filename = prefix % Placeholder(phLength) % suffix;
- + }
- int fd = createFileFromTemplate(filename, phPos, phLength);
- @@ -326,14 +359,13 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (fd == -1)
- return false;
- - QString template_ = d->fileEntry.filePath();
- d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
- if (QFSFileEngine::open(openMode)) {
- filePathIsTemplate = false;
- return true;
- }
- - d->fileEntry = QFileSystemEntry(template_, QFileSystemEntry::FromInternalPath());
- + d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
- return false;
- #endif
- }
- --
- 1.7.5.2
- From 7cabe00f8b189dc592d6df0975e6952012f29674 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:39:53 +0200
- Subject: [PATCH 07/14] Make Symbian follow Windows code in temporary path
- generation
- On the one hand, we stop using OpenC here. On the other, we no longer
- use an atomic create and obtain file handle API -- just as we don't on
- Windows yet.
- This is a stepping stone to removing back and forth conversions of path
- names when generating unique names and also towards the use of native
- APIs for creating and obtaining a file handle atomically.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 13 +++++--------
- 1 files changed, 5 insertions(+), 8 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 1d3f7ca..b079d3e 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -50,12 +50,9 @@
- #include "private/qabstractfileengine_p.h"
- #include "private/qfsfileengine_p.h"
- -#if !defined(Q_OS_WINCE)
- -# include <errno.h>
- -#endif
- -
- -#if defined(Q_OS_UNIX)
- -# include "private/qcore_unix_p.h" // overrides QT_OPEN
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- +#include "private/qcore_unix_p.h" // overrides QT_OPEN
- +#include <errno.h>
- #endif
- #if defined(QT_BUILD_CORE_LIB)
- @@ -169,7 +166,7 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- for (;;) {
- // Atomically create file and obtain handle
- -#ifndef Q_OS_WIN
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- {
- int fd = QT_OPEN(path.constData(),
- QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
- @@ -336,7 +333,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- int fd = createFileFromTemplate(filename, phPos, phLength);
- -#ifndef Q_OS_WIN
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- if (fd != -1) {
- // First open the fd as an external file descriptor to
- // initialize the engine properly.
- --
- 1.7.5.2
- From 07183c34f31fea7f4d5cd12abee863239443eb0c Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:40:46 +0200
- Subject: [PATCH 08/14] Avoid spurious detaching in
- QDir::to/fromNativeSeparators
- The new code avoids non-const detaching operations until needed and uses
- a pointer into the "raw" QChar data from then on, thus skipping unneeded
- checks on the reference count for further detaching.
- These functions are used all the time by the file system classes so this
- small optimization won't hurt. In particular, it will help users who
- already use '/' when passing paths into Qt.
- Reviewed-by: Peter Hartmann
- ---
- src/corelib/io/qdir.cpp | 38 ++++++++++++++++++++++++++++----------
- 1 files changed, 28 insertions(+), 10 deletions(-)
- diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
- index b31cf69..f9196e0 100644
- --- a/src/corelib/io/qdir.cpp
- +++ b/src/corelib/io/qdir.cpp
- @@ -802,14 +802,23 @@ QString QDir::convertSeparators(const QString &pathName)
- */
- QString QDir::toNativeSeparators(const QString &pathName)
- {
- - QString n(pathName);
- #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN)
- - for (int i = 0; i < (int)n.length(); ++i) {
- - if (n[i] == QLatin1Char('/'))
- - n[i] = QLatin1Char('\\');
- + int i = pathName.indexOf(QLatin1Char('/'));
- + if (i != -1) {
- + QString n(pathName);
- +
- + QChar * const data = n.data();
- + data[i++] = QLatin1Char('\\');
- +
- + for (; i < n.length(); ++i) {
- + if (data[i] == QLatin1Char('/'))
- + data[i] = QLatin1Char('\\');
- + }
- +
- + return n;
- }
- #endif
- - return n;
- + return pathName;
- }
- /*!
- @@ -826,14 +835,23 @@ QString QDir::toNativeSeparators(const QString &pathName)
- */
- QString QDir::fromNativeSeparators(const QString &pathName)
- {
- - QString n(pathName);
- #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN)
- - for (int i = 0; i < (int)n.length(); ++i) {
- - if (n[i] == QLatin1Char('\\'))
- - n[i] = QLatin1Char('/');
- + int i = pathName.indexOf(QLatin1Char('\\'));
- + if (i != -1) {
- + QString n(pathName);
- +
- + QChar * const data = n.data();
- + data[i++] = QLatin1Char('/');
- +
- + for (; i < n.length(); ++i) {
- + if (data[i] == QLatin1Char('\\'))
- + data[i] = QLatin1Char('/');
- + }
- +
- + return n;
- }
- #endif
- - return n;
- + return pathName;
- }
- /*!
- --
- 1.7.5.2
- From a3e2fdb4382cf460c6fed2caca06a0a99b9d7f1b Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:58:08 +0200
- Subject: [PATCH 09/14] Minimize encoding conversions when generating unique
- file name
- With minor adjustments, createFileFromTemplate is made to work directly
- on (UTF-16) QString data, which is already in the native encoding for
- Windows and Symbian. This is possible because the function only fills
- out the placeholder sub-string, without touching adjacent characters.
- This eliminates unnecessary conversions on those platforms.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 69 +++++++++++++++++++++++++++++--------
- 1 files changed, 54 insertions(+), 15 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index b079d3e..e4c53aa 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -61,6 +61,33 @@
- QT_BEGIN_NAMESPACE
- +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- +typedef ushort Char;
- +
- +static inline Char Latin1Char(char ch)
- +{
- + return ushort(uchar(ch));
- +}
- +
- +template <>
- +struct QConcatenable<Char>
- +{
- + typedef Char type;
- + typedef QString ConvertTo;
- + enum { ExactSize = true };
- + static int size(const Char &) { return 1; }
- +
- + static inline void appendTo(const Char &u16, QChar *&out)
- + {
- + *out++ = QChar(u16);
- + }
- +};
- +
- +#else // POSIX
- +typedef char Char;
- +typedef char Latin1Char;
- +#endif
- +
- struct Placeholder
- {
- Placeholder(int size)
- @@ -134,23 +161,24 @@ struct QConcatenable<Placeholder>
- handle otherwise. In both cases, the string in \a path will be changed and
- contain the generated path name.
- */
- -static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- +static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
- + size_t pos, size_t length)
- {
- Q_ASSERT(length != 0);
- Q_ASSERT(pos < size_t(path.length()));
- Q_ASSERT(length < size_t(path.length()) - pos);
- - char *const placeholderStart = path.data() + pos;
- - char *const placeholderEnd = placeholderStart + length;
- + Char *const placeholderStart = (Char *)path.data() + pos;
- + Char *const placeholderEnd = placeholderStart + length;
- // Initialize placeholder with random chars + PID.
- {
- - char *rIter = placeholderEnd;
- + Char *rIter = placeholderEnd;
- #if defined(QT_BUILD_CORE_LIB)
- quint64 pid = quint64(QCoreApplication::applicationPid());
- do {
- - *--rIter = (pid % 10) + '0';
- + *--rIter = Latin1Char((pid % 10) + '0');
- pid /= 10;
- } while (rIter != placeholderStart && pid != 0);
- #endif
- @@ -158,9 +186,9 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- while (rIter != placeholderStart) {
- char ch = char((qrand() & 0xffff) % (26 + 26));
- if (ch < 26)
- - *--rIter = ch + 'A';
- + *--rIter = Latin1Char(ch + 'A');
- else
- - *--rIter = ch - 26 + 'a';
- + *--rIter = Latin1Char(ch - 26 + 'a');
- }
- }
- @@ -177,18 +205,18 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- return -1;
- }
- #else
- - if (!QFileInfo(QString::fromLocal8Bit(path.constData(), path.length())).exists())
- + if (!QFileInfo(path).exists())
- return 1;
- #endif
- /* tricky little algorwwithm for backward compatibility */
- - for (char *iter = placeholderStart;;) {
- + for (Char *iter = placeholderStart;;) {
- // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z'
- // String progression: "ZZaiC" => "aabiC"
- - switch (*iter) {
- + switch (char(*iter)) {
- case 'Z':
- // Rollover, advance next character
- - *iter = 'a';
- + *iter = Latin1Char('a');
- if (++iter == placeholderEnd)
- return -1;
- @@ -196,12 +224,12 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- - *iter = 'a';
- + *iter = Latin1Char('a');
- break;
- case 'z':
- // increment 'z' to 'A'
- - *iter = 'A';
- + *iter = Latin1Char('A');
- break;
- default:
- @@ -314,8 +342,9 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- phLength = 0;
- }
- - QByteArray filename;
- + QFileSystemEntry::NativePath filename;
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- if (phLength < 6) {
- filename = qfilename.toLocal8Bit();
- @@ -330,6 +359,16 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- phPos = prefix.length();
- filename = prefix % Placeholder(phLength) % suffix;
- }
- +#else
- + if (phLength < 6) {
- + phPos = qfilename.length() + 1; // Account for added dot in prefix
- + phLength = 6;
- + filename = qfilename % Latin1Char('.') % Placeholder(phLength);
- + } else
- + filename = qfilename;
- +
- + // No native separators, not a "native path"
- +#endif
- int fd = createFileFromTemplate(filename, phPos, phLength);
- @@ -356,7 +395,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (fd == -1)
- return false;
- - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
- + d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromInternalPath());
- if (QFSFileEngine::open(openMode)) {
- filePathIsTemplate = false;
- return true;
- --
- 1.7.5.2
- From 77111a1e945a16ca50c3c4ea60d7a45a8cc1a404 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:45:08 +0200
- Subject: [PATCH 10/14] Use native paths on Windows and Symbian
- On these platforms, we know the native encoding for file names and can
- make conversions ahead of time.
- There's a change in behaviour on Windows and Symbian: fileNames returned
- by QTemporaryFile on Windows and Symbian are always absolute after open
- has been called. This has to do with how
- QFileSystemEntry::nativeFilePath works on these platforms.
- Test was updated to reflect change in behaviour.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 21 +++++++++++---
- tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp | 31 ++++++++++++++--------
- 2 files changed, 36 insertions(+), 16 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index e4c53aa..c9d726b 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -319,7 +319,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (!filePathIsTemplate)
- return QFSFileEngine::open(openMode);
- - const QString qfilename = d->fileEntry.filePath();
- + const QString qfilename =
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- + // Since the native encoding is out of our control, we need to process
- + // the path as UTF-16 before doing any conversions
- + d->fileEntry.filePath();
- +#else
- + d->fileEntry.nativeFilePath();
- +#endif
- // Find placeholder string.
- uint phPos = qfilename.length();
- @@ -333,8 +340,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- continue;
- }
- - if (qfilename[phPos] == QLatin1Char('/')
- - || phLength >= 6) {
- + if (phLength >= 6
- + || qfilename[phPos] ==
- +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- + QLatin1Char('/')
- +#else
- + QLatin1Char('\\')
- +#endif
- + ) {
- ++phPos;
- break;
- }
- @@ -366,8 +379,6 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- filename = qfilename % Latin1Char('.') % Placeholder(phLength);
- } else
- filename = qfilename;
- -
- - // No native separators, not a "native path"
- #endif
- int fd = createFileFromTemplate(filename, phPos, phLength);
- diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- index 2edb93a..05fee95 100644
- --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
- @@ -201,11 +201,12 @@ void tst_QTemporaryFile::fileTemplate()
- QCOMPARE(file.open(), true);
- + QString fileName = QFileInfo(file).fileName();
- if (prefix.length())
- - QCOMPARE(file.fileName().left(prefix.length()), prefix);
- + QCOMPARE(fileName.left(prefix.length()), prefix);
- if (suffix.length())
- - QCOMPARE(file.fileName().right(suffix.length()), suffix);
- + QCOMPARE(fileName.right(suffix.length()), suffix);
- }
- @@ -701,20 +702,28 @@ void tst_QTemporaryFile::QTBUG_4796()
- << file5.fileName()
- << file6.fileName();
- - QVERIFY(file1.fileName().startsWith(fileTemplate1 + QLatin1Char('.')));
- - QVERIFY(file2.fileName().startsWith(fileTemplate2 + QLatin1Char('.')));
- - QVERIFY(file5.fileName().startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
- - QVERIFY(file6.fileName().startsWith("test-XXXXXX/" + prefix));
- + QDir currentDir;
- + QString fileName1 = currentDir.relativeFilePath(file1.fileName());
- + QString fileName2 = currentDir.relativeFilePath(file2.fileName());
- + QString fileName3 = currentDir.relativeFilePath(file3.fileName());
- + QString fileName4 = currentDir.relativeFilePath(file4.fileName());
- + QString fileName5 = currentDir.relativeFilePath(file5.fileName());
- + QString fileName6 = currentDir.relativeFilePath(file6.fileName());
- +
- + QVERIFY(fileName1.startsWith(fileTemplate1 + QLatin1Char('.')));
- + QVERIFY(fileName2.startsWith(fileTemplate2 + QLatin1Char('.')));
- + QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
- + QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
- if (!prefix.isEmpty()) {
- - QVERIFY(file3.fileName().startsWith(prefix));
- - QVERIFY(file4.fileName().startsWith(prefix));
- + QVERIFY(fileName3.startsWith(prefix));
- + QVERIFY(fileName4.startsWith(prefix));
- }
- if (!suffix.isEmpty()) {
- - QVERIFY(file3.fileName().endsWith(suffix));
- - QVERIFY(file4.fileName().endsWith(suffix));
- - QVERIFY(file6.fileName().endsWith(suffix));
- + QVERIFY(fileName3.endsWith(suffix));
- + QVERIFY(fileName4.endsWith(suffix));
- + QVERIFY(fileName6.endsWith(suffix));
- }
- }
- }
- --
- 1.7.5.2
- From b78dc17595591096e17265748247aa8463084cd3 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:47:01 +0200
- Subject: [PATCH 11/14] Cleanup #includes
- These are already required and included by qfsfileengine_p.h.
- ---
- src/corelib/io/qtemporaryfile.cpp | 2 --
- 1 files changed, 0 insertions(+), 2 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index c9d726b..ba9a2a7 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -44,10 +44,8 @@
- #ifndef QT_NO_TEMPORARYFILE
- #include "qplatformdefs.h"
- -#include "qabstractfileengine.h"
- #include "qstringbuilder.h"
- #include "private/qfile_p.h"
- -#include "private/qabstractfileengine_p.h"
- #include "private/qfsfileengine_p.h"
- #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- --
- 1.7.5.2
- From 708ea483f465264e80c7a2fcb7c00277cd57f762 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 11:00:51 +0200
- Subject: [PATCH 12/14] Atomic implementation of create file and obtain handle
- for Win/Symbian
- createFileFromTemplate now not only generates a unique name, but also
- acquires a file handle on all platforms. The function directly modifies
- the file engine's native handle, returns true on success.
- Errors, other than "file exists" are propagated up with resulting
- failure in opening the temporary file.
- Fixes a long standing security issue on Windows.
- This change otherwise unifies error handling and should give consistent
- behaviour across all platforms.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 130 ++++++++++++++++++++++++-------------
- 1 files changed, 86 insertions(+), 44 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index ba9a2a7..9f7cde2 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -47,6 +47,11 @@
- #include "qstringbuilder.h"
- #include "private/qfile_p.h"
- #include "private/qfsfileengine_p.h"
- +#include "private/qsystemerror_p.h"
- +
- +#if defined(Q_OS_SYMBIAN)
- +#include "private/qcore_symbian_p.h"
- +#endif
- #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- #include "private/qcore_unix_p.h" // overrides QT_OPEN
- @@ -81,9 +86,20 @@ struct QConcatenable<Char>
- }
- };
- +# ifdef Q_OS_WIN
- +typedef HANDLE NativeFileHandle;
- +# else // Q_OS_SYMBIAN
- +# ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
- +typedef RFile64 NativeFileHandle;
- +# else
- +typedef RFile NativeFileHandle;
- +# endif
- +# endif
- +
- #else // POSIX
- typedef char Char;
- typedef char Latin1Char;
- +typedef int NativeFileHandle;
- #endif
- struct Placeholder
- @@ -159,8 +175,9 @@ struct QConcatenable<Placeholder>
- handle otherwise. In both cases, the string in \a path will be changed and
- contain the generated path name.
- */
- -static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
- - size_t pos, size_t length)
- +static bool createFileFromTemplate(NativeFileHandle &file,
- + QFileSystemEntry::NativePath &path, size_t pos, size_t length,
- + QSystemError &error)
- {
- Q_ASSERT(length != 0);
- Q_ASSERT(pos < size_t(path.length()));
- @@ -190,21 +207,50 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
- }
- }
- +#ifdef Q_OS_SYMBIAN
- + RFs& fs = qt_s60GetRFs();
- +#endif
- +
- for (;;) {
- // Atomically create file and obtain handle
- -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- - {
- - int fd = QT_OPEN(path.constData(),
- - QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
- - 0600);
- - if (fd != -1)
- - return fd;
- - if (errno != EEXIST)
- - return -1;
- +#if defined(Q_OS_WIN)
- + file = CreateFile((const wchar_t *)path.constData(),
- + GENERIC_READ | GENERIC_WRITE,
- + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
- + FILE_ATTRIBUTE_NORMAL, NULL);
- +
- + if (file != INVALID_HANDLE_VALUE)
- + return true;
- +
- + DWORD err = GetLastError();
- + if (err != ERROR_FILE_EXISTS) {
- + error = QSystemError(err, QSystemError::NativeError);
- + return false;
- + }
- +#elif defined(Q_OS_SYMBIAN)
- + TInt err = file.Create(fs, qt_QString2TPtrC(path),
- + EFileRead | EFileWrite | EFileShareReadersOrWriters);
- +
- + if (err == KErrNone)
- + return true;
- +
- + if (err != KErrAlreadyExists) {
- + error = QSystemError(err, QSystemError::NativeError);
- + return false;
- + }
- +#else // POSIX
- + file = QT_OPEN(path.constData(),
- + QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
- + 0600);
- +
- + if (file != -1)
- + return true;
- +
- + int err = errno;
- + if (err != EEXIST) {
- + error = QSystemError(err, QSystemError::NativeError);
- + return false;
- }
- -#else
- - if (!QFileInfo(path).exists())
- - return 1;
- #endif
- /* tricky little algorwwithm for backward compatibility */
- @@ -215,8 +261,11 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
- case 'Z':
- // Rollover, advance next character
- *iter = Latin1Char('a');
- - if (++iter == placeholderEnd)
- - return -1;
- + if (++iter == placeholderEnd) {
- + // Out of alternatives. Return file exists error, previously set.
- + error = QSystemError(err, QSystemError::NativeError);
- + return false;
- + }
- continue;
- @@ -379,40 +428,33 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- filename = qfilename;
- #endif
- - int fd = createFileFromTemplate(filename, phPos, phLength);
- + QSystemError error;
- +#if defined(Q_OS_WIN)
- + NativeFileHandle &file = d->fileHandle;
- +#elif defined(Q_OS_SYMBIAN)
- + NativeFileHandle &file = d->symbianFile;
- +#else // POSIX
- + NativeFileHandle &file = d->fd;
- +#endif
- -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- - if (fd != -1) {
- - // First open the fd as an external file descriptor to
- - // initialize the engine properly.
- - if (QFSFileEngine::open(openMode, fd)) {
- + if (!createFileFromTemplate(file, filename, phPos, phLength, error)) {
- + setError(QFile::OpenError, error.toString());
- + return false;
- + }
- - // Allow the engine to close the handle even if it's "external".
- - d->closeFileHandle = true;
- + d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
- - // Restore the file names (open() resets them).
- - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length())); //note that filename is NOT a native path
- - filePathIsTemplate = false;
- - return true;
- - }
- +#if !defined(Q_OS_WIN)
- + d->closeFileHandle = true;
- +#endif
- - QT_CLOSE(fd);
- - }
- - setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- - return false;
- -#else
- - if (fd == -1)
- - return false;
- + filePathIsTemplate = false;
- - d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromInternalPath());
- - if (QFSFileEngine::open(openMode)) {
- - filePathIsTemplate = false;
- - return true;
- - }
- + d->openMode = openMode;
- + d->lastFlushFailed = false;
- + d->tried_stat = 0;
- - d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
- - return false;
- -#endif
- + return true;
- }
- bool QTemporaryFileEngine::remove()
- --
- 1.7.5.2
- From a52e6abc5cc254d4f5664ad9e94434f996bd26bf Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Fri, 5 Aug 2011 10:49:44 +0200
- Subject: [PATCH 13/14] Use "native paths" on POSIX platforms as well
- And don't rely solely on "local8Bit" conversions.
- QFile defines an API for overriding how encoding conversions are done
- for filenames. In generating unique names, QTemporaryFile ignored that
- API and hardcoded the use of local 8-bit, implicitly assuming that that
- was appropriate.
- With this change, we switch that assumption to one where user supplied
- encoding function keeps the byte value of 'X' and '/', also assuming
- that encoded 'X' takes up a single-byte (i.e., the byte sequence for
- "XXXXXX" remains unchanged).
- There was also, and there still is an assumption in name generation that
- byte values for ASCII alpha-numeric characters are valid in the "native"
- encoding.
- In practice this change is compatible with UTF-8, Latin-1 and other
- ISO/IEC 8859 encodings. At any rate, it's very likely that only UTF-8 is
- relevant here.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 30 +++---------------------------
- 1 files changed, 3 insertions(+), 27 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 9f7cde2..ac5deac 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -366,14 +366,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (!filePathIsTemplate)
- return QFSFileEngine::open(openMode);
- - const QString qfilename =
- -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- - // Since the native encoding is out of our control, we need to process
- - // the path as UTF-16 before doing any conversions
- - d->fileEntry.filePath();
- -#else
- - d->fileEntry.nativeFilePath();
- -#endif
- + const QFileSystemEntry::NativePath qfilename = d->fileEntry.nativeFilePath();
- // Find placeholder string.
- uint phPos = qfilename.length();
- @@ -382,7 +375,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- while (phPos != 0) {
- --phPos;
- - if (qfilename[phPos] == QLatin1Char('X')) {
- + if (qfilename[phPos] == Latin1Char('X')) {
- ++phLength;
- continue;
- }
- @@ -390,7 +383,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- if (phLength >= 6
- || qfilename[phPos] ==
- #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- - QLatin1Char('/')
- + '/'
- #else
- QLatin1Char('\\')
- #endif
- @@ -404,29 +397,12 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- QFileSystemEntry::NativePath filename;
- -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- - if (phLength < 6) {
- - filename = qfilename.toLocal8Bit();
- -
- - phPos = filename.length() + 1; // Account for added dot in prefix
- - phLength = 6;
- - filename = filename % '.' % Placeholder(phLength);
- - } else {
- - QByteArray prefix, suffix;
- - prefix = qfilename.leftRef(phPos).toLocal8Bit();
- - suffix = qfilename.midRef(phPos + phLength).toLocal8Bit();
- -
- - phPos = prefix.length();
- - filename = prefix % Placeholder(phLength) % suffix;
- - }
- -#else
- if (phLength < 6) {
- phPos = qfilename.length() + 1; // Account for added dot in prefix
- phLength = 6;
- filename = qfilename % Latin1Char('.') % Placeholder(phLength);
- } else
- filename = qfilename;
- -#endif
- QSystemError error;
- #if defined(Q_OS_WIN)
- --
- 1.7.5.2
- From bdc307bfa48f921c8dcc1b4ac510cfcda30f5f6c Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
- Date: Wed, 10 Aug 2011 18:11:25 +0200
- Subject: [PATCH 14/14] Fix warning when compiling with VS 2008
- warning C4308: negative integral constant converted to unsigned type
- ---
- src/corelib/tools/qbytearray.cpp | 4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
- diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
- index 767b713..a8edea4 100644
- --- a/src/corelib/tools/qbytearray.cpp
- +++ b/src/corelib/tools/qbytearray.cpp
- @@ -541,7 +541,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
- forever {
- ulong alloc = len;
- - if (len >= (1 << 31) - sizeof(QByteArray::Data)) {
- + if (len >= ulong(1 << 31) - sizeof(QByteArray::Data)) {
- //QByteArray does not support that huge size anyway.
- qWarning("qUncompress: Input data is corrupted");
- return QByteArray();
- @@ -561,7 +561,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
- switch (res) {
- case Z_OK:
- if (len != alloc) {
- - if (len >= (1 << 31) - sizeof(QByteArray::Data)) {
- + if (len >= ulong(1 << 31) - sizeof(QByteArray::Data)) {
- //QByteArray does not support that huge size anyway.
- qWarning("qUncompress: Input data is corrupted");
- return QByteArray();
- --
- 1.7.5.2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement