From fd61059d359f0bee1c37d6bf08bf4b83381658ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 16 Aug 2011 17:53:41 +0200 Subject: Fix QTemporaryFile regressions and new found issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this change, the file template is always processed in original QString format. Trying to generate native paths before adding a missing placeholder mask could change the meaning of templates, such as "." and "..", which are now tested to mean "..XXXXXX" and "...XXXXXX", respectively. After ensuring the template includes a placeholder mask, the path is converted to a native *absolute* file path and the mask is sought for again. On Windows, native paths were already absolute. On Symbian, we'd need at least a clean path, as "." and ",," are not natively understood. There is a requirement that the placeholder mask /XXXXXX+/ makes it through this conversion unaltered, which relaxes prior requirements on *nix platforms. On Windows and Symbian the conversion is under Qt's control and not user-configurable. Reviewed-by: Shane Kearns (cherry picked from commit 401722ef9e6fe79bd41f9d5f79668f5c4997c8e6) Conflicts: tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp Change-Id: Iac823881c865adf0931dc4f429c6c1ef135eeb56 Reviewed-by: João Abecasis --- src/corelib/io/qtemporaryfile.cpp | 84 +++++++++------------- .../io/qtemporaryfile/tst_qtemporaryfile.cpp | 2 + 2 files changed, 36 insertions(+), 50 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 82d67ab644..9247dd326d 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -44,10 +44,10 @@ #ifndef QT_NO_TEMPORARYFILE #include "qplatformdefs.h" -#include "qstringbuilder.h" #include "private/qfile_p.h" #include "private/qfsfileengine_p.h" #include "private/qsystemerror_p.h" +#include "private/qfilesystemengine_p.h" #if defined(Q_OS_SYMBIAN) #include "private/qcore_symbian_p.h" @@ -102,38 +102,6 @@ typedef char Latin1Char; typedef int NativeFileHandle; #endif -struct Placeholder -{ - Placeholder(int size) - : size_(size) - { - } - - int size() const - { - return size_; - } - -private: - int size_; -}; - -template <> -struct QConcatenable -{ - typedef Placeholder type; - typedef QByteArray ConvertTo; - enum { ExactSize = true }; - static int size(const Placeholder &p) { return p.size(); } - - template - 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. @@ -366,43 +334,59 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) if (!filePathIsTemplate) return QFSFileEngine::open(openMode); - const QFileSystemEntry::NativePath qfilename = d->fileEntry.nativeFilePath(); + QString qfilename = d->fileEntry.filePath(); - // Find placeholder string. + // Ensure there is a placeholder mask uint phPos = qfilename.length(); uint phLength = 0; while (phPos != 0) { --phPos; - if (qfilename[phPos] == Latin1Char('X')) { + if (qfilename[phPos] == QLatin1Char('X')) { ++phLength; continue; } if (phLength >= 6 - || qfilename[phPos] == -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) - '/' -#else - QLatin1Char('\\') -#endif - ) { + || qfilename[phPos] == QLatin1Char('/')) { ++phPos; break; } + // start over phLength = 0; } - QFileSystemEntry::NativePath filename; + if (phLength < 6) + qfilename.append(QLatin1String(".XXXXXX")); + + // "Nativify" :-) + QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName( + QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath())) + .nativeFilePath(); + + // Find mask in native path + phPos = filename.length(); + phLength = 0; + while (phPos != 0) { + --phPos; + + if (filename[phPos] == Latin1Char('X')) { + ++phLength; + continue; + } + + if (phLength >= 6) { + ++phPos; + break; + } + + // start over + phLength = 0; + } - if (phLength < 6) { - phPos = qfilename.length() + 1; // Account for added dot in prefix - phLength = 6; - filename = qfilename % Latin1Char('.') % Placeholder(phLength); - } else - filename = qfilename; + Q_ASSERT(phLength >= 6); QSystemError error; #if defined(Q_OS_WIN) diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 655c167c21..f2d2b0a1c8 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -647,6 +647,8 @@ void tst_QTemporaryFile::QTBUG_4796_data() QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8"); QTest::newRow("") << QString() << QString() << true; + QTest::newRow(".") << QString(".") << QString() << true; + QTest::newRow("..") << QString("..") << QString() << true; QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true; QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true; QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false; -- cgit v1.2.3