@@ -421,7 +421,7 @@ Folder *FolderMan::folderForPath(const QString &path, QString *relativePath)
421421 for (auto *folder : std::as_const (_folders)) {
422422 const QString folderPath = folder->cleanPath () + QLatin1Char (' /' );
423423
424- if (absolutePath. startsWith (folderPath, ( Utility::isWindows () || Utility::isMac ()) ? Qt::CaseInsensitive : Qt::CaseSensitive )) {
424+ if (FileSystem::isChildPathOf2 (absolutePath, folderPath). testAnyFlag (FileSystem::ChildResult::IsChild )) {
425425 if (relativePath) {
426426 *relativePath = absolutePath.mid (folderPath.length ());
427427 relativePath->chop (1 ); // we added a '/' above
@@ -541,25 +541,36 @@ QString FolderMan::trayTooltipStatusString(
541541 return folderMessage;
542542}
543543
544- // QFileInfo:: canonicalPath returns an empty string if the file does not exist.
544+ // canonicalPath returns an empty string if the file does not exist.
545545// This function also works with files that does not exist and resolve the symlinks in the
546546// parent directories.
547- static QString canonicalPath (const QString &path)
548- {
549- QFileInfo selFile (path);
550- if (!selFile.exists ()) {
551- const auto parentPath = selFile.dir ().path ();
552-
553- // It's possible for the parentPath to match the path
554- // (possibly we've arrived at a non-existant drive root on Windows)
555- // and recursing would be fatal.
556- if (parentPath == path) {
557- return path;
547+ static std::filesystem::path canonicalPath (const std::filesystem::path &p)
548+ {
549+ std::error_code ec;
550+ if (!std::filesystem::exists (p, ec) && !ec) {
551+ const auto parentPath = p.lexically_normal ().parent_path ();
552+ // last invocation will return /
553+ if (parentPath == p) {
554+ return p;
558555 }
559556
560- return canonicalPath (parentPath) + QLatin1Char (' /' ) + selFile.fileName ();
557+ return canonicalPath (parentPath) / p.filename ();
558+ }
559+ if (ec) {
560+ qCWarning (lcFolderMan) << " Failed to check existence of path:" << p << ec.message ();
561561 }
562- return selFile.canonicalFilePath ();
562+ const auto out = std::filesystem::canonical (p, ec);
563+ if (ec) {
564+ qCWarning (lcFolderMan) << " Failed to canonicalize path:" << p << ec.message ();
565+ return p;
566+ }
567+ return out;
568+ }
569+
570+ static QString canonicalPath (const QString &p)
571+ {
572+ // clean path to normalize path back to Qt form
573+ return QDir::cleanPath (FileSystem::fromFilesystemPath (canonicalPath (FileSystem::toFilesystemPath (p))));
563574}
564575
565576static QString checkPathForSyncRootMarkingRecursive (const QString &path, FolderMan::NewFolderType folderType, const QUuid &accountUuid)
@@ -645,17 +656,18 @@ QString FolderMan::checkPathValidityRecursive(const QString &path, FolderMan::Ne
645656QString FolderMan::checkPathValidityForNewFolder (const QString &path, NewFolderType folderType, const QUuid &accountUuid) const
646657{
647658 // check if the local directory isn't used yet in another sync
648- const auto cs = Utility::fsCaseSensitivity ();
649-
650- const QString userDir = QDir::cleanPath (canonicalPath (path)) + QLatin1Char (' /' );
659+ if (path.isEmpty ()) {
660+ return u" Passingg an empty path is not supported" _s;
661+ }
662+ const QString userDir = canonicalPath (path) + QLatin1Char (' /' );
651663 for (auto f : _folders) {
652- const QString folderDir = QDir::cleanPath ( canonicalPath (f->path () )) + QLatin1Char (' /' );
664+ const QString folderDir = canonicalPath (f->path ()) + QLatin1Char (' /' );
653665
654- if (QString::compare (folderDir, userDir, cs) == 0 ) {
666+ const auto isChild = FileSystem::isChildPathOf2 (folderDir, userDir);
667+ if (isChild.testFlag (FileSystem::ChildResult::IsEqual)) {
655668 return tr (" There is already a sync from the server to this local folder. "
656669 " Please pick another local folder!" );
657- }
658- if (FileSystem::isChildPathOf (folderDir, userDir)) {
670+ } else if (isChild.testFlag (FileSystem::ChildResult::IsChild)) {
659671 return tr (" The local folder »%1« already contains a folder used in a folder sync connection. "
660672 " Please pick another local folder!" )
661673 .arg (QDir::toNativeSeparators (path));
@@ -681,13 +693,15 @@ QString FolderMan::findGoodPathForNewSyncFolder(
681693 OC_ASSERT (!accountUuid.isNull () || folderType == FolderMan::NewFolderType::SpacesSyncRoot);
682694
683695 // reserve extra characters to allow appending of a number
684- const QString normalisedPath = FileSystem::createPortableFileName (basePath, FileSystem::pathEscape ( newFolder) , std::string_view (" (100)" ).size ());
696+ const QString normalisedPath = FileSystem::createPortableFileName (basePath, newFolder, std::string_view (" (100)" ).size ());
685697
686698 // If the parent folder is a sync folder or contained in one, we can't
687699 // possibly find a valid sync folder inside it.
688700 // Example: Someone syncs their home directory. Then ~/foobar is not
689701 // going to be an acceptable sync folder path for any value of foobar.
690- if (FolderMan::instance ()->folderForPath (QFileInfo (normalisedPath).canonicalPath ())) {
702+ // If relativePath is empty, the path is equal to newFolder, and we will find a name in the following loop
703+ QString relativePath;
704+ if (FolderMan::instance ()->folderForPath (canonicalPath (normalisedPath), &relativePath) && !relativePath.isEmpty ()) {
691705 // Any path with that parent is going to be unacceptable,
692706 // so just keep it as-is.
693707 return canonicalPath (normalisedPath);
0 commit comments