Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions src/gui/folderman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -541,25 +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)
{
QFileInfo selFile(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) + QLatin1Char('/') + 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)
Expand Down Expand Up @@ -647,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. "
Expand Down Expand Up @@ -687,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);
Expand Down
2 changes: 0 additions & 2 deletions src/libsync/propagateuploadtus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion test/testfolderman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Loading