CSYNC_FILE_EXCLUDE_HIDDEN,
CSYNC_FILE_EXCLUDE_STAT_FAILED,
CSYNC_FILE_EXCLUDE_CONFLICT,
- CSYNC_FILE_EXCLUDE_CANNOT_ENCODE
+ CSYNC_FILE_EXCLUDE_CANNOT_ENCODE,
+ CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED,
};
class ExcludedFilesTest;
return _capabilities[QStringLiteral("uploadConflictFiles")].toBool();
}
+QStringList Capabilities::blacklistedFiles() const
+{
+ return _capabilities["files"].toMap()["blacklisted_files"].toStringList();
+}
+
/*-------------------------------------------------------------------------------------*/
// Direct Editing
*/
QString invalidFilenameRegex() const;
+ /**
+ * return the list of filename that should not be uploaded
+ */
+ QStringList blacklistedFiles() const;
+
/**
* Whether conflict files should remain local (default) or should be uploaded.
*/
// local stat function.
// Recall file shall not be ignored (#4420)
bool isHidden = e.localEntry.isHidden || (f.first[0] == '.' && f.first != QLatin1String(".sys.admin#recall#"));
- if (handleExcluded(path._target, e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden, e.localEntry.isSymLink))
+ if (handleExcluded(path._target, e.localEntry.name,
+ e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden,
+ e.localEntry.isSymLink))
continue;
if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path._original)) {
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
}
-bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory, bool isHidden, bool isSymlink)
+bool ProcessDirectoryJob::handleExcluded(const QString &path, const QString &localName, bool isDirectory, bool isHidden, bool isSymlink)
{
auto excluded = _discoveryData->_excludes->traversalPatternMatch(path, isDirectory ? ItemTypeDirectory : ItemTypeFile);
if (excluded == CSYNC_NOT_EXCLUDED && _discoveryData->_ignoreHiddenFiles && isHidden) {
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
}
+ if (excluded == CSYNC_NOT_EXCLUDED && !localName.isEmpty()
+ && _discoveryData->_serverBlacklistedFiles.contains(localName)) {
+ excluded = CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED;
+ isInvalidPattern = true;
+ }
auto localCodec = QTextCodec::codecForLocale();
if (localCodec->mibEnum() != 106) {
case CSYNC_FILE_EXCLUDE_CANNOT_ENCODE:
item->_errorString = tr("The filename cannot be encoded on your file system.");
break;
+ case CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED:
+ item->_errorString = tr("The filename is blacklisted on the server.");
+ break;
}
}
*/
void process();
- // return true if the file is excluded
- bool handleExcluded(const QString &path, bool isDirectory, bool isHidden, bool isSymlink);
+ // return true if the file is excluded.
+ // path is the full relative path of the file. localName is the base name of the local entry.
+ bool handleExcluded(const QString &path, const QString &localName, bool isDirectory,
+ bool isHidden, bool isSymlink);
/** Reconcile local/remote/db information for a single item.
*
QStringList _selectiveSyncWhiteList;
ExcludedFiles *_excludes;
QRegExp _invalidFilenameRx; // FIXME: maybe move in ExcludedFiles
+ QStringList _serverBlacklistedFiles; // The blacklist from the capabilities
bool _ignoreHiddenFiles = false;
std::function<bool(const QString &)> _shouldDiscoverLocaly;
}
if (!invalidFilenamePattern.isEmpty())
_discoveryPhase->_invalidFilenameRx = QRegExp(invalidFilenamePattern);
+ _discoveryPhase->_serverBlacklistedFiles = _account->capabilities().blacklistedFiles();
_discoveryPhase->_ignoreHiddenFiles = ignoreHiddenFiles();
connect(_discoveryPhase.data(), &DiscoveryPhase::itemDiscovered, this, &SyncEngine::slotItemDiscovered);
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
}
+ // Tests the behavior of invalid filename detection
+ void testServerBlacklist()
+ {
+ FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() };
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+ fakeFolder.syncEngine().account()->setCapabilities({ { "files",
+ QVariantMap { { "blacklisted_files", QVariantList { ".foo", "bar" } } } } });
+ fakeFolder.localModifier().insert("C/.foo");
+ fakeFolder.localModifier().insert("C/bar");
+ fakeFolder.localModifier().insert("C/moo");
+ fakeFolder.localModifier().insert("C/.moo");
+ QVERIFY(fakeFolder.syncOnce());
+ QVERIFY(fakeFolder.currentRemoteState().find("C/moo"));
+ QVERIFY(fakeFolder.currentRemoteState().find("C/.moo"));
+ QVERIFY(!fakeFolder.currentRemoteState().find("C/.foo"));
+ QVERIFY(!fakeFolder.currentRemoteState().find("C/bar"));
+ }
};
QTEST_GUILESS_MAIN(TestLocalDiscovery)