Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 7e8b178278069309e9cc9ec686c7a90632c315f2 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/13] 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 c0dbb2ae2bb7590301b760746335784c516fee38 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/13] 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 df4db419fabd1099c846116cc7cf2d04feafd157 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/13] 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 763da9b1cbae094590fb8f66508e34c38378b633 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/13] 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 3958cfec41c775fc3ce3ef02ebba6f627fcbbe3e 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/13] 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 3be403715bca1edf2dbcc081e4990578ed1c1a0b 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/13] 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 9553b9b1e8fbadd9981835a7ac0f5f73d394ea64 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/13] 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 9b68b786487988ccd861a5abe1b2b50a4e0a5880 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/13] 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 d1f2e21a1b25f635f4aee22d731825dcbd8024b5 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/13] 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 | 50 +++++++++++++++++++++++++-----------
- 1 files changed, 35 insertions(+), 15 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index b079d3e..292ad50 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -61,6 +61,14 @@
- QT_BEGIN_NAMESPACE
- +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- +typedef ushort Char;
- +typedef QLatin1Char Latin1Char;
- +#else // POSIX
- +typedef char Char;
- +typedef char Latin1Char;
- +#endif
- +
- struct Placeholder
- {
- Placeholder(int size)
- @@ -134,23 +142,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 +167,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 +186,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 +205,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 +323,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 +340,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 % '.' % Placeholder(phLength);
- + } else
- + filename = qfilename;
- +
- + // No native separators, not a "native path"
- +#endif
- int fd = createFileFromTemplate(filename, phPos, phLength);
- @@ -356,7 +376,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 1794f7252c270504df9eda3d041d37f3f1382a86 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/13] 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.
- Reviewed-by: ?
- ---
- src/corelib/io/qtemporaryfile.cpp | 21 ++++++++++++++++-----
- 1 files changed, 16 insertions(+), 5 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 292ad50..6157a22 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -300,7 +300,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();
- @@ -314,8 +321,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;
- }
- @@ -347,8 +360,6 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- filename = qfilename % '.' % Placeholder(phLength);
- } else
- filename = qfilename;
- -
- - // No native separators, not a "native path"
- #endif
- int fd = createFileFromTemplate(filename, phPos, phLength);
- --
- 1.7.5.2
- From 870690cad1598de8c6029acc820ef203707d5811 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/13] 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 6157a22..828f4e5 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 39bdf994fc7773aab601d6906f4487bba9b4d6d8 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/13] 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 | 131 ++++++++++++++++++++++++-------------
- 1 files changed, 86 insertions(+), 45 deletions(-)
- diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
- index 828f4e5..687166c 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
- @@ -59,12 +64,22 @@
- QT_BEGIN_NAMESPACE
- -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- +#ifdef Q_OS_WIN
- typedef ushort Char;
- typedef QLatin1Char Latin1Char;
- +typedef HANDLE NativeFileHandle;
- +#elif defined(Q_OS_SYMBIAN)
- +typedef ushort Char;
- +typedef QLatin1Char Latin1Char;
- +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
- +typedef RFile64 NativeFileHandle;
- +#else
- +typedef RFile NativeFileHandle;
- +#endif
- #else // POSIX
- typedef char Char;
- typedef char Latin1Char;
- +typedef int NativeFileHandle;
- #endif
- struct Placeholder
- @@ -140,8 +155,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()));
- @@ -171,21 +187,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);
- +
- + 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 */
- @@ -196,8 +241,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;
- @@ -360,40 +408,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 9868ecd4ebdea88058201a51308fe61f1a4d8b31 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/13] 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 687166c..e565ba5 100644
- --- a/src/corelib/io/qtemporaryfile.cpp
- +++ b/src/corelib/io/qtemporaryfile.cpp
- @@ -346,14 +346,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();
- @@ -362,7 +355,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
- while (phPos != 0) {
- --phPos;
- - if (qfilename[phPos] == QLatin1Char('X')) {
- + if (qfilename[phPos] == Latin1Char('X')) {
- ++phLength;
- continue;
- }
- @@ -370,7 +363,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
- @@ -384,29 +377,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 % '.' % Placeholder(phLength);
- } else
- filename = qfilename;
- -#endif
- QSystemError error;
- #if defined(Q_OS_WIN)
- --
- 1.7.5.2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement