128 lines
4.2 KiB
C++
128 lines
4.2 KiB
C++
#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
|