From: Olivier Goffart Date: Thu, 26 Nov 2020 15:22:50 +0000 (+0100) Subject: Exclude: do everything with QString wiuthout converting to char* X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~421 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3c3619f99af1b9b3bc3f43ad585eb69c34003f7e;p=nextcloud-desktop.git Exclude: do everything with QString wiuthout converting to char* --- diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index 2398d10dd..c21b1e00c 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -93,9 +93,9 @@ static const char *win_reserved_words_n[] = { "CLOCK$", "$Recycle.Bin" }; * @param file_name filename * @return true if file is reserved, false otherwise */ -bool csync_is_windows_reserved_word(const char *filename) +bool csync_is_windows_reserved_word(const QStringRef &filename) { - size_t len_filename = strlen(filename); + size_t len_filename = filename.size(); // Drive letters if (len_filename == 2 && filename[1] == ':') { @@ -109,7 +109,7 @@ bool csync_is_windows_reserved_word(const char *filename) if (len_filename == 3 || (len_filename > 3 && filename[3] == '.')) { for (const char *word : win_reserved_words_3) { - if (c_strncasecmp(filename, word, 3) == 0) { + if (filename.left(3).compare(QLatin1String(word), Qt::CaseInsensitive) == 0) { return true; } } @@ -117,15 +117,14 @@ bool csync_is_windows_reserved_word(const char *filename) if (len_filename == 4 || (len_filename > 4 && filename[4] == '.')) { for (const char *word : win_reserved_words_4) { - if (c_strncasecmp(filename, word, 4) == 0) { + if (filename.left(4).compare(QLatin1String(word), Qt::CaseInsensitive) == 0) { return true; } } } for (const char *word : win_reserved_words_n) { - size_t len_word = strlen(word); - if (len_word == len_filename && c_strncasecmp(filename, word, len_word) == 0) { + if (filename.compare(QLatin1String(word), Qt::CaseInsensitive) == 0) { return true; } } @@ -133,43 +132,30 @@ bool csync_is_windows_reserved_word(const char *filename) return false; } -static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path, bool excludeConflictFiles) +static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const QString &path, bool excludeConflictFiles) { - const char *bname = nullptr; - size_t blen = 0; int rc = -1; CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED; /* split up the path */ - bname = strrchr(path, '/'); - if (bname) { - bname += 1; // don't include the / - } else { - bname = path; + QStringRef bname(&path); + int lastSlash = path.lastIndexOf('/'); + if (lastSlash >= 0) { + bname = path.midRef(lastSlash + 1); } - blen = strlen(bname); + size_t blen = bname.size(); // 9 = strlen(".sync_.db") if (blen >= 9 && bname[0] == '.') { - rc = csync_fnmatch("._sync_*.db*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - goto out; - } - rc = csync_fnmatch(".sync_*.db*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - goto out; - } - rc = csync_fnmatch(".csync_journal.db*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - goto out; + if (bname.contains(QLatin1String(".db"))) { + if (bname.startsWith(QLatin1String("._sync_"), Qt::CaseInsensitive) // "._sync_*.db*" + || bname.startsWith(QLatin1String(".sync_"), Qt::CaseInsensitive) // ".sync_*.db*" + || bname.startsWith(QLatin1String(".csync_journal.db"), Qt::CaseInsensitive)) { // ".csync_journal.db*" + return CSYNC_FILE_SILENTLY_EXCLUDED; + } } - rc = csync_fnmatch(".owncloudsync.log*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - goto out; + if (bname.startsWith(QLatin1String(".owncloudsync.log"), Qt::CaseInsensitive)) { // ".owncloudsync.log*" + return CSYNC_FILE_SILENTLY_EXCLUDED; } } @@ -201,8 +187,8 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path, bool excludeC } // Filter out characters not allowed in a filename on windows - for (const char *p = path; *p; p++) { - switch (*p) { + for (auto p : path) { + switch (p.unicode()) { case '\\': case ':': case '?': @@ -221,14 +207,14 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const char *path, bool excludeC /* We create a Desktop.ini on Windows for the sidebar icon, make sure we don't sync it. */ if (blen == 11 && path == bname) { - rc = csync_fnmatch("Desktop.ini", bname, 0); + rc = bname.compare(QLatin1String("Desktop.ini"), Qt::CaseInsensitive); if (rc == 0) { match = CSYNC_FILE_SILENTLY_EXCLUDED; goto out; } } - if (excludeConflictFiles && OCC::Utility::isConflictFile(bname)) { + if (excludeConflictFiles && OCC::Utility::isConflictFile(path)) { match = CSYNC_FILE_EXCLUDE_CONFLICT; goto out; } @@ -439,10 +425,10 @@ bool ExcludedFiles::isExcluded( relativePath.chop(1); } - return fullPatternMatch(relativePath.toUtf8(), type) != CSYNC_NOT_EXCLUDED; + return fullPatternMatch(relativePath, type) != CSYNC_NOT_EXCLUDED; } -CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemType filetype) +CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const QString &path, ItemType filetype) { auto match = _csync_excluded_common(path, _excludeConflictFiles); if (match != CSYNC_NOT_EXCLUDED) @@ -463,16 +449,13 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy // Check the bname part of the path to see whether the full // regex should be run. - - const char *bname = strrchr(path, '/'); - if (bname) { - bname += 1; // don't include the / - } else { - bname = path; + QStringRef bnameStr(&path); + int lastSlash = path.lastIndexOf('/'); + if (lastSlash >= 0) { + bnameStr = path.midRef(lastSlash + 1); } - QString bnameStr = QString::fromUtf8(bname); - QByteArray basePath(_localPath.toUtf8() + path); + QByteArray basePath(_localPath.toUtf8() + path.toUtf8()); while (basePath.size() > _localPath.size()) { basePath = leftIncludeLast(basePath, '/'); QRegularExpressionMatch m; @@ -496,17 +479,16 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy } // third capture: full path matching is triggered - QString pathStr = QString::fromUtf8(path); - basePath = _localPath.toUtf8() + path; + basePath = _localPath.toUtf8() + path.toUtf8(); while (basePath.size() > _localPath.size()) { basePath = leftIncludeLast(basePath, '/'); QRegularExpressionMatch m; if (filetype == ItemTypeDirectory && _fullTraversalRegexDir.contains(basePath)) { - m = _fullTraversalRegexDir[basePath].match(pathStr); + m = _fullTraversalRegexDir[basePath].match(path); } else if (filetype == ItemTypeFile && _fullTraversalRegexFile.contains(basePath)) { - m = _fullTraversalRegexFile[basePath].match(pathStr); + m = _fullTraversalRegexFile[basePath].match(path); } else { continue; } @@ -522,21 +504,21 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const char *path, ItemTy return CSYNC_NOT_EXCLUDED; } -CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const char *path, ItemType filetype) const +CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const QString &p, ItemType filetype) const { - auto match = _csync_excluded_common(path, _excludeConflictFiles); + auto match = _csync_excluded_common(p, _excludeConflictFiles); if (match != CSYNC_NOT_EXCLUDED) return match; if (_allExcludes.isEmpty()) return CSYNC_NOT_EXCLUDED; - QString p = QString::fromUtf8(path); // `path` seems to always be relative to `_localPath`, the tests however have not been // written that way... this makes the tests happy for now. TODO Fix the tests at some point + QString path = p; if (path[0] == '/') - ++path; + path = path.mid(1); - QByteArray basePath(_localPath.toUtf8() + path); + QByteArray basePath(_localPath.toUtf8() + path.toUtf8()); while (basePath.size() > _localPath.size()) { basePath = leftIncludeLast(basePath, '/'); QRegularExpressionMatch m; diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index 10eb65e36..4f68a5d0b 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -137,7 +137,7 @@ public: * Note that this only matches patterns. It does not check whether the file * or directory pointed to is hidden (or whether it even exists). */ - CSYNC_EXCLUDE_TYPE traversalPatternMatch(const char *path, ItemType filetype); + CSYNC_EXCLUDE_TYPE traversalPatternMatch(const QString &path, ItemType filetype); public slots: /** @@ -175,7 +175,7 @@ private: * Note that this only matches patterns. It does not check whether the file * or directory pointed to is hidden (or whether it even exists). */ - CSYNC_EXCLUDE_TYPE fullPatternMatch(const char *path, ItemType filetype) const; + CSYNC_EXCLUDE_TYPE fullPatternMatch(const QString &path, ItemType filetype) const; // Our BasePath need to end with '/' class BasePathByteArray : public QByteArray diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp index 47b96068f..b6a689fcd 100644 --- a/src/libsync/capabilities.cpp +++ b/src/libsync/capabilities.cpp @@ -195,7 +195,7 @@ QList Capabilities::httpErrorCodesThatResetFailingChunkedUploads() const QString Capabilities::invalidFilenameRegex() const { - return _capabilities["dav"].toMap()["invalidFilenameRegex"].toString(); + return _capabilities[QStringLiteral("dav")].toMap()[QStringLiteral("invalidFilenameRegex")].toString(); } bool Capabilities::uploadConflictFiles() const @@ -205,7 +205,7 @@ bool Capabilities::uploadConflictFiles() const if (envIsSet) return envValue != 0; - return _capabilities["uploadConflictFiles"].toBool(); + return _capabilities[QStringLiteral("uploadConflictFiles")].toBool(); } /*-------------------------------------------------------------------------------------*/ diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 4abb07cb7..79560e785 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -155,8 +155,7 @@ void ProcessDirectoryJob::process() bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory, bool isHidden, bool isSymlink) { - // FIXME! call directly, without char* conversion - auto excluded = _discoveryData->_excludes->traversalPatternMatch(path.toUtf8(), isDirectory ? ItemTypeDirectory : ItemTypeFile); + auto excluded = _discoveryData->_excludes->traversalPatternMatch(path, isDirectory ? ItemTypeDirectory : ItemTypeFile); // FIXME: move to ExcludedFiles 's regexp ? bool isInvalidPattern = false; diff --git a/test/csync/csync_tests/check_csync_exclude.cpp b/test/csync/csync_tests/check_csync_exclude.cpp index 61f7283e2..c4d9a91d9 100644 --- a/test/csync/csync_tests/check_csync_exclude.cpp +++ b/test/csync/csync_tests/check_csync_exclude.cpp @@ -583,6 +583,11 @@ static void check_csync_bname_trigger(void **) static void check_csync_is_windows_reserved_word(void **) { + auto csync_is_windows_reserved_word = [](const char *fn) { + QString s = QString::fromLatin1(fn); + return ::csync_is_windows_reserved_word(&s); + }; + assert_true(csync_is_windows_reserved_word("CON")); assert_true(csync_is_windows_reserved_word("con")); assert_true(csync_is_windows_reserved_word("CON."));