From 02418d1aaa6760e08d55f0f6213d02d56b057fd2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 19 May 2015 17:51:15 -0700 Subject: [PATCH] Set the state of QTemporaryFileEngine properly prior to reopening QTemporaryFileEngine does not store the pattern, so it needs to get it again from QTemporaryFilePrivate prior to reopening the file. It's possible to lose the pattern when remove() is called on the object. Task-number: QTBUG-46156 Change-Id: I66a35ce5f88941f29aa6ffff13dfc7f83d4fa3a2 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: David Faure --- src/corelib/io/qsavefile.cpp | 3 ++- src/corelib/io/qtemporaryfile.cpp | 25 ++++++++++++++++--- src/corelib/io/qtemporaryfile_p.h | 14 ++++------- .../io/qtemporaryfile/tst_qtemporaryfile.cpp | 1 + 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index ffa6ad1c55..5a325f8e2c 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -215,7 +215,8 @@ bool QSaveFile::open(OpenMode mode) d->finalFileName = existingFile.filePath(); } - d->fileEngine = new QTemporaryFileEngine(d->finalFileName, 0666); + d->fileEngine = new QTemporaryFileEngine; + static_cast(d->fileEngine)->initialize(d->finalFileName, 0666); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 556bc6e760..68ac85fffd 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -409,14 +409,24 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() QAbstractFileEngine *QTemporaryFilePrivate::engine() const { if (!fileEngine) { - if (fileName.isEmpty()) - fileEngine = new QTemporaryFileEngine(templateName, 0600); - else - fileEngine = new QTemporaryFileEngine(fileName, 0600, false); + fileEngine = new QTemporaryFileEngine; + resetFileEngine(); } return fileEngine; } +void QTemporaryFilePrivate::resetFileEngine() const +{ + if (!fileEngine) + return; + + QTemporaryFileEngine *tef = static_cast(fileEngine); + if (fileName.isEmpty()) + tef->initialize(templateName, 0600); + else + tef->initialize(fileName, 0600, false); +} + QString QTemporaryFilePrivate::defaultTemplateName() { QString baseName; @@ -769,6 +779,13 @@ bool QTemporaryFile::open(OpenMode flags) } } + // reset the engine state so it creates a new, unique file name from the template; + // equivalent to: + // delete d->fileEngine; + // d->fileEngine = 0; + // d->engine(); + d->resetFileEngine(); + if (QFile::open(flags)) { d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName); return true; diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index 475298f264..2d4468fcf8 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -64,6 +64,7 @@ protected: ~QTemporaryFilePrivate(); QAbstractFileEngine *engine() const; + void resetFileEngine() const; bool autoRemove; QString templateName; @@ -77,22 +78,17 @@ class QTemporaryFileEngine : public QFSFileEngine { Q_DECLARE_PRIVATE(QFSFileEngine) public: - - QTemporaryFileEngine(const QString &file, - quint32 fileMode, - bool fileIsTemplate = true) : - QFSFileEngine(), - fileMode(fileMode), - filePathIsTemplate(fileIsTemplate), - filePathWasTemplate(fileIsTemplate) + void initialize(const QString &file, quint32 mode, bool nameIsTemplate = true) { Q_D(QFSFileEngine); + Q_ASSERT(!isReallyOpen()); + fileMode = mode; + filePathIsTemplate = filePathWasTemplate = nameIsTemplate; d->fileEntry = QFileSystemEntry(file); if (!filePathIsTemplate) QFSFileEngine::setFileName(file); } - ~QTemporaryFileEngine(); bool isReallyOpen(); diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index e7325d2b8e..94e6bbaade 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -353,6 +353,7 @@ void tst_QTemporaryFile::removeAndReOpen() QVERIFY(!QFile::exists(fileName)); QVERIFY(file.open()); + QCOMPARE(QFileInfo(file.fileName()).path(), QFileInfo(fileName).path()); fileName = file.fileName(); QVERIFY(QFile::exists(fileName)); }