Ensure QTemporaryFile can create files when an identical dir exists.

When QTemporaryFile attempts to create a new file in
createFileFromTemplate, it fails if the filename exists and is a
directory. Windows returns error code 5 (ERROR_ACCESS_DENIED) in this
case - rather than ERROR_FILE_EXISTS - which is not handled.

This patch handles ERROR_ACCESS_DENIED in addition to the already
handled ERROR_FILE_EXISTS, meaning that QTemporaryFile will continue
to look for unique names when a directory with the same name exists.

Task-number: QTBUG-30058

Change-Id: I42339887d7f5483e3dc6a03a9da15111c350da8f
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
bb10
Mitch Curtis 2013-03-19 16:45:25 +01:00 committed by The Qt Project
parent 0450d81190
commit a3304489e8
2 changed files with 43 additions and 1 deletions

View File

@ -160,7 +160,14 @@ static bool createFileFromTemplate(NativeFileHandle &file,
return true;
DWORD err = GetLastError();
if (err != ERROR_FILE_EXISTS) {
if (err == ERROR_ACCESS_DENIED) {
DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
if (attributes == INVALID_FILE_ATTRIBUTES) {
// Potential write error (read-only parent directory, etc.).
error = QSystemError(err, QSystemError::NativeError);
return false;
} // else file already exists as a directory.
} else if (err != ERROR_FILE_EXISTS) {
error = QSystemError(err, QSystemError::NativeError);
return false;
}

View File

@ -92,6 +92,7 @@ private slots:
void createNativeFile();
void QTBUG_4796_data();
void QTBUG_4796();
void guaranteeUnique();
};
void tst_QTemporaryFile::initTestCase()
@ -782,5 +783,39 @@ void tst_QTemporaryFile::QTBUG_4796()
cleaner.reset();
}
void tst_QTemporaryFile::guaranteeUnique()
{
QDir dir(QDir::tempPath());
QString takenFileName;
// First pass. See which filename QTemporaryFile will try first.
{
// Fix the random seed.
qsrand(1135);
QTemporaryFile tmpFile("testFile1.XXXXXX");
tmpFile.open();
takenFileName = tmpFile.fileName();
QVERIFY(QFile::exists(takenFileName));
}
QVERIFY(!QFile::exists(takenFileName));
// Create a directory with same name.
QVERIFY(dir.mkdir(takenFileName));
// Second pass, now we have blocked its first attempt with a directory.
{
// Fix the random seed.
qsrand(1135);
QTemporaryFile tmpFile("testFile1.XXXXXX");
QVERIFY(tmpFile.open());
QString uniqueFileName = tmpFile.fileName();
QVERIFY(QFileInfo(uniqueFileName).isFile());
QVERIFY(uniqueFileName != takenFileName);
}
QVERIFY(dir.rmdir(takenFileName));
}
QTEST_MAIN(tst_QTemporaryFile)
#include "tst_qtemporaryfile.moc"