summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qsavefile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qsavefile.cpp')
-rw-r--r--src/corelib/io/qsavefile.cpp45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 3f45ca5f91..56934a9a0f 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -184,7 +184,8 @@ void QSaveFile::setFileName(const QString &name)
Important: the \a mode must include QIODevice::WriteOnly.
It may also have additional flags, such as QIODevice::Text and QIODevice::Unbuffered.
- QIODevice::ReadWrite and QIODevice::Append are not supported at the moment.
+ QIODevice::ReadWrite, QIODevice::Append, QIODevice::NewOnly and
+ QIODevice::ExistingOnly are not supported at the moment.
\sa QIODevice::OpenMode, setFileName()
*/
@@ -201,7 +202,8 @@ bool QSaveFile::open(OpenMode mode)
return false;
}
// In the future we could implement ReadWrite by copying from the existing file to the temp file...
- if ((mode & ReadOnly) || (mode & Append)) {
+ // The implications of NewOnly and ExistingOnly when used with QSaveFile need to be considered carefully...
+ if (mode & (ReadOnly | Append | NewOnly | ExistingOnly)) {
qWarning("QSaveFile::open: Unsupported open mode 0x%x", int(mode));
return false;
}
@@ -231,7 +233,38 @@ bool QSaveFile::open(OpenMode mode)
d->finalFileName = existingFile.filePath();
}
- d->fileEngine = new QTemporaryFileEngine;
+ 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
// to a third party
@@ -243,12 +276,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