summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-07-12 18:41:35 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-08-09 05:19:23 +0000
commit9312ec54dbf8031f4d23c6fc400c1ca27e3f9d1f (patch)
tree09e4443fd5b5762ab1499404d9598c13fe7fc465 /src/corelib
parent284fff12172095a899303d9b4fc06c7bf502c93d (diff)
Fix QAbstractFileEngine::clone misuse
QFile::copy was assuming that the target file was native and therefore it could simply take the file descriptor to clone. While that was not currently a problem, in theory it could be as we do have one writeable file engine besides QFSFileEngine (QWinRTFileEngine). By refactoring to take the parameter as a QAbstractFileEngine, we can ensure that the target file is a native file. Change-Id: Ib7a1737987bf4c4a8c51fffd14d0c048fd509025 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qabstractfileengine.cpp9
-rw-r--r--src/corelib/io/qabstractfileengine_p.h2
-rw-r--r--src/corelib/io/qfile.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_p.h2
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp9
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp6
6 files changed, 18 insertions, 12 deletions
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index 1163234b62..f2a895bbb8 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -864,13 +864,14 @@ bool QAbstractFileEngine::unmap(uchar *address)
/*!
\since 5.10
- Copies the contents from the file specified by \a sourceHandle to this file
- by cloning it.
+ Duplicates the contents of this file (starting from the current position)
+ to the file specified by the engine \a target.
+
Returns \c true on success; otherwise, \c false is returned.
*/
-bool QAbstractFileEngine::clone(int sourceHandle)
+bool QAbstractFileEngine::cloneTo(QAbstractFileEngine *target)
{
- Q_UNUSED(sourceHandle);
+ Q_UNUSED(target);
return false;
}
diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h
index c3f7619268..00c415b521 100644
--- a/src/corelib/io/qabstractfileengine_p.h
+++ b/src/corelib/io/qabstractfileengine_p.h
@@ -150,7 +150,7 @@ public:
virtual QDateTime fileTime(FileTime time) const;
virtual void setFileName(const QString &file);
virtual int handle() const;
- virtual bool clone(int sourceHandle);
+ virtual bool cloneTo(QAbstractFileEngine *target);
bool atEnd() const;
uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
bool unmap(uchar *ptr);
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 5b487a1339..d32c2ed9fd 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -804,7 +804,7 @@ QFile::copy(const QString &newName)
close();
d->setError(QFile::CopyError, tr("Cannot open for output"));
} else {
- if (!out.d_func()->engine()->clone(d->engine()->handle())) {
+ if (!d->engine()->cloneTo(out.d_func()->engine())) {
char block[4096];
qint64 totalRead = 0;
while (!atEnd()) {
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index f352fcd475..1f34dfc2be 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -110,7 +110,7 @@ public:
qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
qint64 readLine(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
- bool clone(int sourceHandle) override;
+ bool cloneTo(QAbstractFileEngine *target) override;
bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) Q_DECL_OVERRIDE;
bool supportsExtension(Extension extension) const Q_DECL_OVERRIDE;
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index bb9b3dc87a..83091ca808 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -735,16 +735,19 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
/*!
\reimp
*/
-bool QFSFileEngine::clone(int sourceHandle)
+bool QFSFileEngine::cloneTo(QAbstractFileEngine *target)
{
+ if ((target->fileFlags(LocalDiskFlag) & LocalDiskFlag) == 0)
+ return false;
#if defined(Q_OS_LINUX)
Q_D(QFSFileEngine);
# if !defined FICLONE
# define FICLONE _IOW (0x94, 9, int)
# endif
- return ::ioctl(d->fd, FICLONE, sourceHandle) == 0;
+ int srcfd = d->nativeHandle();
+ int dstfd = target->handle();
+ return ::ioctl(dstfd, FICLONE, srcfd) == 0;
#else
- Q_UNUSED(sourceHandle);
return false;
#endif
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 97fefe8927..759effe632 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1032,9 +1032,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
/*!
\reimp
*/
-bool QFSFileEngine::clone(int sourceHandle)
+bool QFSFileEngine::cloneTo(QAbstractFileEngine *target)
{
- Q_UNUSED(sourceHandle);
+ // There's some Windows Server 2016 API, but we won't
+ // bother with it.
+ Q_UNUSED(target);
return false;
}