64 if (declaredPath.isEmpty() || directory.isEmpty()) {
68 const QDir dir(directory);
69 const bool wasAbsolute = QFileInfo(declaredPath).isAbsolute();
73 return QDir::cleanPath(declaredPath);
78 const QString resolved = wasAbsolute ? declaredPath : dir.absoluteFilePath(declaredPath);
80 const QString lexicalRoot = QDir::cleanPath(dir.absolutePath());
81 const QString canonicalRoot = QFileInfo(dir.absolutePath()).canonicalFilePath();
105 const auto canonicalise = [](
const QString& path) -> std::optional<QString> {
106 QString current = QDir::cleanPath(path);
111 const QString canonical = QFileInfo(current).canonicalFilePath();
112 if (!canonical.isEmpty()) {
113 if (tail.isEmpty()) {
118 return QDir::cleanPath(canonical + QLatin1Char(
'/') + tail.join(QLatin1Char(
'/')));
120 const QFileInfo info(current);
137 if (info.isSymLink()) {
140 const QString parent = info.absolutePath();
141 const QString name = info.fileName();
142 if (name.isEmpty() || parent.isEmpty() || parent == current) {
152 const bool useCanonical = !canonicalRoot.isEmpty();
155 const auto canonicalTarget = canonicalise(resolved);
156 if (!canonicalTarget) {
159 target = *canonicalTarget;
161 target = QDir::cleanPath(resolved);
163 const QString root = useCanonical ? canonicalRoot : lexicalRoot;
167 const QString prefix = root.endsWith(QLatin1Char(
'/')) ? root : root + QLatin1Char(
'/');
168 if (target == root || !target.startsWith(prefix)) {
173 return QDir::cleanPath(resolved);
std::optional< QString > resolveWithinDirectory(const QString &declaredPath, const QString &directory, AbsolutePathPolicy policy)
Resolve declaredPath against directory, refusing anything that lands outside it.
Definition PackPathGuard.h:61