QFileSystemEngine/Darwin: remove use of clonefile() on Apple systems

Because we called this before opening the target file, we did not check
that the destination file engine is the QFSFileEngine, and therefore we
may have passed a path that referred to a Qt resource path. We still do
that on Windows, but Qt resource paths start with a ':' character and
that is not allowed on Windows, so the Win32 CopyFile() function fails.

Moreover, this function *can* clone directory trees, which we don't want
to happen because it doesn't happen on other OSes. Instead, fall back to
the fcopyfile() call in cloneFile(). It will still do cloning where
permitted.

This was added in commit db0064b767474a89bc72ea4374f477682983c5f4,
before the fcopyfile() in 974b3adf8a099ca95fc2eabfc434038ce73f62c8,
though both were for Qt 5.10.

[ChangeLog][QtCore][QFile] Fixed a bug on Apple systems that would cause
copy() to copy a directory if the QFile pointed to a directory and the
destination was in the same volume. Now copy()'s behavior is the same as
in other OSes: directories are never copied.

[ChangeLog][QtCore][QFile] Fixed a bug on Apple systems that allowed
copy() to create a file with the name that referred to a Qt resource
path, if one tried to copy to that path. Qt resource paths can't be
modified using QFile.

Change-Id: I996368f4c656ff10ff5efffd5b47c6ddde34fd10
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 45886e6a81016c5c9212fffb5c0a83fd2431223e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2025-01-24 12:36:58 -08:00 committed by Qt Cherry-pick Bot
parent 8d791bfb30
commit c4eacb70fd

View File

@ -47,7 +47,6 @@
# include <UniformTypeIdentifiers/UTType.h>
# include <UniformTypeIdentifiers/UTCoreTypes.h>
# include <Foundation/Foundation.h>
# include <sys/clonefile.h>
# include <copyfile.h>
#endif
@ -1617,18 +1616,10 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source,
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
#if defined(Q_OS_DARWIN)
if (::clonefile(source.nativeFilePath().constData(),
target.nativeFilePath().constData(), 0) == 0)
return true;
error = QSystemError(errno, QSystemError::StandardLibraryError);
return false;
#else
Q_UNUSED(source);
Q_UNUSED(target);
error = QSystemError(ENOSYS, QSystemError::StandardLibraryError); //Function not implemented
return false;
#endif
}
//static