From f5630ee418461841ae490a361beec4f5a61d1f85 Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Tue, 18 Nov 2025 11:50:18 +0100 Subject: [PATCH 1/2] Fix canonicalPath for drives (c:) --- src/gui/folderman.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 87635ea767..5df99aa68f 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -546,7 +546,11 @@ QString FolderMan::trayTooltipStatusString( // parent directories. static QString canonicalPath(const QString &path) { - QFileInfo selFile(path); + if (path.isEmpty()) { + return path; + } + // QFile::canonicalFilePath for C: returns the current working dir 🤷‍♀️ + QFileInfo selFile(Utility::ensureTrailingSlash(path)); if (!selFile.exists()) { const auto parentPath = selFile.dir().path(); @@ -557,7 +561,7 @@ static QString canonicalPath(const QString &path) return path; } - return canonicalPath(parentPath) + QLatin1Char('/') + selFile.fileName(); + return canonicalPath(parentPath) + '/'_L1 + selFile.fileName(); } return selFile.canonicalFilePath(); } From 8087a68dd8dd903f056804a8d33298d0cd0839c9 Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Wed, 19 Nov 2025 14:57:52 +0100 Subject: [PATCH 2/2] wip --- src/gui/folderman.cpp | 50 +++++++++++++++++------------- src/libsync/propagateuploadtus.cpp | 2 -- test/testfolderman.cpp | 3 +- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 5df99aa68f..92a1e34a1b 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -421,7 +421,7 @@ Folder *FolderMan::folderForPath(const QString &path, QString *relativePath) for (auto *folder : std::as_const(_folders)) { const QString folderPath = folder->cleanPath() + QLatin1Char('/'); - if (absolutePath.startsWith(folderPath, (Utility::isWindows() || Utility::isMac()) ? Qt::CaseInsensitive : Qt::CaseSensitive)) { + if (FileSystem::isChildPathOf2(absolutePath, folderPath).testAnyFlag(FileSystem::ChildResult::IsChild)) { if (relativePath) { *relativePath = absolutePath.mid(folderPath.length()); relativePath->chop(1); // we added a '/' above @@ -541,29 +541,35 @@ QString FolderMan::trayTooltipStatusString( return folderMessage; } -// QFileInfo::canonicalPath returns an empty string if the file does not exist. +// canonicalPath returns an empty string if the file does not exist. // This function also works with files that does not exist and resolve the symlinks in the // parent directories. -static QString canonicalPath(const QString &path) -{ - if (path.isEmpty()) { - return path; - } - // QFile::canonicalFilePath for C: returns the current working dir 🤷‍♀️ - QFileInfo selFile(Utility::ensureTrailingSlash(path)); - if (!selFile.exists()) { - const auto parentPath = selFile.dir().path(); - - // It's possible for the parentPath to match the path - // (possibly we've arrived at a non-existant drive root on Windows) - // and recursing would be fatal. - if (parentPath == path) { - return path; +static std::filesystem::path canonicalPath(const std::filesystem::path &p) +{ + std::error_code ec; + if (!std::filesystem::exists(p, ec) && !ec) { + const auto parentPath = p.lexically_normal().parent_path(); + // last invocation will return / + if (parentPath == p) { + return p; } - return canonicalPath(parentPath) + '/'_L1 + selFile.fileName(); + return canonicalPath(parentPath) / p.filename(); + } + if (ec) { + qCWarning(lcFolderMan) << "Failed to check existence of path:" << p << ec.message(); + } + const auto out = std::filesystem::canonical(p, ec); + if (ec) { + qCWarning(lcFolderMan) << "Failed to canonicalize path:" << p << ec.message(); + return p; } - return selFile.canonicalFilePath(); + return out; +} + +static QString canonicalPath(const QString &p) +{ + return FileSystem::fromFilesystemPath(canonicalPath(FileSystem::toFilesystemPath(p))); } static QString checkPathForSyncRootMarkingRecursive(const QString &path, FolderMan::NewFolderType folderType, const QUuid &accountUuid) @@ -651,9 +657,9 @@ QString FolderMan::checkPathValidityForNewFolder(const QString &path, NewFolderT // check if the local directory isn't used yet in another sync const auto cs = Utility::fsCaseSensitivity(); - const QString userDir = QDir::cleanPath(canonicalPath(path)) + QLatin1Char('/'); + const QString userDir = canonicalPath(path) + QLatin1Char('/'); for (auto f : _folders) { - const QString folderDir = QDir::cleanPath(canonicalPath(f->path())) + QLatin1Char('/'); + const QString folderDir = canonicalPath(f->path()) + QLatin1Char('/'); if (QString::compare(folderDir, userDir, cs) == 0) { return tr("There is already a sync from the server to this local folder. " @@ -691,7 +697,7 @@ QString FolderMan::findGoodPathForNewSyncFolder( // possibly find a valid sync folder inside it. // Example: Someone syncs their home directory. Then ~/foobar is not // going to be an acceptable sync folder path for any value of foobar. - if (FolderMan::instance()->folderForPath(QFileInfo(normalisedPath).canonicalPath())) { + if (FolderMan::instance()->folderForPath(canonicalPath(normalisedPath))) { // Any path with that parent is going to be unacceptable, // so just keep it as-is. return canonicalPath(normalisedPath); diff --git a/src/libsync/propagateuploadtus.cpp b/src/libsync/propagateuploadtus.cpp index fc5b2f7c0a..cd22e24991 100644 --- a/src/libsync/propagateuploadtus.cpp +++ b/src/libsync/propagateuploadtus.cpp @@ -235,8 +235,6 @@ void PropagateUploadFileTUS::slotChunkFinished() propagator()->_anotherSyncNeeded = true; if (!_finished) { abortWithError(SyncFileItem::Message, fileChangedMessage()); - // FIXME: the legacy code was retrying for a few seconds. - // and also checking that after the last chunk, and removed the file in case of INSTRUCTION_NEW return; } } diff --git a/test/testfolderman.cpp b/test/testfolderman.cpp index a0ed19a51c..dd63093748 100644 --- a/test/testfolderman.cpp +++ b/test/testfolderman.cpp @@ -105,7 +105,8 @@ private Q_SLOTS: QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/OpenCloud1/some/sub/path"), type, uuid).isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/OpenCloud2/blublu"), type, uuid).isNull()); QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/OpenCloud1/folder/g/h"), type, uuid).isNull()); - QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3/folder/neu_folder"), type, uuid).isNull()); + qDebug() << folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3/folder/neu_folder"), type, uuid); + QCOMPARE_NE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3/folder/neu_folder"), type, uuid), QString()); // Subfolder of links QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link1/subfolder"), type, uuid).isNull());