Excludes: switch all the path handling to QString
authorKevin Ottens <kevin.ottens@nextcloud.com>
Thu, 26 Nov 2020 15:55:04 +0000 (16:55 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:20 +0000 (10:58 +0100)
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/csync/csync_exclude.cpp
src/csync/csync_exclude.h
test/csync/csync_tests/check_csync_exclude.cpp

index 3a752b06987b03bbdfd35c613dda567f675ac6ef..b443c3bc48d1444ab59fe7953d435be83368e6e1 100644 (file)
@@ -223,7 +223,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const QString &path, bool exclu
     return match;
 }
 
-static QByteArray leftIncludeLast(const QByteArray & arr, char c)
+static QString leftIncludeLast(const QString &arr, char c)
 {
     // left up to and including `c`
     return arr.left(arr.lastIndexOf(c, arr.size() - 2) + 1);
@@ -231,8 +231,8 @@ static QByteArray leftIncludeLast(const QByteArray & arr, char c)
 
 using namespace OCC;
 
-ExcludedFiles::ExcludedFiles(QString localPath)
-    : _localPath(std::move(localPath))
+ExcludedFiles::ExcludedFiles(const QString &localPath)
+    : _localPath(localPath)
     , _clientVersion(MIRALL_VERSION_MAJOR, MIRALL_VERSION_MINOR, MIRALL_VERSION_PATCH)
 {
     Q_ASSERT(_localPath.endsWith("/"));
@@ -253,12 +253,12 @@ ExcludedFiles::~ExcludedFiles() = default;
 
 void ExcludedFiles::addExcludeFilePath(const QString &path)
 {
-    _excludeFiles[_localPath.toUtf8()].append(path);
+    _excludeFiles[_localPath].append(path);
 }
 
 void ExcludedFiles::addInTreeExcludeFilePath(const QString &path)
 {
-    BasePathByteArray basePath = leftIncludeLast(path.toUtf8(), '/');
+    BasePathString basePath = leftIncludeLast(path, '/');
     _excludeFiles[basePath].append(path);
 }
 
@@ -267,12 +267,12 @@ void ExcludedFiles::setExcludeConflictFiles(bool onoff)
     _excludeConflictFiles = onoff;
 }
 
-void ExcludedFiles::addManualExclude(const QByteArray &expr)
+void ExcludedFiles::addManualExclude(const QString &expr)
 {
-    addManualExclude(expr, _localPath.toUtf8());
+    addManualExclude(expr, _localPath);
 }
 
-void ExcludedFiles::addManualExclude(const QByteArray &expr, const QByteArray &basePath)
+void ExcludedFiles::addManualExclude(const QString &expr, const QString &basePath)
 {
 #if defined(Q_OS_WIN)
     Q_ASSERT(basePath.size() >= 2 && basePath.at(1) == ':');
@@ -304,13 +304,13 @@ void ExcludedFiles::setClientVersion(ExcludedFiles::Version version)
     _clientVersion = version;
 }
 
-bool ExcludedFiles::loadExcludeFile(const QByteArray & basePath, const QString & file)
+bool ExcludedFiles::loadExcludeFile(const QString &basePath, const QString & file)
 {
     QFile f(file);
     if (!f.open(QIODevice::ReadOnly))
         return false;
 
-    QList<QByteArray> patterns;
+    QStringList patterns;
     while (!f.atEnd()) {
         QByteArray line = f.readLine().trimmed();
         if (line.startsWith("#!version")) {
@@ -320,7 +320,7 @@ bool ExcludedFiles::loadExcludeFile(const QByteArray & basePath, const QString &
         if (line.isEmpty() || line.startsWith('#'))
             continue;
         csync_exclude_expand_escapes(line);
-        patterns.append(line);
+        patterns.append(QString::fromUtf8(line));
     }
     _allExcludes.insert(basePath, patterns);
 
@@ -437,7 +437,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const QString &path, Ite
 
     // Directories are guaranteed to be visited before their files
     if (filetype == ItemTypeDirectory) {
-        const auto basePath = QString(_localPath + path + QLatin1Char('/')).toUtf8();
+        const auto basePath = QString(_localPath + path + QLatin1Char('/'));
         const auto fi = QFileInfo(basePath + QStringLiteral(".sync-exclude.lst"));
 
         if (fi.isReadable()) {
@@ -454,7 +454,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const QString &path, Ite
         bnameStr = path.midRef(lastSlash + 1);
     }
 
-    QByteArray basePath(_localPath.toUtf8() + path.toUtf8());
+    QString basePath(_localPath + path);
     while (basePath.size() > _localPath.size()) {
         basePath = leftIncludeLast(basePath, '/');
         QRegularExpressionMatch m;
@@ -478,7 +478,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const QString &path, Ite
     }
 
     // third capture: full path matching is triggered
-    basePath = _localPath.toUtf8() + path.toUtf8();
+    basePath = _localPath + path;
     while (basePath.size() > _localPath.size()) {
         basePath = leftIncludeLast(basePath, '/');
         QRegularExpressionMatch m;
@@ -517,7 +517,7 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(const QString &p, ItemType fi
     if (path[0] == '/')
         path = path.mid(1);
 
-    QByteArray basePath(_localPath.toUtf8() + path.toUtf8());
+    QString basePath(_localPath + path);
     while (basePath.size() > _localPath.size()) {
         basePath = leftIncludeLast(basePath, '/');
         QRegularExpressionMatch m;
@@ -689,7 +689,7 @@ void ExcludedFiles::prepare()
         prepare(basePath);
 }
 
-void ExcludedFiles::prepare(const BasePathByteArray & basePath)
+void ExcludedFiles::prepare(const BasePathString & basePath)
 {
     Q_ASSERT(_allExcludes.contains(basePath));
 
@@ -765,7 +765,7 @@ void ExcludedFiles::prepare(const BasePathByteArray & basePath)
             // Make exclude relative to _localPath
             exclude.prepend(relPath);
         }
-        auto regexExclude = convertToRegexpSyntax(QString::fromUtf8(exclude), _wildcardsMatchSlash);
+        auto regexExclude = convertToRegexpSyntax(exclude, _wildcardsMatchSlash);
         if (!fullPath) {
             regexAppend(bnameFileDir, bnameDir, regexExclude, matchDirOnly);
         } else {
index 4f68a5d0bf3d4911980da970bb3e5015e2a20f58..5de60eb26aeb410af7587de04d19b08641110c63 100644 (file)
@@ -67,7 +67,7 @@ class OCSYNC_EXPORT ExcludedFiles : public QObject
 public:
     typedef std::tuple<int, int, int> Version;
 
-    ExcludedFiles(QString localPath = "/");
+    explicit ExcludedFiles(const QString &localPath = QStringLiteral("/"));
     ~ExcludedFiles();
 
     /**
@@ -102,8 +102,8 @@ public:
      * Primarily used in tests. Patterns added this way are preserved when
      * reloadExcludeFiles() is called.
      */
-    void addManualExclude(const QByteArray &expr);
-    void addManualExclude(const QByteArray &expr, const QByteArray &basePath);
+    void addManualExclude(const QString &expr);
+    void addManualExclude(const QString &expr, const QString &basePath);
 
     /**
      * Removes all manually added exclude patterns.
@@ -147,7 +147,7 @@ public slots:
     /**
      * Loads the exclude patterns from file the registered base paths.
      */
-    bool loadExcludeFile(const QByteArray & basePath, const QString & file);
+    bool loadExcludeFile(const QString &basePath, const QString &file);
 
 private:
     /**
@@ -178,24 +178,19 @@ private:
     CSYNC_EXCLUDE_TYPE fullPatternMatch(const QString &path, ItemType filetype) const;
 
     // Our BasePath need to end with '/'
-    class BasePathByteArray : public QByteArray
+    class BasePathString : public QString
     {
     public:
-        BasePathByteArray(QByteArray && other)
-            : QByteArray(std::move(other))
+        BasePathString(QString &&other)
+            : QString(std::move(other))
         {
-            Q_ASSERT(this->endsWith('/'));
+            Q_ASSERT(endsWith('/'));
         }
 
-        BasePathByteArray(const QByteArray & other)
-            : QByteArray(other)
-        {
-            Q_ASSERT(this->endsWith('/'));
-        }
-
-        BasePathByteArray(const char * data, int size = -1)
-            : BasePathByteArray(QByteArray(data, size))
+        BasePathString(const QString &other)
+            : QString(other)
         {
+            Q_ASSERT(endsWith('/'));
         }
     };
 
@@ -228,28 +223,28 @@ private:
      * full matcher would exclude. Example: "b" is excluded. traversal("b/c")
      * returns not-excluded because "c" isn't a bname activation pattern.
      */
-    void prepare(const BasePathByteArray & basePath);
+    void prepare(const BasePathString &basePath);
 
     void prepare();
 
 
     QString _localPath;
     /// Files to load excludes from
-    QMap<BasePathByteArray, QList<QString>> _excludeFiles;
+    QMap<BasePathString, QStringList> _excludeFiles;
 
     /// Exclude patterns added with addManualExclude()
-    QMap<BasePathByteArray, QList<QByteArray>> _manualExcludes;
+    QMap<BasePathString, QStringList> _manualExcludes;
 
     /// List of all active exclude patterns
-    QMap<BasePathByteArray, QList<QByteArray>> _allExcludes;
+    QMap<BasePathString, QStringList> _allExcludes;
 
     /// see prepare()
-    QMap<BasePathByteArray, QRegularExpression> _bnameTraversalRegexFile;
-    QMap<BasePathByteArray, QRegularExpression> _bnameTraversalRegexDir;
-    QMap<BasePathByteArray, QRegularExpression> _fullTraversalRegexFile;
-    QMap<BasePathByteArray, QRegularExpression> _fullTraversalRegexDir;
-    QMap<BasePathByteArray, QRegularExpression> _fullRegexFile;
-    QMap<BasePathByteArray, QRegularExpression> _fullRegexDir;
+    QMap<BasePathString, QRegularExpression> _bnameTraversalRegexFile;
+    QMap<BasePathString, QRegularExpression> _bnameTraversalRegexDir;
+    QMap<BasePathString, QRegularExpression> _fullTraversalRegexFile;
+    QMap<BasePathString, QRegularExpression> _fullTraversalRegexDir;
+    QMap<BasePathString, QRegularExpression> _fullRegexFile;
+    QMap<BasePathString, QRegularExpression> _fullRegexDir;
 
     bool _excludeConflictFiles = true;
 
index c4d9a91d9a2fdff889fade5d148e0113210b26ff..a8268449c6e95f764dbcf6c8067de32fc9088c5f 100644 (file)
@@ -100,16 +100,16 @@ static void check_csync_exclude_add(void **)
     excludedFiles->addManualExclude("/tmp/check_csync1/*");
     assert_int_equal(check_file_full("/tmp/check_csync1/foo"), CSYNC_FILE_EXCLUDE_LIST);
     assert_int_equal(check_file_full("/tmp/check_csync2/foo"), CSYNC_NOT_EXCLUDED);
-    assert_true(excludedFiles->_allExcludes["/"].contains("/tmp/check_csync1/*"));
+    assert_true(excludedFiles->_allExcludes[QStringLiteral("/")].contains("/tmp/check_csync1/*"));
 
-    assert_true(excludedFiles->_fullRegexFile["/"].pattern().contains("csync1"));
-    assert_true(excludedFiles->_fullTraversalRegexFile["/"].pattern().contains("csync1"));
-    assert_false(excludedFiles->_bnameTraversalRegexFile["/"].pattern().contains("csync1"));
+    assert_true(excludedFiles->_fullRegexFile[QStringLiteral("/")].pattern().contains("csync1"));
+    assert_true(excludedFiles->_fullTraversalRegexFile[QStringLiteral("/")].pattern().contains("csync1"));
+    assert_false(excludedFiles->_bnameTraversalRegexFile[QStringLiteral("/")].pattern().contains("csync1"));
 
     excludedFiles->addManualExclude("foo");
-    assert_true(excludedFiles->_bnameTraversalRegexFile["/"].pattern().contains("foo"));
-    assert_true(excludedFiles->_fullRegexFile["/"].pattern().contains("foo"));
-    assert_false(excludedFiles->_fullTraversalRegexFile["/"].pattern().contains("foo"));
+    assert_true(excludedFiles->_bnameTraversalRegexFile[QStringLiteral("/")].pattern().contains("foo"));
+    assert_true(excludedFiles->_fullRegexFile[QStringLiteral("/")].pattern().contains("foo"));
+    assert_false(excludedFiles->_fullTraversalRegexFile[QStringLiteral("/")].pattern().contains("foo"));
 }
 
 static void check_csync_exclude_add_per_dir(void **)
@@ -117,15 +117,15 @@ static void check_csync_exclude_add_per_dir(void **)
     excludedFiles->addManualExclude("*", "/tmp/check_csync1/");
     assert_int_equal(check_file_full("/tmp/check_csync1/foo"), CSYNC_FILE_EXCLUDE_LIST);
     assert_int_equal(check_file_full("/tmp/check_csync2/foo"), CSYNC_NOT_EXCLUDED);
-    assert_true(excludedFiles->_allExcludes["/tmp/check_csync1/"].contains("*"));
+    assert_true(excludedFiles->_allExcludes[QStringLiteral("/tmp/check_csync1/")].contains("*"));
 
     excludedFiles->addManualExclude("foo");
-    assert_true(excludedFiles->_fullRegexFile["/"].pattern().contains("foo"));
+    assert_true(excludedFiles->_fullRegexFile[QStringLiteral("/")].pattern().contains("foo"));
 
     excludedFiles->addManualExclude("foo/bar", "/tmp/check_csync1/");
-    assert_true(excludedFiles->_fullRegexFile["/tmp/check_csync1/"].pattern().contains("bar"));
-    assert_true(excludedFiles->_fullTraversalRegexFile["/tmp/check_csync1/"].pattern().contains("bar"));
-    assert_false(excludedFiles->_bnameTraversalRegexFile["/tmp/check_csync1/"].pattern().contains("foo"));
+    assert_true(excludedFiles->_fullRegexFile[QStringLiteral("/tmp/check_csync1/")].pattern().contains("bar"));
+    assert_true(excludedFiles->_fullTraversalRegexFile[QStringLiteral("/tmp/check_csync1/")].pattern().contains("bar"));
+    assert_false(excludedFiles->_bnameTraversalRegexFile[QStringLiteral("/tmp/check_csync1/")].pattern().contains("foo"));
 }
 
 static void check_csync_excluded(void **)