feat(client): 迁移Hub更新客户端实现
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
#include "UpdatePathPolicy.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
|
||||
namespace {
|
||||
|
||||
bool exactOrRuntimeMatch(const QString& folded, const QString& runtimePrefix,
|
||||
const QSet<QString>& exactPaths)
|
||||
{
|
||||
if (exactPaths.contains(folded))
|
||||
return true;
|
||||
if (runtimePrefix.isEmpty() || !folded.startsWith(runtimePrefix + QStringLiteral("/")))
|
||||
return false;
|
||||
return exactPaths.contains(folded.mid(runtimePrefix.size() + 1));
|
||||
}
|
||||
|
||||
bool prefixOrRuntimePrefixMatch(const QString& folded, const QString& runtimePrefix,
|
||||
const QString& prefix)
|
||||
{
|
||||
if (folded.startsWith(prefix))
|
||||
return true;
|
||||
if (runtimePrefix.isEmpty())
|
||||
return false;
|
||||
return folded.startsWith(runtimePrefix + QStringLiteral("/") + prefix);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace UpdatePathPolicy {
|
||||
|
||||
QString normalizeRelativePath(const QString& path)
|
||||
{
|
||||
QString normalized = QDir::cleanPath(QDir::fromNativeSeparators(path.trimmed()));
|
||||
if (normalized == QStringLiteral("."))
|
||||
return QString();
|
||||
while (normalized.startsWith(QStringLiteral("./")))
|
||||
normalized = normalized.mid(2);
|
||||
return normalized;
|
||||
}
|
||||
|
||||
bool isSafeRelativePath(const QString& path)
|
||||
{
|
||||
const QString clean = normalizeRelativePath(path);
|
||||
return !clean.isEmpty() && !QDir::isAbsolutePath(clean) && clean != QStringLiteral("..")
|
||||
&& !clean.startsWith(QStringLiteral("../")) && !clean.contains(QLatin1Char(':'));
|
||||
}
|
||||
|
||||
bool isUpdaterRuntimeProtectedPath(const QString& path, const QString& runtimeRelativePath)
|
||||
{
|
||||
const QString folded = normalizeRelativePath(path).toCaseFolded();
|
||||
const QString runtimePrefix = normalizeRelativePath(runtimeRelativePath).toCaseFolded();
|
||||
const QSet<QString> exactPaths{
|
||||
QStringLiteral("bootstrap"),
|
||||
QStringLiteral("bootstrap.exe"),
|
||||
QStringLiteral("launcher"),
|
||||
QStringLiteral("launcher.exe"),
|
||||
QStringLiteral("updater"),
|
||||
QStringLiteral("updater.exe"),
|
||||
QStringLiteral("client.ini"),
|
||||
QStringLiteral("config/app_config.json"),
|
||||
QStringLiteral("config/local_state.json"),
|
||||
QStringLiteral("config/client_identity.dat"),
|
||||
QStringLiteral("config/version_policy.dat")
|
||||
};
|
||||
if (exactOrRuntimeMatch(folded, runtimePrefix, exactPaths))
|
||||
return true;
|
||||
return prefixOrRuntimePrefixMatch(folded, runtimePrefix, QStringLiteral("update/"))
|
||||
|| prefixOrRuntimePrefixMatch(folded, runtimePrefix, QStringLiteral("update_temp/"));
|
||||
}
|
||||
|
||||
bool isIFWInstallerManagedPath(const QString& path)
|
||||
{
|
||||
const QString folded = normalizeRelativePath(path).toCaseFolded();
|
||||
if (folded.isEmpty())
|
||||
return false;
|
||||
|
||||
const bool rootFile = !folded.contains(QLatin1Char('/'));
|
||||
if (rootFile && (folded == QStringLiteral("maintenancetool")
|
||||
|| folded == QStringLiteral("maintenancetool.exe")
|
||||
|| folded.startsWith(QStringLiteral("maintenancetool.")))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const QSet<QString> exactPaths{
|
||||
QStringLiteral("components.xml"),
|
||||
QStringLiteral("components.xml.new"),
|
||||
QStringLiteral("components.xml.old"),
|
||||
QStringLiteral("installation.xml"),
|
||||
QStringLiteral("installation.dat"),
|
||||
QStringLiteral("installer.dat"),
|
||||
QStringLiteral("installer.ini"),
|
||||
QStringLiteral("network.xml"),
|
||||
QStringLiteral("repositories.xml"),
|
||||
QStringLiteral("repositories.cfg"),
|
||||
QStringLiteral("repository.xml")
|
||||
};
|
||||
if (exactPaths.contains(folded))
|
||||
return true;
|
||||
|
||||
const QStringList prefixes{
|
||||
QStringLiteral("installerresources/"),
|
||||
QStringLiteral("installationinformation/"),
|
||||
QStringLiteral("licenses/")
|
||||
};
|
||||
for (const QString& prefix : prefixes) {
|
||||
if (folded.startsWith(prefix))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFullUpdateProtectedPath(const QString& path, const QString& runtimeRelativePath)
|
||||
{
|
||||
return isUpdaterRuntimeProtectedPath(path, runtimeRelativePath)
|
||||
|| isIFWInstallerManagedPath(path);
|
||||
}
|
||||
|
||||
bool isExecutableOrLibrary(const QString& path)
|
||||
{
|
||||
const QString suffix = QFileInfo(path).suffix().toCaseFolded();
|
||||
return suffix == QStringLiteral("exe") || suffix == QStringLiteral("dll");
|
||||
}
|
||||
|
||||
} // namespace UpdatePathPolicy
|
||||
Reference in New Issue
Block a user