Skip to content

Commit

Permalink
Fix SourcePath::resolveSymlinks()
Browse files Browse the repository at this point in the history
This fixes handling of symlinks that start with '..', and symlink
targets that contain symlinks themselves.
  • Loading branch information
edolstra committed Jun 5, 2023
1 parent 9c6ede8 commit 2151be5
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/libfetchers/input-accessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,28 @@ SourcePath SourcePath::resolveSymlinks() const

int linksAllowed = 1024;

for (auto & component : path) {
res.path.push(component);
while (true) {
if (auto st = res.maybeLstat()) {
std::list<std::string> todo;
for (auto & c : path)
todo.push_back(std::string(c));

while (!todo.empty()) {
auto c = *todo.begin();
todo.pop_front();
if (c == "" || c == ".")
;
else if (c == "..")
res.path.pop();
else {
res.path.push(c);
if (auto st = res.maybeLstat(); st && st->type == InputAccessor::tSymlink) {
if (!linksAllowed--)
throw Error("infinite symlink recursion in path '%s'", path);
if (st->type != InputAccessor::tSymlink) break;
auto target = res.readLink();
res.path.pop();
if (hasPrefix(target, "/"))
res = CanonPath(target);
else {
res.path.pop();
res.path.extend(CanonPath(target));
}
} else
break;
res.path = CanonPath::root;
todo.splice(todo.begin(), tokenizeString<std::list<std::string>>(target, "/"));
}
}
}

Expand Down

0 comments on commit 2151be5

Please sign in to comment.