Advertisement
Guest User

Untitled

a guest
Oct 3rd, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 47.24 KB | None | 0 0
  1. From c45ba032cba21c4e2fc46c2a0a2e8ee13467dd11 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  3. Date: Fri, 5 Aug 2011 10:39:53 +0200
  4. Subject: [PATCH 01/10] Make Symbian follow Windows code in temporary path
  5.  generation
  6.  
  7. On the one hand, we stop using OpenC here. On the other, we no longer
  8. use an atomic create and obtain file handle API -- just as we don't on
  9. Windows yet.
  10.  
  11. This is a stepping stone to removing back and forth conversions of path
  12. names when generating unique names and also towards the use of native
  13. APIs for creating and obtaining a file handle atomically.
  14.  
  15. Reviewed-by: Gareth Stockwell
  16. Reviewed-by: Shane Kearns
  17. ---
  18. src/corelib/io/qtemporaryfile.cpp |   13 +++++--------
  19.  1 files changed, 5 insertions(+), 8 deletions(-)
  20.  
  21. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  22. index 9228f94..497faad 100644
  23. --- a/src/corelib/io/qtemporaryfile.cpp
  24. +++ b/src/corelib/io/qtemporaryfile.cpp
  25. @@ -49,12 +49,9 @@
  26.  #include "private/qabstractfileengine_p.h"
  27.  #include "private/qfsfileengine_p.h"
  28.  
  29. -#if !defined(Q_OS_WINCE)
  30. -#  include <errno.h>
  31. -#endif
  32. -
  33. -#if defined(Q_OS_UNIX)
  34. -# include "private/qcore_unix_p.h"      // overrides QT_OPEN
  35. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  36. +#include "private/qcore_unix_p.h"       // overrides QT_OPEN
  37. +#include <errno.h>
  38.  #endif
  39.  
  40.  #if defined(QT_BUILD_CORE_LIB)
  41. @@ -136,7 +133,7 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
  42.  
  43.      for (;;) {
  44.          // Atomically create file and obtain handle
  45. -#ifndef Q_OS_WIN
  46. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  47.          {
  48.              int fd = QT_OPEN(path.constData(),
  49.                      QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
  50. @@ -303,7 +300,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  51.  
  52.      int fd = createFileFromTemplate(filename, phPos, phLength);
  53.  
  54. -#ifndef Q_OS_WIN
  55. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  56.      if (fd != -1) {
  57.          // First open the fd as an external file descriptor to
  58.          // initialize the engine properly.
  59. --
  60. 1.7.5.2
  61.  
  62.  
  63. From d15ecfafc54e0a054ab328e5ee2b2ccc858e3bca Mon Sep 17 00:00:00 2001
  64. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  65. Date: Fri, 5 Aug 2011 10:57:19 +0200
  66. Subject: [PATCH 02/10] Use QStringBuilder when copying template for
  67.  modification
  68.  
  69. This avoids modifying the original string in the case where a
  70. placeholder marker is not found. By marking the variable const we
  71. further avoid checks on the reference count and detaches, also allowing
  72. us to safely reuse it later in the function.
  73.  
  74. The new approach also fixes an issue where suffix wasn't empty, but the
  75. toLocal8Bit conversion would be. This resulted in a buffer overflow
  76. inside createFileFromTemplate.
  77.  
  78. Reviewed-by: Shane Kearns
  79. ---
  80. src/corelib/io/qtemporaryfile.cpp |   62 ++++++++++++++++++++++++++++---------
  81.  1 files changed, 47 insertions(+), 15 deletions(-)
  82.  
  83. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  84. index 497faad..b079d3e 100644
  85. --- a/src/corelib/io/qtemporaryfile.cpp
  86. +++ b/src/corelib/io/qtemporaryfile.cpp
  87. @@ -45,6 +45,7 @@
  88.  
  89.  #include "qplatformdefs.h"
  90.  #include "qabstractfileengine.h"
  91. +#include "qstringbuilder.h"
  92.  #include "private/qfile_p.h"
  93.  #include "private/qabstractfileengine_p.h"
  94.  #include "private/qfsfileengine_p.h"
  95. @@ -60,6 +61,38 @@
  96.  
  97.  QT_BEGIN_NAMESPACE
  98.  
  99. +struct Placeholder
  100. +{
  101. +    Placeholder(int size)
  102. +        : size_(size)
  103. +    {
  104. +    }
  105. +
  106. +    int size() const
  107. +    {
  108. +        return size_;
  109. +    }
  110. +
  111. +private:
  112. +    int size_;
  113. +};
  114. +
  115. +template <>
  116. +struct QConcatenable<Placeholder>
  117. +{
  118. +    typedef Placeholder type;
  119. +    typedef QByteArray ConvertTo;
  120. +    enum { ExactSize = true };
  121. +    static int size(const Placeholder &p) { return p.size(); }
  122. +
  123. +    template <class CharT>
  124. +    static inline void appendTo(const Placeholder &p, CharT *&out)
  125. +    {
  126. +        // Uninitialized
  127. +        out += p.size();
  128. +    }
  129. +};
  130. +
  131.  /*
  132.   * Copyright (c) 1987, 1993
  133.   * The Regents of the University of California.  All rights reserved.
  134. @@ -258,7 +291,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  135.      if (!filePathIsTemplate)
  136.          return QFSFileEngine::open(openMode);
  137.  
  138. -    QString qfilename = d->fileEntry.filePath();
  139. +    const QString qfilename = d->fileEntry.filePath();
  140.  
  141.      // Find placeholder string.
  142.      uint phPos = qfilename.length();
  143. @@ -281,22 +314,22 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  144.          phLength = 0;
  145.      }
  146.  
  147. -    QStringRef prefix, suffix;
  148. +    QByteArray filename;
  149. +
  150.      if (phLength < 6) {
  151. -        qfilename += QLatin1Char('.');
  152. -        prefix = QStringRef(&qfilename);
  153. +        filename = qfilename.toLocal8Bit();
  154. +
  155. +        phPos = filename.length() + 1; // Account for added dot in prefix
  156.          phLength = 6;
  157. +        filename = filename % '.' % Placeholder(phLength);
  158.      } else {
  159. -        prefix = qfilename.leftRef(phPos);
  160. -        suffix = qfilename.midRef(phPos + phLength);
  161. -    }
  162. +        QByteArray prefix, suffix;
  163. +        prefix = qfilename.leftRef(phPos).toLocal8Bit();
  164. +        suffix = qfilename.midRef(phPos + phLength).toLocal8Bit();
  165.  
  166. -    QByteArray filename = prefix.toLocal8Bit();
  167. -    phPos = filename.length();
  168. -    if (suffix.isEmpty())
  169. -        filename.resize(phPos + phLength);
  170. -    else
  171. -        filename.insert(phPos + phLength, suffix.toLocal8Bit());
  172. +        phPos = prefix.length();
  173. +        filename = prefix % Placeholder(phLength) % suffix;
  174. +    }
  175.  
  176.      int fd = createFileFromTemplate(filename, phPos, phLength);
  177.  
  178. @@ -323,14 +356,13 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  179.      if (fd == -1)
  180.          return false;
  181.  
  182. -    QString template_ = d->fileEntry.filePath();
  183.      d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
  184.      if (QFSFileEngine::open(openMode)) {
  185.          filePathIsTemplate = false;
  186.          return true;
  187.      }
  188.  
  189. -    d->fileEntry = QFileSystemEntry(template_, QFileSystemEntry::FromInternalPath());
  190. +    d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
  191.      return false;
  192.  #endif
  193.  }
  194. --
  195. 1.7.5.2
  196.  
  197.  
  198. From 2df98e039e8ffb4858df474e65ef9b250e5b8708 Mon Sep 17 00:00:00 2001
  199. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  200. Date: Fri, 5 Aug 2011 10:58:08 +0200
  201. Subject: [PATCH 03/10] Minimize encoding conversions when generating unique
  202.  file name
  203.  
  204. With minor adjustments, createFileFromTemplate is made to work directly
  205. on (UTF-16) QString data, which is already in the native encoding for
  206. Windows and Symbian. This is possible because the function only fills
  207. out the placeholder sub-string, without touching adjacent characters.
  208.  
  209. This eliminates unnecessary conversions on those platforms.
  210.  
  211. Reviewed-by: Gareth Stockwell
  212. Reviewed-by: Shane Kearns
  213. ---
  214. src/corelib/io/qtemporaryfile.cpp |   69 +++++++++++++++++++++++++++++--------
  215.  1 files changed, 54 insertions(+), 15 deletions(-)
  216.  
  217. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  218. index b079d3e..e4c53aa 100644
  219. --- a/src/corelib/io/qtemporaryfile.cpp
  220. +++ b/src/corelib/io/qtemporaryfile.cpp
  221. @@ -61,6 +61,33 @@
  222.  
  223.  QT_BEGIN_NAMESPACE
  224.  
  225. +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
  226. +typedef ushort Char;
  227. +
  228. +static inline Char Latin1Char(char ch)
  229. +{
  230. +    return ushort(uchar(ch));
  231. +}
  232. +
  233. +template <>
  234. +struct QConcatenable<Char>
  235. +{
  236. +    typedef Char type;
  237. +    typedef QString ConvertTo;
  238. +    enum { ExactSize = true };
  239. +    static int size(const Char &) { return 1; }
  240. +
  241. +    static inline void appendTo(const Char &u16, QChar *&out)
  242. +    {
  243. +        *out++ = QChar(u16);
  244. +    }
  245. +};
  246. +
  247. +#else // POSIX
  248. +typedef char Char;
  249. +typedef char Latin1Char;
  250. +#endif
  251. +
  252.  struct Placeholder
  253.  {
  254.      Placeholder(int size)
  255. @@ -134,23 +161,24 @@ struct QConcatenable<Placeholder>
  256.      handle otherwise. In both cases, the string in \a path will be changed and
  257.      contain the generated path name.
  258.  */
  259. -static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
  260. +static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
  261. +        size_t pos, size_t length)
  262.  {
  263.      Q_ASSERT(length != 0);
  264.      Q_ASSERT(pos < size_t(path.length()));
  265.      Q_ASSERT(length < size_t(path.length()) - pos);
  266.  
  267. -    char *const placeholderStart = path.data() + pos;
  268. -    char *const placeholderEnd = placeholderStart + length;
  269. +    Char *const placeholderStart = (Char *)path.data() + pos;
  270. +    Char *const placeholderEnd = placeholderStart + length;
  271.  
  272.      // Initialize placeholder with random chars + PID.
  273.      {
  274. -        char *rIter = placeholderEnd;
  275. +        Char *rIter = placeholderEnd;
  276.  
  277.  #if defined(QT_BUILD_CORE_LIB)
  278.          quint64 pid = quint64(QCoreApplication::applicationPid());
  279.          do {
  280. -            *--rIter = (pid % 10) + '0';
  281. +            *--rIter = Latin1Char((pid % 10) + '0');
  282.              pid /= 10;
  283.          } while (rIter != placeholderStart && pid != 0);
  284.  #endif
  285. @@ -158,9 +186,9 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
  286.          while (rIter != placeholderStart) {
  287.              char ch = char((qrand() & 0xffff) % (26 + 26));
  288.              if (ch < 26)
  289. -                *--rIter = ch + 'A';
  290. +                *--rIter = Latin1Char(ch + 'A');
  291.              else
  292. -                *--rIter = ch - 26 + 'a';
  293. +                *--rIter = Latin1Char(ch - 26 + 'a');
  294.          }
  295.      }
  296.  
  297. @@ -177,18 +205,18 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
  298.                  return -1;
  299.          }
  300.  #else
  301. -        if (!QFileInfo(QString::fromLocal8Bit(path.constData(), path.length())).exists())
  302. +        if (!QFileInfo(path).exists())
  303.              return 1;
  304.  #endif
  305.  
  306.          /* tricky little algorwwithm for backward compatibility */
  307. -        for (char *iter = placeholderStart;;) {
  308. +        for (Char *iter = placeholderStart;;) {
  309.              // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z'
  310.              // String progression: "ZZaiC" => "aabiC"
  311. -            switch (*iter) {
  312. +            switch (char(*iter)) {
  313.                  case 'Z':
  314.                      // Rollover, advance next character
  315. -                    *iter = 'a';
  316. +                    *iter = Latin1Char('a');
  317.                      if (++iter == placeholderEnd)
  318.                          return -1;
  319.  
  320. @@ -196,12 +224,12 @@ static int createFileFromTemplate(QByteArray &path, size_t pos, size_t length)
  321.  
  322.                  case '0': case '1': case '2': case '3': case '4':
  323.                  case '5': case '6': case '7': case '8': case '9':
  324. -                    *iter = 'a';
  325. +                    *iter = Latin1Char('a');
  326.                      break;
  327.  
  328.                  case 'z':
  329.                      // increment 'z' to 'A'
  330. -                    *iter = 'A';
  331. +                    *iter = Latin1Char('A');
  332.                      break;
  333.  
  334.                  default:
  335. @@ -314,8 +342,9 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  336.          phLength = 0;
  337.      }
  338.  
  339. -    QByteArray filename;
  340. +    QFileSystemEntry::NativePath filename;
  341.  
  342. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  343.      if (phLength < 6) {
  344.          filename = qfilename.toLocal8Bit();
  345.  
  346. @@ -330,6 +359,16 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  347.          phPos = prefix.length();
  348.          filename = prefix % Placeholder(phLength) % suffix;
  349.      }
  350. +#else
  351. +    if (phLength < 6) {
  352. +        phPos = qfilename.length() + 1; // Account for added dot in prefix
  353. +        phLength = 6;
  354. +        filename = qfilename % Latin1Char('.') % Placeholder(phLength);
  355. +    } else
  356. +        filename = qfilename;
  357. +
  358. +    // No native separators, not a "native path"
  359. +#endif
  360.  
  361.      int fd = createFileFromTemplate(filename, phPos, phLength);
  362.  
  363. @@ -356,7 +395,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  364.      if (fd == -1)
  365.          return false;
  366.  
  367. -    d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
  368. +    d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromInternalPath());
  369.      if (QFSFileEngine::open(openMode)) {
  370.          filePathIsTemplate = false;
  371.          return true;
  372. --
  373. 1.7.5.2
  374.  
  375.  
  376. From 7e73761bf45350a49b82db5f7f2514ff440be3c2 Mon Sep 17 00:00:00 2001
  377. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  378. Date: Fri, 5 Aug 2011 10:45:08 +0200
  379. Subject: [PATCH 04/10] Atomic implementation of create file and obtain handle
  380.  for Win/Symbian
  381.  
  382. Besides generating a unique name, createFileFromTemplate now also
  383. acquires a file handle on all platforms. The file engine's native handle
  384. is passed by reference and modified in place.
  385.  
  386. This fixes a long standing security issue on Windows.
  387.  
  388. On Windows and Symbian platforms we directly use the "native" file path
  389. when processing the template and generating the unique name. Since the
  390. native encoding is known, conversions at this point are safe.
  391.  
  392. Errors other than "file exists" are propagated to Q(Temporary)File,
  393. and result in a failure in open(). The changes also unify error handling
  394. and should give consistent behaviour across all platforms.
  395.  
  396. Worthy of note, there's a change in behaviour on Windows and Symbian:
  397. fileNames returned by QTemporaryFile on Windows and Symbian are always
  398. absolute after open has been called. This has to do with how
  399. QFileSystemEntry::nativeFilePath works on these platforms. (Test was
  400. updated to reflect change in behaviour.)
  401.  
  402. Reviewed-by: Gareth Stockwell
  403. Reviewed-by: Shane Kearns
  404. ---
  405. src/corelib/io/qtemporaryfile.cpp                |  151 +++++++++++++++-------
  406.  tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |   31 +++--
  407.  2 files changed, 122 insertions(+), 60 deletions(-)
  408.  
  409. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  410. index e4c53aa..cd6ab40 100644
  411. --- a/src/corelib/io/qtemporaryfile.cpp
  412. +++ b/src/corelib/io/qtemporaryfile.cpp
  413. @@ -49,6 +49,11 @@
  414.  #include "private/qfile_p.h"
  415.  #include "private/qabstractfileengine_p.h"
  416.  #include "private/qfsfileengine_p.h"
  417. +#include "private/qsystemerror_p.h"
  418. +
  419. +#if defined(Q_OS_SYMBIAN)
  420. +#include "private/qcore_symbian_p.h"
  421. +#endif
  422.  
  423.  #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  424.  #include "private/qcore_unix_p.h"       // overrides QT_OPEN
  425. @@ -83,9 +88,20 @@ struct QConcatenable<Char>
  426.      }
  427.  };
  428.  
  429. +# ifdef Q_OS_WIN
  430. +typedef HANDLE NativeFileHandle;
  431. +# else // Q_OS_SYMBIAN
  432. +#  ifdef  SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
  433. +typedef RFile64 NativeFileHandle;
  434. +#  else
  435. +typedef RFile NativeFileHandle;
  436. +#  endif
  437. +# endif
  438. +
  439.  #else // POSIX
  440.  typedef char Char;
  441.  typedef char Latin1Char;
  442. +typedef int NativeFileHandle;
  443.  #endif
  444.  
  445.  struct Placeholder
  446. @@ -161,8 +177,9 @@ struct QConcatenable<Placeholder>
  447.      handle otherwise. In both cases, the string in \a path will be changed and
  448.      contain the generated path name.
  449.  */
  450. -static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
  451. -        size_t pos, size_t length)
  452. +static bool createFileFromTemplate(NativeFileHandle &file,
  453. +        QFileSystemEntry::NativePath &path, size_t pos, size_t length,
  454. +        QSystemError &error)
  455.  {
  456.      Q_ASSERT(length != 0);
  457.      Q_ASSERT(pos < size_t(path.length()));
  458. @@ -192,21 +209,50 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
  459.          }
  460.      }
  461.  
  462. +#ifdef Q_OS_SYMBIAN
  463. +    RFs& fs = qt_s60GetRFs();
  464. +#endif
  465. +
  466.      for (;;) {
  467.          // Atomically create file and obtain handle
  468. -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  469. -        {
  470. -            int fd = QT_OPEN(path.constData(),
  471. -                    QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
  472. -                    0600);
  473. -            if (fd != -1)
  474. -                return fd;
  475. -            if (errno != EEXIST)
  476. -                return -1;
  477. +#if defined(Q_OS_WIN)
  478. +        file = CreateFile((const wchar_t *)path.constData(),
  479. +                GENERIC_READ | GENERIC_WRITE,
  480. +                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
  481. +                FILE_ATTRIBUTE_NORMAL, NULL);
  482. +
  483. +        if (file != INVALID_HANDLE_VALUE)
  484. +            return true;
  485. +
  486. +        DWORD err = GetLastError();
  487. +        if (err != ERROR_FILE_EXISTS) {
  488. +            error = QSystemError(err, QSystemError::NativeError);
  489. +            return false;
  490. +        }
  491. +#elif defined(Q_OS_SYMBIAN)
  492. +        TInt err = file.Create(fs, qt_QString2TPtrC(path),
  493. +                EFileRead | EFileWrite | EFileShareReadersOrWriters);
  494. +
  495. +        if (err == KErrNone)
  496. +            return true;
  497. +
  498. +        if (err != KErrAlreadyExists) {
  499. +            error = QSystemError(err, QSystemError::NativeError);
  500. +            return false;
  501. +        }
  502. +#else // POSIX
  503. +        file = QT_OPEN(path.constData(),
  504. +                QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
  505. +                0600);
  506. +
  507. +        if (file != -1)
  508. +            return true;
  509. +
  510. +        int err = errno;
  511. +        if (err != EEXIST) {
  512. +            error = QSystemError(err, QSystemError::NativeError);
  513. +            return false;
  514.          }
  515. -#else
  516. -        if (!QFileInfo(path).exists())
  517. -            return 1;
  518.  #endif
  519.  
  520.          /* tricky little algorwwithm for backward compatibility */
  521. @@ -217,8 +263,11 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
  522.                  case 'Z':
  523.                      // Rollover, advance next character
  524.                      *iter = Latin1Char('a');
  525. -                    if (++iter == placeholderEnd)
  526. -                        return -1;
  527. +                    if (++iter == placeholderEnd) {
  528. +                        // Out of alternatives. Return file exists error, previously set.
  529. +                        error = QSystemError(err, QSystemError::NativeError);
  530. +                        return false;
  531. +                    }
  532.  
  533.                      continue;
  534.  
  535. @@ -319,7 +368,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  536.      if (!filePathIsTemplate)
  537.          return QFSFileEngine::open(openMode);
  538.  
  539. -    const QString qfilename = d->fileEntry.filePath();
  540. +    const QString qfilename =
  541. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  542. +        // Since the native encoding is out of our control, we need to process
  543. +        // the path as UTF-16 before doing any conversions
  544. +        d->fileEntry.filePath();
  545. +#else
  546. +        d->fileEntry.nativeFilePath();
  547. +#endif
  548.  
  549.      // Find placeholder string.
  550.      uint phPos = qfilename.length();
  551. @@ -333,8 +389,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  552.              continue;
  553.          }
  554.  
  555. -        if (qfilename[phPos] == QLatin1Char('/')
  556. -                || phLength >= 6) {
  557. +        if (phLength >= 6
  558. +                || qfilename[phPos] ==
  559. +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  560. +                    QLatin1Char('/')
  561. +#else
  562. +                    QLatin1Char('\\')
  563. +#endif
  564. +                ) {
  565.              ++phPos;
  566.              break;
  567.          }
  568. @@ -366,44 +428,35 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  569.          filename = qfilename % Latin1Char('.') % Placeholder(phLength);
  570.      } else
  571.          filename = qfilename;
  572. -
  573. -    // No native separators, not a "native path"
  574.  #endif
  575.  
  576. -    int fd = createFileFromTemplate(filename, phPos, phLength);
  577. +    QSystemError error;
  578. +#if defined(Q_OS_WIN)
  579. +    NativeFileHandle &file = d->fileHandle;
  580. +#elif defined(Q_OS_SYMBIAN)
  581. +    NativeFileHandle &file = d->symbianFile;
  582. +#else // POSIX
  583. +    NativeFileHandle &file = d->fd;
  584. +#endif
  585.  
  586. -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  587. -    if (fd != -1) {
  588. -        // First open the fd as an external file descriptor to
  589. -        // initialize the engine properly.
  590. -        if (QFSFileEngine::open(openMode, fd)) {
  591. +    if (!createFileFromTemplate(file, filename, phPos, phLength, error)) {
  592. +        setError(QFile::OpenError, error.toString());
  593. +        return false;
  594. +    }
  595.  
  596. -            // Allow the engine to close the handle even if it's "external".
  597. -            d->closeFileHandle = true;
  598. +    d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
  599.  
  600. -            // Restore the file names (open() resets them).
  601. -            d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length())); //note that filename is NOT a native path
  602. -            filePathIsTemplate = false;
  603. -            return true;
  604. -        }
  605. +#if !defined(Q_OS_WIN)
  606. +    d->closeFileHandle = true;
  607. +#endif
  608.  
  609. -        QT_CLOSE(fd);
  610. -    }
  611. -    setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
  612. -    return false;
  613. -#else
  614. -    if (fd == -1)
  615. -        return false;
  616. +    filePathIsTemplate = false;
  617.  
  618. -    d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromInternalPath());
  619. -    if (QFSFileEngine::open(openMode)) {
  620. -        filePathIsTemplate = false;
  621. -        return true;
  622. -    }
  623. +    d->openMode = openMode;
  624. +    d->lastFlushFailed = false;
  625. +    d->tried_stat = 0;
  626.  
  627. -    d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
  628. -    return false;
  629. -#endif
  630. +    return true;
  631.  }
  632.  
  633.  bool QTemporaryFileEngine::remove()
  634. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  635. index 2edb93a..05fee95 100644
  636. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  637. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  638. @@ -201,11 +201,12 @@ void tst_QTemporaryFile::fileTemplate()
  639.  
  640.      QCOMPARE(file.open(), true);
  641.  
  642. +    QString fileName = QFileInfo(file).fileName();
  643.      if (prefix.length())
  644. -        QCOMPARE(file.fileName().left(prefix.length()), prefix);
  645. +        QCOMPARE(fileName.left(prefix.length()), prefix);
  646.  
  647.      if (suffix.length())
  648. -        QCOMPARE(file.fileName().right(suffix.length()), suffix);
  649. +        QCOMPARE(fileName.right(suffix.length()), suffix);
  650.  }
  651.  
  652.  
  653. @@ -701,20 +702,28 @@ void tst_QTemporaryFile::QTBUG_4796()
  654.                  << file5.fileName()
  655.                  << file6.fileName();
  656.  
  657. -            QVERIFY(file1.fileName().startsWith(fileTemplate1 + QLatin1Char('.')));
  658. -            QVERIFY(file2.fileName().startsWith(fileTemplate2 + QLatin1Char('.')));
  659. -            QVERIFY(file5.fileName().startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
  660. -            QVERIFY(file6.fileName().startsWith("test-XXXXXX/" + prefix));
  661. +            QDir currentDir;
  662. +            QString fileName1 = currentDir.relativeFilePath(file1.fileName());
  663. +            QString fileName2 = currentDir.relativeFilePath(file2.fileName());
  664. +            QString fileName3 = currentDir.relativeFilePath(file3.fileName());
  665. +            QString fileName4 = currentDir.relativeFilePath(file4.fileName());
  666. +            QString fileName5 = currentDir.relativeFilePath(file5.fileName());
  667. +            QString fileName6 = currentDir.relativeFilePath(file6.fileName());
  668. +
  669. +            QVERIFY(fileName1.startsWith(fileTemplate1 + QLatin1Char('.')));
  670. +            QVERIFY(fileName2.startsWith(fileTemplate2 + QLatin1Char('.')));
  671. +            QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
  672. +            QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
  673.  
  674.              if (!prefix.isEmpty()) {
  675. -                QVERIFY(file3.fileName().startsWith(prefix));
  676. -                QVERIFY(file4.fileName().startsWith(prefix));
  677. +                QVERIFY(fileName3.startsWith(prefix));
  678. +                QVERIFY(fileName4.startsWith(prefix));
  679.              }
  680.  
  681.              if (!suffix.isEmpty()) {
  682. -                QVERIFY(file3.fileName().endsWith(suffix));
  683. -                QVERIFY(file4.fileName().endsWith(suffix));
  684. -                QVERIFY(file6.fileName().endsWith(suffix));
  685. +                QVERIFY(fileName3.endsWith(suffix));
  686. +                QVERIFY(fileName4.endsWith(suffix));
  687. +                QVERIFY(fileName6.endsWith(suffix));
  688.              }
  689.          }
  690.      }
  691. --
  692. 1.7.5.2
  693.  
  694.  
  695. From c910587cc28943f3c24a4baa34e8f77352fbce76 Mon Sep 17 00:00:00 2001
  696. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  697. Date: Tue, 16 Aug 2011 16:02:47 +0200
  698. Subject: [PATCH 05/10] Add output on test failure
  699.  
  700. ---
  701. tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |   43 +++++++++++++---------
  702.  1 files changed, 26 insertions(+), 17 deletions(-)
  703.  
  704. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  705. index 05fee95..2db5c60 100644
  706. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  707. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  708. @@ -412,11 +412,11 @@ void tst_QTemporaryFile::rename()
  709.      {
  710.          QTemporaryFile file(dir.filePath("temporary-file.XXXXXX"));
  711.  
  712. -        QVERIFY(file.open());
  713. +        QVERIFY2(file.open(), qPrintable(file.errorString()));
  714.          tempname = file.fileName();
  715.          QVERIFY(dir.exists(tempname));
  716.  
  717. -        QVERIFY(file.rename("temporary-file.txt"));
  718. +        QVERIFY2(file.rename("temporary-file.txt"), qPrintable(file.errorString()));
  719.          QVERIFY(!dir.exists(tempname));
  720.          QVERIFY(dir.exists("temporary-file.txt"));
  721.          QCOMPARE(file.fileName(), QString("temporary-file.txt"));
  722. @@ -679,12 +679,21 @@ void tst_QTemporaryFile::QTBUG_4796()
  723.          QTemporaryFile file5("test-XXXXXX/" + fileTemplate1);
  724.          QTemporaryFile file6("test-XXXXXX/" + fileTemplate3);
  725.  
  726. -        QCOMPARE(file1.open(), openResult);
  727. -        QCOMPARE(file2.open(), openResult);
  728. -        QCOMPARE(file3.open(), openResult);
  729. -        QCOMPARE(file4.open(), openResult);
  730. -        QCOMPARE(file5.open(), openResult);
  731. -        QCOMPARE(file6.open(), openResult);
  732. +        if (openResult) {
  733. +            QVERIFY2(file1.open(), qPrintable(file1.errorString()));
  734. +            QVERIFY2(file2.open(), qPrintable(file2.errorString()));
  735. +            QVERIFY2(file3.open(), qPrintable(file3.errorString()));
  736. +            QVERIFY2(file4.open(), qPrintable(file4.errorString()));
  737. +            QVERIFY2(file5.open(), qPrintable(file5.errorString()));
  738. +            QVERIFY2(file6.open(), qPrintable(file6.errorString()));
  739. +        } else {
  740. +            QVERIFY(!file1.open());
  741. +            QVERIFY(!file2.open());
  742. +            QVERIFY(!file3.open());
  743. +            QVERIFY(!file4.open());
  744. +            QVERIFY(!file5.open());
  745. +            QVERIFY(!file6.open());
  746. +        }
  747.  
  748.          QCOMPARE(file1.exists(), openResult);
  749.          QCOMPARE(file2.exists(), openResult);
  750. @@ -710,20 +719,20 @@ void tst_QTemporaryFile::QTBUG_4796()
  751.              QString fileName5 = currentDir.relativeFilePath(file5.fileName());
  752.              QString fileName6 = currentDir.relativeFilePath(file6.fileName());
  753.  
  754. -            QVERIFY(fileName1.startsWith(fileTemplate1 + QLatin1Char('.')));
  755. -            QVERIFY(fileName2.startsWith(fileTemplate2 + QLatin1Char('.')));
  756. -            QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')));
  757. -            QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix));
  758. +            QVERIFY2(fileName1.startsWith(fileTemplate1 + QLatin1Char('.')), qPrintable(file1.fileName()));
  759. +            QVERIFY2(fileName2.startsWith(fileTemplate2 + QLatin1Char('.')), qPrintable(file2.fileName()));
  760. +            QVERIFY2(fileName5.startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.')), qPrintable(file5.fileName()));
  761. +            QVERIFY2(fileName6.startsWith("test-XXXXXX/" + prefix), qPrintable(file6.fileName()));
  762.  
  763.              if (!prefix.isEmpty()) {
  764. -                QVERIFY(fileName3.startsWith(prefix));
  765. -                QVERIFY(fileName4.startsWith(prefix));
  766. +                QVERIFY2(fileName3.startsWith(prefix), qPrintable(file3.fileName()));
  767. +                QVERIFY2(fileName4.startsWith(prefix), qPrintable(file4.fileName()));
  768.              }
  769.  
  770.              if (!suffix.isEmpty()) {
  771. -                QVERIFY(fileName3.endsWith(suffix));
  772. -                QVERIFY(fileName4.endsWith(suffix));
  773. -                QVERIFY(fileName6.endsWith(suffix));
  774. +                QVERIFY2(fileName3.endsWith(suffix), qPrintable(file3.fileName()));
  775. +                QVERIFY2(fileName4.endsWith(suffix), qPrintable(file4.fileName()));
  776. +                QVERIFY2(fileName6.endsWith(suffix), qPrintable(file6.fileName()));
  777.              }
  778.          }
  779.      }
  780. --
  781. 1.7.5.2
  782.  
  783.  
  784. From 1ee92ef77eeb4fd1a4b76faf4e1a1c3bd32dc6b4 Mon Sep 17 00:00:00 2001
  785. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  786. Date: Fri, 5 Aug 2011 10:47:01 +0200
  787. Subject: [PATCH 06/10] Cleanup #includes
  788.  
  789. These are already required and included by qfsfileengine_p.h.
  790. ---
  791. src/corelib/io/qtemporaryfile.cpp |    2 --
  792.  1 files changed, 0 insertions(+), 2 deletions(-)
  793.  
  794. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  795. index cd6ab40..9f7cde2 100644
  796. --- a/src/corelib/io/qtemporaryfile.cpp
  797. +++ b/src/corelib/io/qtemporaryfile.cpp
  798. @@ -44,10 +44,8 @@
  799.  #ifndef QT_NO_TEMPORARYFILE
  800.  
  801.  #include "qplatformdefs.h"
  802. -#include "qabstractfileengine.h"
  803.  #include "qstringbuilder.h"
  804.  #include "private/qfile_p.h"
  805. -#include "private/qabstractfileengine_p.h"
  806.  #include "private/qfsfileengine_p.h"
  807.  #include "private/qsystemerror_p.h"
  808.  
  809. --
  810. 1.7.5.2
  811.  
  812.  
  813. From 3e7fa05d47ffd5a0012b5a512956e6ce386e2fc5 Mon Sep 17 00:00:00 2001
  814. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  815. Date: Fri, 5 Aug 2011 10:49:44 +0200
  816. Subject: [PATCH 07/10] Use "native paths" on POSIX platforms as well
  817.  
  818. And don't rely solely on "local8Bit" conversions.
  819.  
  820. QFile defines an API for overriding how encoding conversions are done
  821. for filenames. In generating unique names, QTemporaryFile ignored that
  822. API and hardcoded the use of local 8-bit, implicitly assuming that that
  823. was appropriate.
  824.  
  825. With this change, we switch that assumption to one where user supplied
  826. encoding function keeps the byte value of 'X' and '/', also assuming
  827. that encoded 'X' takes up a single-byte (i.e., the byte sequence for
  828. "XXXXXX" remains unchanged).
  829.  
  830. There was also, and there still is an assumption in name generation that
  831. byte values for ASCII alpha-numeric characters are valid in the "native"
  832. encoding.
  833.  
  834. In practice this change is compatible with UTF-8, Latin-1 and other
  835. ISO/IEC 8859 encodings. At any rate, it's very likely that only UTF-8 is
  836. relevant here.
  837.  
  838. Reviewed-by: Denis Dzyubenko
  839. ---
  840. src/corelib/io/qtemporaryfile.cpp |   30 +++---------------------------
  841.  1 files changed, 3 insertions(+), 27 deletions(-)
  842.  
  843. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  844. index 9f7cde2..ac5deac 100644
  845. --- a/src/corelib/io/qtemporaryfile.cpp
  846. +++ b/src/corelib/io/qtemporaryfile.cpp
  847. @@ -366,14 +366,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  848.      if (!filePathIsTemplate)
  849.          return QFSFileEngine::open(openMode);
  850.  
  851. -    const QString qfilename =
  852. -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  853. -        // Since the native encoding is out of our control, we need to process
  854. -        // the path as UTF-16 before doing any conversions
  855. -        d->fileEntry.filePath();
  856. -#else
  857. -        d->fileEntry.nativeFilePath();
  858. -#endif
  859. +    const QFileSystemEntry::NativePath qfilename = d->fileEntry.nativeFilePath();
  860.  
  861.      // Find placeholder string.
  862.      uint phPos = qfilename.length();
  863. @@ -382,7 +375,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  864.      while (phPos != 0) {
  865.          --phPos;
  866.  
  867. -        if (qfilename[phPos] == QLatin1Char('X')) {
  868. +        if (qfilename[phPos] == Latin1Char('X')) {
  869.              ++phLength;
  870.              continue;
  871.          }
  872. @@ -390,7 +383,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  873.          if (phLength >= 6
  874.                  || qfilename[phPos] ==
  875.  #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  876. -                    QLatin1Char('/')
  877. +                    '/'
  878.  #else
  879.                      QLatin1Char('\\')
  880.  #endif
  881. @@ -404,29 +397,12 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  882.  
  883.      QFileSystemEntry::NativePath filename;
  884.  
  885. -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  886. -    if (phLength < 6) {
  887. -        filename = qfilename.toLocal8Bit();
  888. -
  889. -        phPos = filename.length() + 1; // Account for added dot in prefix
  890. -        phLength = 6;
  891. -        filename = filename % '.' % Placeholder(phLength);
  892. -    } else {
  893. -        QByteArray prefix, suffix;
  894. -        prefix = qfilename.leftRef(phPos).toLocal8Bit();
  895. -        suffix = qfilename.midRef(phPos + phLength).toLocal8Bit();
  896. -
  897. -        phPos = prefix.length();
  898. -        filename = prefix % Placeholder(phLength) % suffix;
  899. -    }
  900. -#else
  901.      if (phLength < 6) {
  902.          phPos = qfilename.length() + 1; // Account for added dot in prefix
  903.          phLength = 6;
  904.          filename = qfilename % Latin1Char('.') % Placeholder(phLength);
  905.      } else
  906.          filename = qfilename;
  907. -#endif
  908.  
  909.      QSystemError error;
  910.  #if defined(Q_OS_WIN)
  911. --
  912. 1.7.5.2
  913.  
  914.  
  915. From d0be3224db3b9b59e4df17eddee7eed38e4460c5 Mon Sep 17 00:00:00 2001
  916. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  917. Date: Tue, 16 Aug 2011 17:53:41 +0200
  918. Subject: [PATCH 08/10] Fix QTemporaryFile regressions and new found issues
  919.  
  920. With this change, the file template is always processed in original
  921. QString format. Trying to generate native paths before adding a missing
  922. placeholder mask could change the meaning of templates, such as "." and
  923. "..", which are now tested to mean "..XXXXXX" and "...XXXXXX",
  924. respectively.
  925.  
  926. After ensuring the template includes a placeholder mask, the path is
  927. converted to a native *absolute* file path and the mask is sought for
  928. again. On Windows, native paths were already absolute. On Symbian, we'd
  929. need at least a clean path, as "." and ",," are not natively understood.
  930.  
  931. There is a requirement that the placeholder mask /XXXXXX+/ makes it
  932. through this conversion unaltered, which relaxes prior requirements on
  933. *nix platforms. On Windows and Symbian the conversion is under Qt's
  934. control and not user-configurable.
  935.  
  936. Reviewed-by: Shane Kearns
  937. ---
  938. src/corelib/io/qtemporaryfile.cpp                |   84 +++++++++-------------
  939.  tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |    2 +
  940.  2 files changed, 36 insertions(+), 50 deletions(-)
  941.  
  942. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  943. index ac5deac..375d07f 100644
  944. --- a/src/corelib/io/qtemporaryfile.cpp
  945. +++ b/src/corelib/io/qtemporaryfile.cpp
  946. @@ -44,10 +44,10 @@
  947.  #ifndef QT_NO_TEMPORARYFILE
  948.  
  949.  #include "qplatformdefs.h"
  950. -#include "qstringbuilder.h"
  951.  #include "private/qfile_p.h"
  952.  #include "private/qfsfileengine_p.h"
  953.  #include "private/qsystemerror_p.h"
  954. +#include "private/qfilesystemengine_p.h"
  955.  
  956.  #if defined(Q_OS_SYMBIAN)
  957.  #include "private/qcore_symbian_p.h"
  958. @@ -102,38 +102,6 @@ typedef char Latin1Char;
  959.  typedef int NativeFileHandle;
  960.  #endif
  961.  
  962. -struct Placeholder
  963. -{
  964. -    Placeholder(int size)
  965. -        : size_(size)
  966. -    {
  967. -    }
  968. -
  969. -    int size() const
  970. -    {
  971. -        return size_;
  972. -    }
  973. -
  974. -private:
  975. -    int size_;
  976. -};
  977. -
  978. -template <>
  979. -struct QConcatenable<Placeholder>
  980. -{
  981. -    typedef Placeholder type;
  982. -    typedef QByteArray ConvertTo;
  983. -    enum { ExactSize = true };
  984. -    static int size(const Placeholder &p) { return p.size(); }
  985. -
  986. -    template <class CharT>
  987. -    static inline void appendTo(const Placeholder &p, CharT *&out)
  988. -    {
  989. -        // Uninitialized
  990. -        out += p.size();
  991. -    }
  992. -};
  993. -
  994.  /*
  995.   * Copyright (c) 1987, 1993
  996.   * The Regents of the University of California.  All rights reserved.
  997. @@ -366,43 +334,59 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  998.      if (!filePathIsTemplate)
  999.          return QFSFileEngine::open(openMode);
  1000.  
  1001. -    const QFileSystemEntry::NativePath qfilename = d->fileEntry.nativeFilePath();
  1002. +    QString qfilename = d->fileEntry.filePath();
  1003.  
  1004. -    // Find placeholder string.
  1005. +    // Ensure there is a placeholder mask
  1006.      uint phPos = qfilename.length();
  1007.      uint phLength = 0;
  1008.  
  1009.      while (phPos != 0) {
  1010.          --phPos;
  1011.  
  1012. -        if (qfilename[phPos] == Latin1Char('X')) {
  1013. +        if (qfilename[phPos] == QLatin1Char('X')) {
  1014.              ++phLength;
  1015.              continue;
  1016.          }
  1017.  
  1018.          if (phLength >= 6
  1019. -                || qfilename[phPos] ==
  1020. -#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
  1021. -                    '/'
  1022. -#else
  1023. -                    QLatin1Char('\\')
  1024. -#endif
  1025. -                ) {
  1026. +                || qfilename[phPos] == QLatin1Char('/')) {
  1027.              ++phPos;
  1028.              break;
  1029.          }
  1030.  
  1031. +        // start over
  1032.          phLength = 0;
  1033.      }
  1034.  
  1035. -    QFileSystemEntry::NativePath filename;
  1036. +    if (phLength < 6)
  1037. +        qfilename.append(QLatin1String(".XXXXXX"));
  1038. +
  1039. +    // "Nativify" :-)
  1040. +    QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName(
  1041. +            QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath()))
  1042. +        .nativeFilePath();
  1043. +
  1044. +    // Find mask in native path
  1045. +    phPos = filename.length();
  1046. +    phLength = 0;
  1047. +    while (phPos != 0) {
  1048. +        --phPos;
  1049. +
  1050. +        if (filename[phPos] == Latin1Char('X')) {
  1051. +            ++phLength;
  1052. +            continue;
  1053. +        }
  1054. +
  1055. +        if (phLength >= 6) {
  1056. +            ++phPos;
  1057. +            break;
  1058. +        }
  1059. +
  1060. +        // start over
  1061. +        phLength = 0;
  1062. +    }
  1063.  
  1064. -    if (phLength < 6) {
  1065. -        phPos = qfilename.length() + 1; // Account for added dot in prefix
  1066. -        phLength = 6;
  1067. -        filename = qfilename % Latin1Char('.') % Placeholder(phLength);
  1068. -    } else
  1069. -        filename = qfilename;
  1070. +    Q_ASSERT(phLength >= 6);
  1071.  
  1072.      QSystemError error;
  1073.  #if defined(Q_OS_WIN)
  1074. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1075. index 2db5c60..18b9337 100644
  1076. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1077. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1078. @@ -632,6 +632,8 @@ void tst_QTemporaryFile::QTBUG_4796_data()
  1079.      QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
  1080.  
  1081.      QTest::newRow("<empty>") << QString() << QString() << true;
  1082. +    QTest::newRow(".") << QString(".") << QString() << true;
  1083. +    QTest::newRow("..") << QString("..") << QString() << true;
  1084.      QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
  1085.      QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
  1086.      QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
  1087. --
  1088. 1.7.5.2
  1089.  
  1090.  
  1091. From 72befe44016f283a95aca9faf276e802633e5a76 Mon Sep 17 00:00:00 2001
  1092. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  1093. Date: Wed, 17 Aug 2011 14:38:27 +0200
  1094. Subject: [PATCH 09/10] Cleanup code: removing empty stubs
  1095.  
  1096. ---
  1097. tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |   29 ----------------------
  1098.  1 files changed, 0 insertions(+), 29 deletions(-)
  1099.  
  1100. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1101. index 18b9337..11b2bb3 100644
  1102. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1103. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1104. @@ -69,13 +69,7 @@
  1105.  class tst_QTemporaryFile : public QObject
  1106.  {
  1107.      Q_OBJECT
  1108. -public:
  1109. -    tst_QTemporaryFile();
  1110. -    virtual ~tst_QTemporaryFile();
  1111.  public slots:
  1112. -    void init();
  1113. -    void cleanup();
  1114. -
  1115.      void initTestCase();
  1116.      void cleanupTestCase();
  1117.  
  1118. @@ -103,8 +97,6 @@ private slots:
  1119.  
  1120.      void QTBUG_4796_data();
  1121.      void QTBUG_4796();
  1122. -
  1123. -public:
  1124.  };
  1125.  
  1126.  void tst_QTemporaryFile::initTestCase()
  1127. @@ -139,27 +131,6 @@ void tst_QTemporaryFile::getSetCheck()
  1128.      QCOMPARE(true, obj1.autoRemove());
  1129.  }
  1130.  
  1131. -tst_QTemporaryFile::tst_QTemporaryFile()
  1132. -{
  1133. -}
  1134. -
  1135. -tst_QTemporaryFile::~tst_QTemporaryFile()
  1136. -{
  1137. -
  1138. -}
  1139. -
  1140. -void tst_QTemporaryFile::init()
  1141. -{
  1142. -// TODO: Add initialization code here.
  1143. -// This will be executed immediately before each test is run.
  1144. -}
  1145. -
  1146. -void tst_QTemporaryFile::cleanup()
  1147. -{
  1148. -// TODO: Add cleanup code here.
  1149. -// This will be executed immediately after each test is run.
  1150. -}
  1151. -
  1152.  void tst_QTemporaryFile::fileTemplate_data()
  1153.  {
  1154.      QTest::addColumn<QString>("constructorTemplate");
  1155. --
  1156. 1.7.5.2
  1157.  
  1158.  
  1159. From efa0c44e9fb2a0c25329eaf8b1582f93f2da5efd Mon Sep 17 00:00:00 2001
  1160. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  1161. Date: Wed, 17 Aug 2011 14:43:18 +0200
  1162. Subject: [PATCH 10/10] Merged fileTemplate test with QTBUG_4796
  1163.  
  1164. The latter was more thorough, but didn't test setting the file template
  1165. after construction, while the former included some prefix/suffix
  1166. combinations that weren't specifically tested in the latter.
  1167.  
  1168. Reviewed-by: ?
  1169. ---
  1170. tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |  116 +++++++++-------------
  1171.  1 files changed, 48 insertions(+), 68 deletions(-)
  1172.  
  1173. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1174. index 11b2bb3..c9d4ba4 100644
  1175. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1176. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  1177. @@ -94,20 +94,17 @@ private slots:
  1178.      void resetTemplateAfterError();
  1179.      void setTemplateAfterOpen();
  1180.      void autoRemoveAfterFailedRename();
  1181. -
  1182. -    void QTBUG_4796_data();
  1183. -    void QTBUG_4796();
  1184.  };
  1185.  
  1186.  void tst_QTemporaryFile::initTestCase()
  1187.  {
  1188. -    // For QTBUG_4796
  1189. +    // For fileTemplate tests
  1190.      QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
  1191.  }
  1192.  
  1193.  void tst_QTemporaryFile::cleanupTestCase()
  1194.  {
  1195. -    // From QTBUG_4796
  1196. +    // From fileTemplate tests
  1197.      QVERIFY(QDir().rmdir("test-XXXXXX"));
  1198.  }
  1199.  
  1200. @@ -131,56 +128,6 @@ void tst_QTemporaryFile::getSetCheck()
  1201.      QCOMPARE(true, obj1.autoRemove());
  1202.  }
  1203.  
  1204. -void tst_QTemporaryFile::fileTemplate_data()
  1205. -{
  1206. -    QTest::addColumn<QString>("constructorTemplate");
  1207. -    QTest::addColumn<QString>("prefix");
  1208. -    QTest::addColumn<QString>("suffix");
  1209. -    QTest::addColumn<QString>("fileTemplate");
  1210. -
  1211. -    QTest::newRow("constructor default") << "" << "." << "" << "";
  1212. -    QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_" << "xxx" << "";
  1213. -    QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_" << "xXx" << "";
  1214. -    QTest::newRow("constructor with no sufix") << "qt_XXXXXX" << "qt_" << "" << "";
  1215. -    QTest::newRow("constructor with >6 X's and xxx suffix") << "qt_XXXXXXXXXXxxx" << "qt_" << "xxx" << "";
  1216. -    QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_" << "" << "";
  1217. -
  1218. -    QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_" << "_XXXX" << "";
  1219. -    QTest::newRow("constructor with XXXXX suffix") << "qt_XXXXXX_XXXXX" << "qt_" << "_XXXXX" << "";
  1220. -    QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX." << "" << "";
  1221. -    QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX." << "" << "";
  1222. -    QTest::newRow("constructor with XXXX  prefix and suffix") << "qt_XXXX_XXXXXX_XXXX" << "qt_XXXX_" << "_XXXX" << "";
  1223. -    QTest::newRow("constructor with XXXXX prefix and suffix") << "qt_XXXXX_XXXXXX_XXXXX" << "qt_XXXXX_" << "_XXXXX" << "";
  1224. -
  1225. -    QTest::newRow("set template, no suffix") << "" << "foo" << "" << "foo";
  1226. -    QTest::newRow("set template, with lowercase XXXXXX") << "" << "qt_" << "xxxxxx" << "qt_XXXXXXxxxxxx";
  1227. -    QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx";
  1228. -    QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx";
  1229. -    QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX";
  1230. -}
  1231. -
  1232. -void tst_QTemporaryFile::fileTemplate()
  1233. -{
  1234. -    QFETCH(QString, constructorTemplate);
  1235. -    QFETCH(QString, prefix);
  1236. -    QFETCH(QString, suffix);
  1237. -    QFETCH(QString, fileTemplate);
  1238. -
  1239. -    QTemporaryFile file(constructorTemplate);
  1240. -    if (!fileTemplate.isEmpty())
  1241. -        file.setFileTemplate(fileTemplate);
  1242. -
  1243. -    QCOMPARE(file.open(), true);
  1244. -
  1245. -    QString fileName = QFileInfo(file).fileName();
  1246. -    if (prefix.length())
  1247. -        QCOMPARE(fileName.left(prefix.length()), prefix);
  1248. -
  1249. -    if (suffix.length())
  1250. -        QCOMPARE(fileName.right(suffix.length()), suffix);
  1251. -}
  1252. -
  1253. -
  1254.  /*
  1255.      This tests whether the temporary file really gets placed in QDir::tempPath
  1256.  */
  1257. @@ -594,7 +541,7 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename()
  1258.      cleaner.reset();
  1259.  }
  1260.  
  1261. -void tst_QTemporaryFile::QTBUG_4796_data()
  1262. +void tst_QTemporaryFile::fileTemplate_data()
  1263.  {
  1264.      QTest::addColumn<QString>("prefix");
  1265.      QTest::addColumn<QString>("suffix");
  1266. @@ -603,17 +550,33 @@ void tst_QTemporaryFile::QTBUG_4796_data()
  1267.      QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
  1268.  
  1269.      QTest::newRow("<empty>") << QString() << QString() << true;
  1270. +
  1271.      QTest::newRow(".") << QString(".") << QString() << true;
  1272.      QTest::newRow("..") << QString("..") << QString() << true;
  1273. +
  1274. +    QTest::newRow("foo") << QString("foo") << QString() << true;
  1275. +    QTest::newRow("qt_ ... xxxxxx") << QString("qt_") << QString("xxxxxx") << true;
  1276. +    QTest::newRow("qt_ ... xxx") << QString("qt_") << QString("xxx") << true;
  1277. +    QTest::newRow("qt_ ... xXx") << QString("qt_") << QString("xXx") << true;
  1278. +    QTest::newRow("qt_ ...") << QString("qt_") << QString() << true;
  1279. +    QTest::newRow("qt_ ... _XXXX") << QString("qt_") << QString("_XXXX") << true;
  1280. +    QTest::newRow("qt_ ... _XXXXX") << QString("qt_") << QString("_XXXXX") << true;
  1281. +    QTest::newRow("qt_XXXX_ ...") << QString("qt_XXXX_") << QString() << true;
  1282. +    QTest::newRow("qt_XXXXX_ ...") << QString("qt_XXXXX_") << QString() << true;
  1283. +    QTest::newRow("qt_XXXX_ ... _XXXX") << QString("qt_XXXX_") << QString("_XXXX") << true;
  1284. +    QTest::newRow("qt_XXXXX_ ... _XXXXX") << QString("qt_XXXXX_") << QString("_XXXXX") << true;
  1285. +
  1286.      QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
  1287.      QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
  1288. +
  1289.      QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
  1290. +
  1291.      QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
  1292.      QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
  1293.      QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true;
  1294.  }
  1295.  
  1296. -void tst_QTemporaryFile::QTBUG_4796()
  1297. +void tst_QTemporaryFile::fileTemplate()
  1298.  {
  1299.      QVERIFY(QDir("test-XXXXXX").exists());
  1300.  
  1301. @@ -639,18 +602,40 @@ void tst_QTemporaryFile::QTBUG_4796()
  1302.      QFETCH(QString, suffix);
  1303.      QFETCH(bool, openResult);
  1304.  
  1305. +    enum IterationType {
  1306. +        UseConstructor,
  1307. +        UseSetFileTemplate,
  1308. +        Done
  1309. +    };
  1310. +
  1311. +    for (IterationType setFileTemplate = UseConstructor; setFileTemplate != Done;
  1312. +            setFileTemplate = IterationType(int(setFileTemplate) + 1))
  1313.      {
  1314. +        Q_FOREACH(QString const &tempName, cleaner.tempNames)
  1315. +            QVERIFY( !QFile::exists(tempName) );
  1316. +
  1317. +        cleaner.reset();
  1318. +
  1319.          QString fileTemplate1 = prefix + QString("XX") + suffix;
  1320.          QString fileTemplate2 = prefix + QString("XXXX") + suffix;
  1321.          QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
  1322.          QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
  1323.  
  1324. -        QTemporaryFile file1(fileTemplate1);
  1325. -        QTemporaryFile file2(fileTemplate2);
  1326. -        QTemporaryFile file3(fileTemplate3);
  1327. -        QTemporaryFile file4(fileTemplate4);
  1328. -        QTemporaryFile file5("test-XXXXXX/" + fileTemplate1);
  1329. -        QTemporaryFile file6("test-XXXXXX/" + fileTemplate3);
  1330. +        QTemporaryFile file1(setFileTemplate ? QString() : fileTemplate1);
  1331. +        QTemporaryFile file2(setFileTemplate ? QString() : fileTemplate2);
  1332. +        QTemporaryFile file3(setFileTemplate ? QString() : fileTemplate3);
  1333. +        QTemporaryFile file4(setFileTemplate ? QString() : fileTemplate4);
  1334. +        QTemporaryFile file5(setFileTemplate ? QString() : "test-XXXXXX/" + fileTemplate1);
  1335. +        QTemporaryFile file6(setFileTemplate ? QString() : "test-XXXXXX/" + fileTemplate3);
  1336. +
  1337. +        if (setFileTemplate) {
  1338. +            file1.setFileTemplate(fileTemplate1);
  1339. +            file2.setFileTemplate(fileTemplate2);
  1340. +            file3.setFileTemplate(fileTemplate3);
  1341. +            file4.setFileTemplate(fileTemplate4);
  1342. +            file5.setFileTemplate("test-XXXXXX/" + fileTemplate1);
  1343. +            file6.setFileTemplate("test-XXXXXX/" + fileTemplate3);
  1344. +        }
  1345.  
  1346.          if (openResult) {
  1347.              QVERIFY2(file1.open(), qPrintable(file1.errorString()));
  1348. @@ -709,11 +694,6 @@ void tst_QTemporaryFile::QTBUG_4796()
  1349.              }
  1350.          }
  1351.      }
  1352. -
  1353. -    Q_FOREACH(QString const &tempName, cleaner.tempNames)
  1354. -        QVERIFY( !QFile::exists(tempName) );
  1355. -
  1356. -    cleaner.reset();
  1357.  }
  1358.  
  1359.  QTEST_MAIN(tst_QTemporaryFile)
  1360. --
  1361. 1.7.5.2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement