From 40eea118074e3c86c0373a00536af8a8c3c8557e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 19 Jan 2025 11:28:26 -0800 Subject: [PATCH] QFile/Unix: ensure the destination of copy() is empty before cloneFile() This is potentially a bug in the !QT_CONFIG(temporaryfile) case in which we wouldn't truncate the file after we had copied it. Change-Id: Ieea7fb3ca9981e555140fffd2300fcebcdd800b5 Reviewed-by: Ivan Solovev --- src/corelib/io/qfile.cpp | 2 +- src/corelib/io/qfilesystemengine_unix.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 3a15b4ac7f6..dcb6f5ce4e0 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -819,7 +819,7 @@ QFile::copy(const QString &newName) const auto fileTemplate = "%1/qt_temp.XXXXXX"_L1; #if !QT_CONFIG(temporaryfile) QFile out(fileTemplate.arg(QFileInfo(newName).path())); - if (!out.open(QIODevice::ReadWrite)) + if (!out.open(QIODevice::ReadWrite | QIODevice::Truncate)) error = true; #else QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path())); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index ec962eba365..d19631b9310 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1084,6 +1084,12 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat return false; } + [[maybe_unused]] auto destinationIsEmpty = [dstfd]() { + QT_STATBUF statBuffer; + return QT_FSTAT(dstfd, &statBuffer) == 0 && statBuffer.st_size == 0; + }; + Q_ASSERT(destinationIsEmpty()); + #if defined(Q_OS_LINUX) // first, try FICLONE (only works on regular files and only on certain fs) if (::ioctl(dstfd, FICLONE, srcfd) == 0)