AK: Fix .. handling in FileSystemPath

We shouldn't just drop leading ..-s for relative paths. At the same time,
we should handle paths like

    ../foo/../../bar

correctly: the first .. after the foo cancels out the foo, but the second
one should get treated as a leading one and not get dropped.

Note that since this path resolution is purely lexical, it's never going to be
completely correct with respect to symlinks and other filesystem magic. Better
don't use it when dealing with files.
This commit is contained in:
Sergey Bugaev 2020-05-22 20:50:01 +03:00 committed by Andreas Kling
parent 75f587d3df
commit a3e4dfdf98
Notes: sideshowbarker 2024-07-19 06:14:44 +09:00

View file

@ -48,22 +48,26 @@ void FileSystemPath::canonicalize()
m_is_absolute = m_string[0] == '/';
auto parts = m_string.split_view('/');
if (!m_is_absolute)
parts.prepend(".");
size_t approximate_canonical_length = 0;
Vector<String> canonical_parts;
for (size_t i = 0; i < parts.size(); ++i) {
auto& part = parts[i];
if (m_is_absolute || i != 0) {
if (part == ".")
continue;
}
if (part == "..") {
if (!canonical_parts.is_empty())
canonical_parts.take_last();
if (part == ".")
continue;
if (part == "..") {
if (canonical_parts.is_empty()) {
if (m_is_absolute) {
// At the root, .. does nothing.
continue;
}
} else {
if (canonical_parts.last() != "..") {
// A .. and a previous non-.. part cancel each other.
canonical_parts.take_last();
continue;
}
}
}
if (!part.is_empty()) {
approximate_canonical_length += part.length() + 1;