diff options
Diffstat (limited to 'src/corelib/io/qsavefile.cpp')
-rw-r--r-- | src/corelib/io/qsavefile.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 3f7ce8d9e9..63f2284ef5 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -231,6 +231,37 @@ bool QSaveFile::open(OpenMode mode) d->finalFileName = existingFile.filePath(); } + auto openDirectly = [&]() { + d->fileEngine = QAbstractFileEngine::create(d->finalFileName); + if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { + d->useTemporaryFile = false; + QFileDevice::open(mode); + return true; + } + return false; + }; + +#ifdef Q_OS_WIN + // check if it is an Alternate Data Stream + if (d->finalFileName == d->fileName && d->fileName.indexOf(QLatin1Char(':'), 2) > 1) { + // yes, we can't rename onto it... + if (d->directWriteFallback) { + if (openDirectly()) + return true; + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); + delete d->fileEngine; + d->fileEngine = 0; + } else { + QString msg = + QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback " + "enabled: path contains an Alternate Data Stream specifier") + .arg(QDir::toNativeSeparators(d->fileName)); + d->setError(QFileDevice::OpenError, msg); + } + return false; + } +#endif + d->fileEngine = new QTemporaryFileEngine(&d->finalFileName); // if the target file exists, we'll copy its permissions below, // but until then, let's ensure the temporary file is not accessible @@ -243,12 +274,8 @@ bool QSaveFile::open(OpenMode mode) #ifdef Q_OS_UNIX if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) { delete d->fileEngine; - d->fileEngine = QAbstractFileEngine::create(d->finalFileName); - if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { - d->useTemporaryFile = false; - QFileDevice::open(mode); + if (openDirectly()) return true; - } err = d->fileEngine->error(); } #endif |