Fix QTemporaryFile regressions and new found issues
authorJoão Abecasis <joao.abecasis@nokia.com>
Tue, 16 Aug 2011 15:53:41 +0000 (17:53 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 21 Oct 2011 20:20:42 +0000 (22:20 +0200)
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 <joao.abecasis@nokia.com>
src/corelib/io/qtemporaryfile.cpp
tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp

index 82d67ab..9247dd3 100644 (file)
 #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<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.
@@ -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)
index 655c167..f2d2b0a 100644 (file)
@@ -647,6 +647,8 @@ void tst_QTemporaryFile::QTBUG_4796_data()
     QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
 
     QTest::newRow("<empty>") << 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;