Skip to content

Commit

Permalink
Use std::filesystem::rename on non-Windows systems
Browse files Browse the repository at this point in the history
To prevent `QFile::rename` doing normalization changes to the file name.
  • Loading branch information
erikjv committed Feb 4, 2025
1 parent b9ae92a commit f638c9f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
23 changes: 5 additions & 18 deletions src/common/filesystembase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,28 +209,15 @@ bool FileSystem::uncheckedRenameReplace(const QString &originFileName,
QString *errorString)
{
Q_ASSERT(errorString);

#ifndef Q_OS_WIN
bool success;
QFile orig(originFileName);
// We want a rename that also overwrites. QFile::rename does not overwrite.
// Qt 5.1 has QSaveFile::renameOverwrite we could use.
// ### FIXME
success = true;
bool destExists = fileExists(destinationFileName);
if (destExists && !QFile::remove(destinationFileName)) {
*errorString = orig.errorString();
qCWarning(lcFileSystem) << "Target file could not be removed.";
success = false;
}
if (success) {
success = orig.rename(destinationFileName);
}
if (!success) {
*errorString = orig.errorString();
std::error_code err;
std::filesystem::rename(originFileName.toStdString(), destinationFileName.toStdString(), err);
if (err) {
*errorString = QString::fromStdString(err.message());
qCWarning(lcFileSystem) << "Renaming temp file to final failed: " << *errorString;
return false;
}

#else //Q_OS_WIN
// You can not overwrite a read-only file on windows.

Expand Down
37 changes: 37 additions & 0 deletions test/testfilesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,43 @@ private Q_SLOTS:
}
csync_vio_local_closedir(dh);
}

void testRename_data()
{
QTest::addColumn<QString>("name");

const unsigned char a_umlaut_composed_bytes[] = {0xc3, 0xa4, 0x00};
const QString a_umlaut_composed = QString::fromUtf8(reinterpret_cast<const char *>(a_umlaut_composed_bytes));
const QString a_umlaut_decomposed = a_umlaut_composed.normalized(QString::NormalizationForm_D);

QTest::newRow("a-umlaut composed") << a_umlaut_composed;
QTest::newRow("a-umlaut decomposed") << a_umlaut_decomposed;
}

// This is not a full test, it is meant to verify that no nomalization changes are done.
void testRename()
{
QFETCH(QString, name);

auto tmp = OCC::TestUtils::createTempDir();
QFile f(tmp.path() + u"/abc");
QVERIFY(f.open(QFile::WriteOnly));
QByteArray data("abc");
QCOMPARE(f.write(data), data.size());
f.close();

QString err;
QVERIFY(OCC::FileSystem::uncheckedRenameReplace(f.fileName(), tmp.path() + u'/' + name, &err));

csync_file_stat_t buf;
auto dh = csync_vio_local_opendir(tmp.path());
QVERIFY(dh);
while (auto fs = csync_vio_local_readdir(dh, nullptr)) {
QCOMPARE(fs->path, name);
QCOMPARE(fs->type, ItemTypeFile);
}
csync_vio_local_closedir(dh);
}
};

QTEST_GUILESS_MAIN(TestFileSystem)
Expand Down

0 comments on commit f638c9f

Please sign in to comment.