Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 29.12 KB | None | 0 0
  1. From a7635e243c06fe5ffc5ce37caf77c994a2eadeeb Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  3. Date: Wed, 10 Nov 2010 11:32:19 +0100
  4. Subject: [PATCH 1/6] Removing dead code in QTemporaryFile
  5.  
  6. The option to create a directory is never used, so let's drop it. There
  7. are bigger issues with this code.
  8.  
  9. Reviewed-by: ? pending
  10. ---
  11. src/corelib/io/qtemporaryfile.cpp |   22 ++++------------------
  12.  1 files changed, 4 insertions(+), 18 deletions(-)
  13.  
  14. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  15. index c34c4a4..f4011ee 100644
  16. --- a/src/corelib/io/qtemporaryfile.cpp
  17. +++ b/src/corelib/io/qtemporaryfile.cpp
  18. @@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
  19.   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  20.   * SUCH DAMAGE.
  21.   */
  22. -static int _gettemp(char *path, int *doopen, int domkdir, int slen)
  23. +static int _gettemp(char *path, int *doopen, int slen)
  24.  {
  25.      char *start, *trv, *suffp;
  26.      QT_STATBUF sbuf;
  27. @@ -120,11 +120,6 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
  28.      pid_t pid;
  29.  #endif
  30.  
  31. -    if (doopen && domkdir) {
  32. -        errno = EINVAL;
  33. -        return 0;
  34. -    }
  35. -
  36.      for (trv = path; *trv; ++trv)
  37.          ;
  38.      trv -= slen;
  39. @@ -167,7 +162,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
  40.       * check the target directory; if you have six X's and it
  41.       * doesn't exist this runs for a *very* long time.
  42.       */
  43. -    if (doopen || domkdir) {
  44. +    if (doopen) {
  45.          for (;; --trv) {
  46.              if (trv <= path)
  47.                  break;
  48. @@ -235,15 +230,6 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
  49.              }
  50.              if (errno != EEXIST)
  51.                  return 0;
  52. -        } else if (domkdir) {
  53. -#ifdef Q_OS_WIN
  54. -            if (QT_MKDIR(path) == 0)
  55. -#else
  56. -            if (QT_MKDIR(path, 0700) == 0)
  57. -#endif
  58. -                return 1;
  59. -            if (errno != EEXIST)
  60. -                return 0;
  61.          }
  62.  #ifndef Q_OS_WIN
  63.          else if (QT_LSTAT(path, &sbuf))
  64. @@ -282,7 +268,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
  65.  static int qt_mkstemps(char *path, int slen)
  66.  {
  67.      int fd = 0;
  68. -    return (_gettemp(path, &fd, 0, slen) ? fd : -1);
  69. +    return (_gettemp(path, &fd, slen) ? fd : -1);
  70.  }
  71.  #endif
  72.  
  73. @@ -390,7 +376,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  74.      setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
  75.      return false;
  76.  #else
  77. -    if (!_gettemp(filename, 0, 0, suffixLength)) {
  78. +    if (!_gettemp(filename, 0, suffixLength)) {
  79.          delete [] filename;
  80.          return false;
  81.      }
  82. --
  83. 1.7.3
  84.  
  85.  
  86. From eb55171fb58f7dbbfc8fba99ec137cc5f270b997 Mon Sep 17 00:00:00 2001
  87. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  88. Date: Wed, 10 Nov 2010 18:09:56 +0100
  89. Subject: [PATCH 2/6] tst_QCompleter: Clean up after one's self
  90.  
  91. The utility class FileSystem uses the RAII idiom to clean up directories
  92. created for the purpose of the test.
  93.  
  94. Reviewed-by: ? pending
  95. ---
  96. tests/auto/qcompleter/tst_qcompleter.cpp |   31 ++++++++++-------------------
  97.  1 files changed, 11 insertions(+), 20 deletions(-)
  98.  
  99. diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp
  100. index 650c328..fe71d68 100644
  101. --- a/tests/auto/qcompleter/tst_qcompleter.cpp
  102. +++ b/tests/auto/qcompleter/tst_qcompleter.cpp
  103. @@ -49,6 +49,7 @@
  104.  #include <QPointer>
  105.  
  106.  #include "../../shared/util.h"
  107. +#include "../../shared/filesystem.h"
  108.  
  109.  //TESTED_CLASS=
  110.  //TESTED_FILES=
  111. @@ -1455,29 +1456,19 @@ void tst_QCompleter::task247560_keyboardNavigation()
  112.  
  113.  void tst_QCompleter::QTBUG_14292_filesystem()
  114.  {
  115. -    QDir tmpDir = QDir::temp();
  116. +    FileSystem fs;
  117. +
  118.      qsrand(QTime::currentTime().msec());
  119.      QString d = "tst_QCompleter_" + QString::number(qrand());
  120. -    QVERIFY(tmpDir.mkdir(d));
  121. -
  122. -#if 0
  123. -    struct Cleanup {
  124. -        QString dir;
  125. -        ~Cleanup() {
  126. -            qDebug() << dir <<
  127. -            QFile::remove(dir); }
  128. -    } cleanup;
  129. -    cleanup.dir = tmpDir.absolutePath()+"/" +d;
  130. -#endif
  131. +    QVERIFY(fs.createDirectory(d));
  132.  
  133. -    QVERIFY(tmpDir.cd(d));
  134. -    QVERIFY(tmpDir.mkdir("hello"));
  135. -    QVERIFY(tmpDir.mkdir("holla"));
  136. +    QVERIFY(fs.createDirectory(d + "/hello"));
  137. +    QVERIFY(fs.createDirectory(d + "/holla"));
  138.  
  139.      QLineEdit edit;
  140.      QCompleter comp;
  141.      QFileSystemModel model;
  142. -    model.setRootPath(tmpDir.path());
  143. +    model.setRootPath("./");
  144.      comp.setModel(&model);
  145.      edit.setCompleter(&comp);
  146.  
  147. @@ -1489,7 +1480,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
  148.      QTRY_VERIFY(edit.hasFocus());
  149.  
  150.      QVERIFY(!comp.popup()->isVisible());
  151. -    edit.setText(tmpDir.path());
  152. +    edit.setText(d);
  153.      QTest::keyClick(&edit, '/');
  154.      QTRY_VERIFY(comp.popup()->isVisible());
  155.      QCOMPARE(comp.popup()->model()->rowCount(), 2);
  156. @@ -1500,12 +1491,12 @@ void tst_QCompleter::QTBUG_14292_filesystem()
  157.      QCOMPARE(comp.popup()->model()->rowCount(), 1);
  158.      QTest::keyClick(&edit, 'r');
  159.      QTRY_VERIFY(!comp.popup()->isVisible());
  160. -    QVERIFY(tmpDir.mkdir("hero"));
  161. +    QVERIFY(fs.createDirectory(d + "/hero"));
  162.      QTRY_VERIFY(comp.popup()->isVisible());
  163.      QCOMPARE(comp.popup()->model()->rowCount(), 1);
  164.      QTest::keyClick(comp.popup(), Qt::Key_Escape);
  165.      QTRY_VERIFY(!comp.popup()->isVisible());
  166. -    QVERIFY(tmpDir.mkdir("nothingThere"));
  167. +    QVERIFY(fs.createDirectory(d + "/nothingThere"));
  168.      //there is no reason creating a file should open a popup, it did in Qt 4.7.0
  169.      QTest::qWait(60);
  170.      QVERIFY(!comp.popup()->isVisible());
  171. @@ -1522,7 +1513,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
  172.      QTest::qWaitForWindowShown(&w);
  173.      QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus());
  174.  
  175. -    QVERIFY(tmpDir.mkdir("hemo"));
  176. +    QVERIFY(fs.createDirectory(d + "/hemo"));
  177.      //there is no reason creating a file should open a popup, it did in Qt 4.7.0
  178.      QTest::qWait(60);
  179.      QVERIFY(!comp.popup()->isVisible());
  180. --
  181. 1.7.3
  182.  
  183.  
  184. From 78ed775c1d93f5bbc1deb1c62a4193ae7a014c4e Mon Sep 17 00:00:00 2001
  185. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  186. Date: Wed, 10 Nov 2010 18:12:13 +0100
  187. Subject: [PATCH 3/6] QTemporaryFile: use GetCurrentProcessId instead of getpid on Windows
  188.  
  189. getpid is deprecated on Windows since VS 2005. Then again, there's no
  190. reason to use a POSIX function here at all. GetCurrentProcessId, on the
  191. other hand, is part of the Windows API and has been available since
  192. Windows 2000.
  193.  
  194. Reviewed-by: ? pending
  195. ---
  196. src/corelib/io/qtemporaryfile.cpp |    6 +++---
  197.  1 files changed, 3 insertions(+), 3 deletions(-)
  198.  
  199. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  200. index f4011ee..fd4f96b 100644
  201. --- a/src/corelib/io/qtemporaryfile.cpp
  202. +++ b/src/corelib/io/qtemporaryfile.cpp
  203. @@ -115,7 +115,7 @@ static int _gettemp(char *path, int *doopen, int slen)
  204.      QT_STATBUF sbuf;
  205.      int rval;
  206.  #if defined(Q_OS_WIN)
  207. -    int pid;
  208. +    DWORD pid;
  209.  #else
  210.      pid_t pid;
  211.  #endif
  212. @@ -129,8 +129,8 @@ static int _gettemp(char *path, int *doopen, int slen)
  213.          errno = EINVAL;
  214.          return 0;
  215.      }
  216. -#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
  217. -    pid = _getpid();
  218. +#if defined(Q_OS_WIN)
  219. +    pid = ::GetCurrentThreadId();
  220.  #elif defined(Q_OS_VXWORKS)
  221.      pid = (pid_t) taskIdCurrent;
  222.  #else
  223. --
  224. 1.7.3
  225.  
  226.  
  227. From bff52a075d52da4571b9a2da662abf98eb5e9b4a Mon Sep 17 00:00:00 2001
  228. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  229. Date: Thu, 11 Nov 2010 15:22:49 +0100
  230. Subject: [PATCH 4/6] QTemporaryFile: More dead code elimination
  231.  
  232. There are exactly 2 uses of the _gettemp function: one for windows
  233. platforms, one for all others. Windows requests a file name, others
  234. request a valid file descriptor for that file name.
  235.  
  236. Despite the 2 distinct use cases, the code was full of #ifdefs to keep
  237. never used code paths compiling.
  238.  
  239. With this change the qt_mkstemp wrapper is eliminated, together with
  240. dead code inside if (doopen) {} blocks on Windows platforms. The more
  241. proper Q_OS_WIN macro is preferred to Q_WS_WIN.
  242.  
  243. _gettemp is also changed to return the valid file descriptor on
  244. non-Windows platforms.
  245.  
  246. Reviewed-by: ? pending
  247. ---
  248. src/corelib/io/qtemporaryfile.cpp |  110 ++++++++++---------------------------
  249.  1 files changed, 29 insertions(+), 81 deletions(-)
  250.  
  251. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  252. index fd4f96b..a17566c 100644
  253. --- a/src/corelib/io/qtemporaryfile.cpp
  254. +++ b/src/corelib/io/qtemporaryfile.cpp
  255. @@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
  256.   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  257.   * SUCH DAMAGE.
  258.   */
  259. -static int _gettemp(char *path, int *doopen, int slen)
  260. +static int _gettemp(char *path, int slen)
  261.  {
  262.      char *start, *trv, *suffp;
  263.      QT_STATBUF sbuf;
  264. @@ -127,7 +127,7 @@ static int _gettemp(char *path, int *doopen, int slen)
  265.      --trv;
  266.      if (trv < path) {
  267.          errno = EINVAL;
  268. -        return 0;
  269. +        return -1;
  270.      }
  271.  #if defined(Q_OS_WIN)
  272.      pid = ::GetCurrentThreadId();
  273. @@ -158,82 +158,38 @@ static int _gettemp(char *path, int *doopen, int slen)
  274.      }
  275.      start = trv + 1;
  276.  
  277. +#ifndef Q_OS_WIN
  278.      /*
  279.       * check the target directory; if you have six X's and it
  280.       * doesn't exist this runs for a *very* long time.
  281.       */
  282. -    if (doopen) {
  283. -        for (;; --trv) {
  284. -            if (trv <= path)
  285. -                break;
  286. -            if (*trv == '/') {
  287. -                *trv = '\0';
  288. -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
  289. -                if (trv - path == 2 && path[1] == ':') {
  290. -                    // Special case for Windows drives
  291. -                    // (e.g., "C:" => "C:\").
  292. -                    // ### Better to use a Windows
  293. -                    // call for this.
  294. -                    char drive[] = "c:\\";
  295. -                    drive[0] = path[0];
  296. -                    rval = QT_STAT(drive, &sbuf);
  297. -                } else
  298. -#endif
  299. -                    rval = QT_STAT(path, &sbuf);
  300. -                *trv = '/';
  301. -                if (rval != 0)
  302. -                    return 0;
  303. -                if (!S_ISDIR(sbuf.st_mode)) {
  304. -                    errno = ENOTDIR;
  305. -                    return 0;
  306. -                }
  307. -                break;
  308. +    for (;; --trv) {
  309. +        if (trv <= path)
  310. +            break;
  311. +        if (*trv == '/') {
  312. +            *trv = '\0';
  313. +            rval = QT_STAT(path, &sbuf);
  314. +            *trv = '/';
  315. +            if (rval != 0)
  316. +                return -1;
  317. +            if (!S_ISDIR(sbuf.st_mode)) {
  318. +                errno = ENOTDIR;
  319. +                return -1;
  320.              }
  321. +            break;
  322.          }
  323.      }
  324. +#endif
  325.  
  326.      for (;;) {
  327. -        if (doopen) {
  328. -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
  329. -            if (_sopen_s(doopen, path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR|QT_OPEN_BINARY
  330. -#  ifdef QT_LARGEFILE_SUPPORT
  331. -                                       |QT_OPEN_LARGEFILE
  332. -#  endif
  333. -                         , _SH_DENYNO, _S_IREAD | _S_IWRITE)== 0)
  334. -#else // WIN && !CE
  335. -#  if defined(Q_OS_WINCE)
  336. -            QString targetPath;
  337. -            if (QDir::isAbsolutePath(QString::fromLatin1(path)))
  338. -                targetPath = QLatin1String(path);
  339. -            else
  340. -                targetPath = QDir::currentPath().append(QLatin1Char('/')) + QLatin1String(path);
  341. -
  342. -            if ((*doopen =
  343. -                QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR
  344. -#  else // CE
  345. -            // this is Unix or older MSVC
  346. -            if ((*doopen =
  347. -                QT_OPEN(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR
  348. -#  endif
  349. -#  ifdef QT_LARGEFILE_SUPPORT
  350. -                           |QT_OPEN_LARGEFILE
  351. -#  endif
  352. -#  if defined(Q_OS_WINCE)
  353. -                           |_O_BINARY
  354. -#  elif defined(Q_OS_WIN)
  355. -                           |O_BINARY
  356. -#  endif
  357. -                     , 0600)) >= 0)
  358. -#endif // WIN && !CE
  359. -            {
  360. -                return 1;
  361. -            }
  362. +#ifndef Q_OS_WIN
  363. +        {
  364. +            int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
  365. +            if (fd != -1)
  366. +                return fd;
  367.              if (errno != EEXIST)
  368. -                return 0;
  369. +                return -1;
  370.          }
  371. -#ifndef Q_OS_WIN
  372. -        else if (QT_LSTAT(path, &sbuf))
  373. -            return (errno == ENOENT) ? 1 : 0;
  374.  #else
  375.          if (!QFileInfo(QLatin1String(path)).exists())
  376.              return 1;
  377. @@ -242,10 +198,10 @@ static int _gettemp(char *path, int *doopen, int slen)
  378.          /* tricky little algorwwithm for backward compatibility */
  379.          for (trv = start;;) {
  380.              if (!*trv)
  381. -                return 0;
  382. +                return -1;
  383.              if (*trv == 'Z') {
  384.                  if (trv == suffp)
  385. -                    return 0;
  386. +                    return -1;
  387.                  *trv++ = 'a';
  388.              } else {
  389.                  if (isdigit(*trv))
  390. @@ -254,7 +210,7 @@ static int _gettemp(char *path, int *doopen, int slen)
  391.                      *trv = 'A';
  392.                  else {
  393.                      if (trv == suffp)
  394. -                        return 0;
  395. +                        return -1;
  396.                      ++*trv;
  397.                  }
  398.                  break;
  399. @@ -264,14 +220,6 @@ static int _gettemp(char *path, int *doopen, int slen)
  400.      /*NOTREACHED*/
  401.  }
  402.  
  403. -#ifndef Q_WS_WIN
  404. -static int qt_mkstemps(char *path, int slen)
  405. -{
  406. -    int fd = 0;
  407. -    return (_gettemp(path, &fd, slen) ? fd : -1);
  408. -}
  409. -#endif
  410. -
  411.  //************* QTemporaryFileEngine
  412.  class QTemporaryFileEngine : public QFSFileEngine
  413.  {
  414. @@ -352,8 +300,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  415.      int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6);
  416.      char *filename = qstrdup(qfilename.toLocal8Bit());
  417.  
  418. -#ifndef Q_WS_WIN
  419. -    int fd = qt_mkstemps(filename, suffixLength);
  420. +#ifndef Q_OS_WIN
  421. +    int fd = _gettemp(filename, suffixLength);
  422.      if (fd != -1) {
  423.          // First open the fd as an external file descriptor to
  424.          // initialize the engine properly.
  425. @@ -376,7 +324,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  426.      setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
  427.      return false;
  428.  #else
  429. -    if (!_gettemp(filename, 0, suffixLength)) {
  430. +    if (_gettemp(filename, suffixLength) == -1) {
  431.          delete [] filename;
  432.          return false;
  433.      }
  434. --
  435. 1.7.3
  436.  
  437.  
  438. From a5a84a1aeeb97de6b7a159cf5b73d3c0af995857 Mon Sep 17 00:00:00 2001
  439. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  440. Date: Mon, 15 Nov 2010 13:47:43 +0100
  441. Subject: [PATCH 5/6] QTemporaryFile: use QCoreApplication::applicationPid
  442.  
  443. ... instead of repeating #ifdef's here.
  444.  
  445. Reviewed-by: ? pending
  446. ---
  447. src/corelib/io/qtemporaryfile.cpp |   16 ++++------------
  448.  1 files changed, 4 insertions(+), 12 deletions(-)
  449.  
  450. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  451. index a17566c..9d028fa 100644
  452. --- a/src/corelib/io/qtemporaryfile.cpp
  453. +++ b/src/corelib/io/qtemporaryfile.cpp
  454. @@ -44,6 +44,7 @@
  455.  #ifndef QT_NO_TEMPORARYFILE
  456.  
  457.  #include "qplatformdefs.h"
  458. +#include "qcoreapplication.h"
  459.  #include "qabstractfileengine.h"
  460.  #include "private/qfile_p.h"
  461.  #include "private/qabstractfileengine_p.h"
  462. @@ -114,11 +115,6 @@ static int _gettemp(char *path, int slen)
  463.      char *start, *trv, *suffp;
  464.      QT_STATBUF sbuf;
  465.      int rval;
  466. -#if defined(Q_OS_WIN)
  467. -    DWORD pid;
  468. -#else
  469. -    pid_t pid;
  470. -#endif
  471.  
  472.      for (trv = path; *trv; ++trv)
  473.          ;
  474. @@ -129,13 +125,9 @@ static int _gettemp(char *path, int slen)
  475.          errno = EINVAL;
  476.          return -1;
  477.      }
  478. -#if defined(Q_OS_WIN)
  479. -    pid = ::GetCurrentThreadId();
  480. -#elif defined(Q_OS_VXWORKS)
  481. -    pid = (pid_t) taskIdCurrent;
  482. -#else
  483. -    pid = getpid();
  484. -#endif
  485. +
  486. +    qint64 pid = QCoreApplication::applicationPid();
  487. +
  488.      while (trv >= path && *trv == 'X' && pid != 0) {
  489.          *trv-- = (pid % 10) + '0';
  490.          pid /= 10;
  491. --
  492. 1.7.3
  493.  
  494.  
  495. From 69cef964a5df5d5f95970bd0d2a39c37262451d7 Mon Sep 17 00:00:00 2001
  496. From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= <joao.abecasis@nokia.com>
  497. Date: Fri, 19 Nov 2010 14:27:45 +0100
  498. Subject: [PATCH 6/6] QTemporaryFile: work in progress
  499.  
  500. Reviewed-by: ! Not up for review !
  501. ---
  502. src/corelib/io/qtemporaryfile.cpp                |  250 +++++++++++-----------
  503.  tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp |  101 +++++++++-
  504.  2 files changed, 224 insertions(+), 127 deletions(-)
  505.  
  506. diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
  507. index 9d028fa..b567287 100644
  508. --- a/src/corelib/io/qtemporaryfile.cpp
  509. +++ b/src/corelib/io/qtemporaryfile.cpp
  510. @@ -82,6 +82,16 @@
  511.  
  512.  QT_BEGIN_NAMESPACE
  513.  
  514. +#ifdef Q_OS_WIN
  515. +typedef QChar Char;
  516. +typedef QLatin1Char Latin1Char;
  517. +typedef HANDLE FileDescriptor;
  518. +#else
  519. +typedef char Char;
  520. +typedef char Latin1Char;
  521. +typedef int FileDescriptor;
  522. +#endif
  523. +
  524.  /*
  525.   * Copyright (c) 1987, 1993
  526.   * The Regents of the University of California.  All rights reserved.
  527. @@ -110,103 +120,74 @@ QT_BEGIN_NAMESPACE
  528.   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  529.   * SUCH DAMAGE.
  530.   */
  531. -static int _gettemp(char *path, int slen)
  532. +static FileDescriptor _gettemp(Char *const path, int placeholderPosition, int placeholderLength)
  533.  {
  534. -    char *start, *trv, *suffp;
  535. -    QT_STATBUF sbuf;
  536. -    int rval;
  537. -
  538. -    for (trv = path; *trv; ++trv)
  539. -        ;
  540. -    trv -= slen;
  541. -    suffp = trv;
  542. -    --trv;
  543. -    if (trv < path) {
  544. -        errno = EINVAL;
  545. -        return -1;
  546. -    }
  547. -
  548. -    qint64 pid = QCoreApplication::applicationPid();
  549. +    Q_ASSERT(path);
  550. +    Q_ASSERT(placeholderPosition >= 0);
  551. +    Q_ASSERT(placeholderLength > 0);
  552.  
  553. -    while (trv >= path && *trv == 'X' && pid != 0) {
  554. -        *trv-- = (pid % 10) + '0';
  555. -        pid /= 10;
  556. -    }
  557. -
  558. -#ifndef S_ISDIR
  559. -#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
  560. -#endif
  561. -
  562. -    while (trv >= path && *trv == 'X') {
  563. -        char c;
  564. -
  565. -        // CHANGE arc4random() -> random()
  566. -        pid = (qrand() & 0xffff) % (26+26);
  567. -        if (pid < 26)
  568. -            c = pid + 'A';
  569. -        else
  570. -            c = (pid - 26) + 'a';
  571. -        *trv-- = c;
  572. -    }
  573. -    start = trv + 1;
  574. +    Char *const placeholderStart = path + placeholderPosition;
  575. +    Char *const placeholderEnd = placeholderStart + placeholderLength;
  576.  
  577. -#ifndef Q_OS_WIN
  578. -    /*
  579. -     * check the target directory; if you have six X's and it
  580. -     * doesn't exist this runs for a *very* long time.
  581. -     */
  582. -    for (;; --trv) {
  583. -        if (trv <= path)
  584. -            break;
  585. -        if (*trv == '/') {
  586. -            *trv = '\0';
  587. -            rval = QT_STAT(path, &sbuf);
  588. -            *trv = '/';
  589. -            if (rval != 0)
  590. -                return -1;
  591. -            if (!S_ISDIR(sbuf.st_mode)) {
  592. -                errno = ENOTDIR;
  593. -                return -1;
  594. -            }
  595. -            break;
  596. +    {
  597. +        static const qint64 constPid = QCoreApplication::applicationPid();
  598. +        qint64 pid = constPid;
  599. +
  600. +        Char *rIter = placeholderEnd;
  601. +        do {
  602. +            *--rIter = Latin1Char((pid % 10) + '0');
  603. +            pid /= 10;
  604. +        } while (rIter != placeholderStart && pid != 0);
  605. +
  606. +        while (rIter != placeholderStart) {
  607. +            int r = (qrand() & 0xffff) % (26 + 26);
  608. +            if (r < 26)
  609. +                *--rIter = Latin1Char(r + 'A');
  610. +            else
  611. +                *--rIter = Latin1Char(r - 26 + 'a');
  612.          }
  613.      }
  614. -#endif
  615.  
  616. -    for (;;) {
  617. +    forever {
  618.  #ifndef Q_OS_WIN
  619. -        {
  620. -            int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
  621. -            if (fd != -1)
  622. -                return fd;
  623. -            if (errno != EEXIST)
  624. -                return -1;
  625. -        }
  626. +        int file = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600);
  627. +        if (file != -1
  628. +                || errno != EEXIST)
  629. +            return file;
  630.  #else
  631. -        if (!QFileInfo(QLatin1String(path)).exists())
  632. -            return 1;
  633. +        HANDLE file = CreateFile((const wchar_t *)path,
  634. +                GENERIC_READ | GENERIC_WRITE,
  635. +                FILE_SHARE_READ | FILE_SHARE_WRITE,
  636. +                NULL,
  637. +                CREATE_NEW,
  638. +                FILE_ATTRIBUTE_NORMAL,
  639. +                NULL);
  640. +        if (file != INVALID_HANDLE_VALUE
  641. +                || GetLastError() != ERROR_FILE_EXISTS)
  642. +            return file;
  643.  #endif
  644.  
  645.          /* tricky little algorwwithm for backward compatibility */
  646. -        for (trv = start;;) {
  647. -            if (!*trv)
  648. -                return -1;
  649. -            if (*trv == 'Z') {
  650. -                if (trv == suffp)
  651. -                    return -1;
  652. -                *trv++ = 'a';
  653. -            } else {
  654. -                if (isdigit(*trv))
  655. -                    *trv = 'a';
  656. -                else if (*trv == 'z') /* inc from z to A */
  657. -                    *trv = 'A';
  658. -                else {
  659. -                    if (trv == suffp)
  660. -                        return -1;
  661. -                    ++*trv;
  662. -                }
  663. -                break;
  664. +        for (Char *iter = placeholderStart; iter != placeholderEnd; ++iter) {
  665. +            switch (char(*iter)) {
  666. +                case 'Z':
  667. +                    *iter = Latin1Char('a');
  668. +                    continue;
  669. +
  670. +                case '0': case '1': case '2': case '3': case '4':
  671. +                case '5': case '6': case '7': case '8': case '9':
  672. +                    *iter = Latin1Char('a');
  673. +                    break;
  674. +
  675. +                case 'z':
  676. +                    *iter = Latin1Char('A');
  677. +                    break;
  678. +
  679. +                default:
  680. +                    ++*iter;
  681. +                    break;
  682.              }
  683. +            break;
  684.          }
  685.      }
  686.      /*NOTREACHED*/
  687. @@ -285,56 +266,79 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
  688.      if (!filePathIsTemplate)
  689.          return QFSFileEngine::open(openMode);
  690.  
  691. -    QString qfilename = d->filePath;
  692. -    if(!qfilename.contains(QLatin1String("XXXXXX")))
  693. -        qfilename += QLatin1String(".XXXXXX");
  694. +    QString filePath = d->filePath;
  695.  
  696. -    int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6);
  697. -    char *filename = qstrdup(qfilename.toLocal8Bit());
  698. +    // Find placeholder string.
  699. +    int placeholderLength = 0;
  700. +    int placeholderPosition = filePath.length();
  701.  
  702. -#ifndef Q_OS_WIN
  703. -    int fd = _gettemp(filename, suffixLength);
  704. -    if (fd != -1) {
  705. -        // First open the fd as an external file descriptor to
  706. -        // initialize the engine properly.
  707. -        if (QFSFileEngine::open(openMode, fd)) {
  708. -
  709. -            // Allow the engine to close the handle even if it's "external".
  710. -            d->closeFileHandle = true;
  711. -
  712. -            // Restore the file names (open() resets them).
  713. -            d->filePath = QString::fromLocal8Bit(filename); //changed now!
  714. -            filePathIsTemplate = false;
  715. -            d->nativeInitFileName();
  716. -            delete [] filename;
  717. -            return true;
  718. +    while (--placeholderPosition != -1) {
  719. +        if (filePath[placeholderPosition] == QLatin1Char('X')) {
  720. +            ++placeholderLength;
  721. +            continue;
  722.          }
  723.  
  724. -        QT_CLOSE(fd);
  725. +        if (placeholderLength >= 6
  726. +                || filePath[placeholderPosition] == QLatin1Char('/'))
  727. +            break;
  728. +
  729. +        placeholderLength = 0;
  730.      }
  731. -    delete [] filename;
  732. -    setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
  733. -    return false;
  734. +    ++placeholderPosition;
  735. +
  736. +    QStringRef prefix, suffix;
  737. +    if (placeholderLength < 6) {
  738. +        filePath += QLatin1Char('.');
  739. +        prefix = QStringRef(&filePath);
  740. +        placeholderLength = 6;
  741. +    } else {
  742. +        if (placeholderPosition)
  743. +            prefix = filePath.leftRef(placeholderPosition);
  744. +        suffix = filePath.midRef(placeholderPosition + placeholderLength);
  745. +    }
  746. +
  747. +#ifdef Q_OS_WIN
  748. +    QString nativeFilePath = prefix % QString(placeholderLength, QLatin1Char('X')) % suffix;
  749. +    placeholderPosition = prefix.length();
  750.  #else
  751. -    if (_gettemp(filename, suffixLength) == -1) {
  752. -        delete [] filename;
  753. +    QByteArray nativeFilePath = prefix.toLocal8Bit();
  754. +    placeholderPosition = nativeFilePath.length();
  755. +
  756. +    nativeFilePath.resize(placeholderPosition + placeholderLength);
  757. +    nativeFilePath += suffix.toLocal8Bit();
  758. +#endif
  759. +
  760. +    Char *fileName = nativeFilePath.data();
  761. +    FileDescriptor file = _gettemp(fileName, placeholderPosition, placeholderLength);
  762. +
  763. +#ifdef Q_OS_WIN
  764. +    if (file == INVALID_HANDLE_VALUE) {
  765. +        setError(QFile::OpenError, qt_error_string());
  766.          return false;
  767.      }
  768.  
  769. -    QString template_ = d->filePath;
  770. -    d->filePath = QString::fromLocal8Bit(filename);
  771. -    d->nativeInitFileName();
  772. -    delete [] filename;
  773. -
  774. -    if (QFSFileEngine::open(openMode)) {
  775. -        filePathIsTemplate = false;
  776. -        return true;
  777. +    d->filePath = nativeFilePath();
  778. +    d->fileHandle = file;
  779. +#else
  780. +    if (file == -1) {
  781. +        setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
  782. +        return false;
  783.      }
  784.  
  785. -    d->filePath = template_;
  786. -    d->nativeFilePath.clear();
  787. -    return false;
  788. +    d->filePath = QString::fromLocal8Bit(fileName);
  789. +    d->fd = file;
  790. +    d->closeFileHandle = true;
  791.  #endif
  792. +
  793. +    filePathIsTemplate = false;
  794. +
  795. +    d->openMode = openMode;
  796. +    d->lastFlushFailed = false;
  797. +    d->tried_stat = 0;
  798. +
  799. +    d->nativeInitFileName();
  800. +
  801. +    return true;
  802.  }
  803.  
  804.  bool QTemporaryFileEngine::remove()
  805. diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  806. index 1304f4e..30d543d 100644
  807. --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  808. +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
  809. @@ -97,6 +97,9 @@ private slots:
  810.      void setTemplateAfterOpen();
  811.      void autoRemoveAfterFailedRename();
  812.  
  813. +    void qtbug_4796_data();
  814. +    void qtbug_4796();
  815. +
  816.  public:
  817.  };
  818.  
  819. @@ -359,10 +362,7 @@ void tst_QTemporaryFile::stressTest()
  820.      for (int i = 0; i < iterations; ++i) {
  821.          QTemporaryFile file;
  822.          file.setAutoRemove(false);
  823. -        if (!file.open()) {
  824. -            qDebug() << "Could not open File:" << file.fileName();
  825. -            continue;
  826. -        }
  827. +        QVERIFY(file.open());
  828.          QVERIFY(!names.contains(file.fileName()));
  829.          names.insert(file.fileName());
  830.      }
  831. @@ -594,5 +594,98 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename()
  832.      cleaner.reset();
  833.  }
  834.  
  835. +void tst_QTemporaryFile::qtbug_4796_data()
  836. +{
  837. +    QTest::addColumn<QString>("prefix");
  838. +    QTest::addColumn<QString>("suffix");
  839. +    QTest::addColumn<bool>("openResult");
  840. +
  841. +    QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
  842. +
  843. +    QTest::newRow("<empty>") << QString() << QString() << true;
  844. +    QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
  845. +    QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
  846. +    QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
  847. +    QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true;
  848. +    QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true;
  849. +    QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true;
  850. +}
  851. +
  852. +void tst_QTemporaryFile::qtbug_4796()
  853. +{
  854. +    struct CleanOnReturn
  855. +    {
  856. +        ~CleanOnReturn()
  857. +        {
  858. +            Q_FOREACH(QString tempName, tempNames)
  859. +                QFile::remove(tempName);
  860. +        }
  861. +
  862. +        void reset()
  863. +        {
  864. +            tempNames.clear();
  865. +        }
  866. +
  867. +        QStringList tempNames;
  868. +    };
  869. +
  870. +    CleanOnReturn cleaner;
  871. +
  872. +    QFETCH(QString, prefix);
  873. +    QFETCH(QString, suffix);
  874. +    QFETCH(bool, openResult);
  875. +
  876. +    {
  877. +        QString fileTemplate1 = prefix + QString("XX") + suffix;
  878. +        QString fileTemplate2 = prefix + QString("XXXX") + suffix;
  879. +        QString fileTemplate3 = prefix + QString("XXXXXX") + suffix;
  880. +        QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix;
  881. +
  882. +        QTemporaryFile file1(fileTemplate1);
  883. +        QTemporaryFile file2(fileTemplate2);
  884. +        QTemporaryFile file3(fileTemplate3);
  885. +        QTemporaryFile file4(fileTemplate4);
  886. +
  887. +        QCOMPARE(file1.open(), openResult);
  888. +        QCOMPARE(file2.open(), openResult);
  889. +        QCOMPARE(file3.open(), openResult);
  890. +        QCOMPARE(file4.open(), openResult);
  891. +
  892. +        QCOMPARE(file1.exists(), openResult);
  893. +        QCOMPARE(file2.exists(), openResult);
  894. +        QCOMPARE(file3.exists(), openResult);
  895. +        QCOMPARE(file4.exists(), openResult);
  896. +
  897. +        // make sure the file exists under the *correct* name
  898. +        if (openResult) {
  899. +            cleaner.tempNames << file1.fileName()
  900. +                << file2.fileName()
  901. +                << file3.fileName()
  902. +                << file4.fileName();
  903. +
  904. +            if (suffix.isEmpty()) {
  905. +                QVERIFY(file1.fileName().startsWith(prefix));
  906. +                QVERIFY(file2.fileName().startsWith(prefix));
  907. +            } else {
  908. +                QVERIFY(file1.fileName().startsWith(fileTemplate1));
  909. +                QVERIFY(file2.fileName().startsWith(fileTemplate2));
  910. +
  911. +                QVERIFY(file3.fileName().endsWith(suffix));
  912. +                QVERIFY(file4.fileName().endsWith(suffix));
  913. +            }
  914. +
  915. +            if (!prefix.isEmpty()) {
  916. +                QVERIFY(file3.fileName().startsWith(prefix));
  917. +                QVERIFY(file4.fileName().startsWith(prefix));
  918. +            }
  919. +        }
  920. +    }
  921. +
  922. +    Q_FOREACH(QString tempName, cleaner.tempNames)
  923. +        QVERIFY( !QFile::exists(tempName) );
  924. +
  925. +    cleaner.reset();
  926. +}
  927. +
  928.  QTEST_MAIN(tst_QTemporaryFile)
  929.  #include "tst_qtemporaryfile.moc"
  930. --
  931. 1.7.3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement