summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-07-11 13:35:45 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-07-11 22:00:10 +0200
commit54684f10e90b2ab1705cad97dd0a5d3942f06cc3 (patch)
treeb93b609e6d729816be57a7b92ecb60bbf05ad600
parentd01693733f6c1ebe6b3709f9c1284239ce3b5354 (diff)
QSaveFile: Fix changing the file name after hitting on readonly file
The call to QFileDevice::unsetError() in QSaveFile::open() does not clear QSaveFilePrivate::writeError. Clear it in addition. Fixes: QTBUG-77007 Change-Id: I5e5009750f1726d1c74c1b4eb1c33f3a5393fe4f Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r--src/corelib/io/qsavefile.cpp1
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp34
2 files changed, 35 insertions, 0 deletions
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 0cbc8c2234..fac8892da2 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -197,6 +197,7 @@ bool QSaveFile::open(OpenMode mode)
return false;
}
unsetError();
+ d->writeError = QFileDevice::NoError;
if ((mode & (ReadOnly | WriteOnly)) == 0) {
qWarning("QSaveFile::open: Open mode not specified");
return false;
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 96970421d3..f1327933c4 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -72,6 +72,7 @@ public slots:
private slots:
void transactionalWrite();
+ void retryTransactionalWrite();
void textStreamManualFlush();
void textStreamAutoFlush();
void saveTwice();
@@ -129,6 +130,39 @@ void tst_QSaveFile::transactionalWrite()
QCOMPARE(QFile::permissions(targetFile), QFile::permissions(otherFile));
}
+// QTBUG-77007: Simulate the case of an application with a loop prompting
+// to retry saving on failure. Create a read-only file first (Unix only)
+void tst_QSaveFile::retryTransactionalWrite()
+{
+#ifndef Q_OS_UNIX
+ QSKIP("This test is Unix only");
+#endif
+ QTemporaryDir dir;
+ QVERIFY2(dir.isValid(), qPrintable(dir.errorString()));
+
+ QString targetFile = dir.path() + QLatin1String("/outfile");
+ const QString readOnlyName = targetFile + QLatin1String(".ro");
+ {
+ QFile readOnlyFile(readOnlyName);
+ QVERIFY2(readOnlyFile.open(QIODevice::WriteOnly), msgCannotOpen(readOnlyFile).constData());
+ readOnlyFile.write("Hello");
+ readOnlyFile.close();
+ auto permissions = readOnlyFile.permissions();
+ permissions &= ~(QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteUser);
+ QVERIFY(readOnlyFile.setPermissions(permissions));
+ }
+
+ QSaveFile file(readOnlyName);
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+
+ file.setFileName(targetFile);
+ QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(file.commit());
+}
+
void tst_QSaveFile::saveTwice()
{
// Check that we can reuse a QSaveFile object