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 <ivan.solovev@qt.io>
This commit is contained in:
Thiago Macieira 2025-01-19 11:28:26 -08:00
parent 8a720c162d
commit 40eea11807
2 changed files with 7 additions and 1 deletions

View File

@ -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()));

View File

@ -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)