From: Christian Kamm Date: Fri, 25 Jan 2019 06:46:16 +0000 (+0100) Subject: Folder: Add remoteFolderTrailingSlash() X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~304 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0eb406519735c2bc3825a2d7c4c617578669bc7e;p=nextcloud-desktop.git Folder: Add remoteFolderTrailingSlash() There were cases where the "/" exception wasn't handled correctly and there'd be extra slashes in generated paths. --- diff --git a/src/common/vfs.h b/src/common/vfs.h index 179f0174d..c57e9349f 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -37,9 +37,16 @@ class SyncFileItem; /** Collection of parameters for initializing a Vfs instance. */ struct OCSYNC_EXPORT VfsSetupParams { - /// The full path to the folder on the local filesystem + /** The full path to the folder on the local filesystem + * + * Always ends with /. + */ QString filesystemPath; - /// The path to the synced folder on the account + + /** The path to the synced folder on the account + * + * Always ends with /. + */ QString remotePath; /// Account url, credentials etc for network calls diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 8674068e3..9828a495c 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -256,6 +256,14 @@ QString Folder::remotePath() const return _definition.targetPath; } +QString Folder::remotePathTrailingSlash() const +{ + QString result = remotePath(); + if (!result.endsWith('/')) + result.append('/'); + return result; +} + QUrl Folder::remoteUrl() const { return Utility::concatUrlPath(_accountState->account()->davUrl(), remotePath()); @@ -476,7 +484,7 @@ void Folder::startVfs() VfsSetupParams vfsParams; vfsParams.filesystemPath = path(); - vfsParams.remotePath = remotePath(); + vfsParams.remotePath = remotePathTrailingSlash(); vfsParams.account = _accountState->account(); vfsParams.journal = &_journal; vfsParams.providerName = Theme::instance()->appNameGUI(); @@ -1303,7 +1311,7 @@ bool FolderDefinition::load(QSettings &settings, const QString &alias, } // Old settings can contain paths with native separators. In the rest of the - // code we assum /, so clean it up now. + // code we assume /, so clean it up now. folder->localPath = prepareLocalPath(folder->localPath); // Target paths also have a convention diff --git a/src/gui/folder.h b/src/gui/folder.h index 4a3c544a2..75fe0b2c5 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -51,11 +51,11 @@ class FolderDefinition public: /// The name of the folder in the ui and internally QString alias; - /// path on local machine + /// path on local machine (always trailing /) QString localPath; /// path to the journal, usually relative to localPath QString journalPath; - /// path on remote + /// path on remote (usually no trailing /, exception "/") QString targetPath; /// whether the folder is paused bool paused = false; @@ -88,7 +88,7 @@ public: /// Ensure / as separator and trailing /. static QString prepareLocalPath(const QString &path); - /// Ensure starting / and no ending /. + /// Remove ending /, then ensure starting '/': so "/foo/bar" and "/". static QString prepareTargetPath(const QString &path); /// journalPath relative to localPath. @@ -146,10 +146,15 @@ public: QString cleanPath() const; /** - * remote folder path + * remote folder path, usually without trailing /, exception "/" */ QString remotePath() const; + /** + * remote folder path, always with a trailing / + */ + QString remotePathTrailingSlash() const; + void setNavigationPaneClsid(const QUuid &clsid) { _definition.navigationPaneClsid = clsid; } QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; } diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 79be36c3e..b690a86d4 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -1091,16 +1091,20 @@ QStringList FolderMan::findFileInLocalFolders(const QString &relPath, const Acco { QStringList re; + // We'll be comparing against Folder::remotePath which always starts with / + QString serverPath = relPath; + if (!serverPath.startsWith('/')) + serverPath.prepend('/'); + for (Folder *folder : this->map().values()) { if (acc && folder->accountState()->account() != acc) { continue; } - QString path = folder->cleanPath(); - QString remRelPath; - // cut off the remote path from the server path. - remRelPath = relPath.mid(folder->remotePath().length()); - path += "/"; - path += remRelPath; + if (!serverPath.startsWith(folder->remotePath())) + continue; + + QString path = folder->cleanPath() + '/'; + path += serverPath.midRef(folder->remotePathTrailingSlash().length()); if (QFile::exists(path)) { re.append(path); } diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index af010f99a..45678d0a6 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -570,11 +570,8 @@ void FolderStatusModel::fetchMore(const QModelIndex &parent) if (!info || info->_fetched || info->_fetchingJob) return; info->resetSubs(this, parent); - QString path = info->_folder->remotePath(); + QString path = info->_folder->remotePathTrailingSlash(); if (info->_path != QLatin1String("/")) { - if (!path.endsWith(QLatin1Char('/'))) { - path += QLatin1Char('/'); - } path += info->_path; } diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index 32cfc7b61..ab109316e 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -449,13 +449,10 @@ bool FolderWizardRemotePath::isComplete() const if (f->accountState()->account() != _account) { continue; } - QString curDir = f->remotePath(); - if (!curDir.startsWith(QLatin1Char('/'))) { - curDir.prepend(QLatin1Char('/')); - } + QString curDir = f->remotePathTrailingSlash(); if (QDir::cleanPath(dir) == QDir::cleanPath(curDir)) { warnStrings.append(tr("This folder is already being synced.")); - } else if (dir.startsWith(curDir + QLatin1Char('/'))) { + } else if (dir.startsWith(curDir)) { warnStrings.append(tr("You are already syncing %1, which is a parent folder of %2.").arg(Utility::escape(curDir), Utility::escape(dir))); } } diff --git a/src/gui/sharemanager.cpp b/src/gui/sharemanager.cpp index 87df91350..ed1eea9cc 100644 --- a/src/gui/sharemanager.cpp +++ b/src/gui/sharemanager.cpp @@ -37,9 +37,7 @@ static void updateFolder(const AccountPtr &account, const QString &path) if (path.startsWith(folderPath) && (path == folderPath || folderPath.endsWith('/') || path[folderPath.size()] == '/')) { // Workaround the fact that the server does not invalidate the etags of parent directories // when something is shared. - auto relative = path.midRef(folderPath.size()); - if (relative.startsWith('/')) - relative = relative.mid(1); + auto relative = path.midRef(f->remotePathTrailingSlash().length()); f->journalDb()->avoidReadFromDbOnNextSync(relative.toString()); // Schedule a sync so it can update the remote permission flag and let the socket API diff --git a/test/syncenginetestutils.h b/test/syncenginetestutils.h index f3663f8ba..66f9717f6 100644 --- a/test/syncenginetestutils.h +++ b/test/syncenginetestutils.h @@ -947,7 +947,7 @@ public: OCC::VfsSetupParams vfsParams; vfsParams.filesystemPath = localPath(); - vfsParams.remotePath = ""; + vfsParams.remotePath = "/"; vfsParams.account = _account; vfsParams.journal = _journalDb.get(); vfsParams.providerName = "OC-TEST";