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>
This commit is contained in:
Friedemann Kleint 2019-07-11 13:35:45 +02:00
parent d01693733f
commit 54684f10e9
2 changed files with 35 additions and 0 deletions

View File

@ -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;

View File

@ -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