diff options
author | Sergey Bugaev <bugaevc@serenityos.org> | 2020-05-22 20:50:01 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-22 23:55:35 +0200 |
commit | a3e4dfdf9859a9b955bf4728328f740a47de5851 (patch) | |
tree | 408582feb0f96ede21df0126b4c8e572d6b0e247 /AK | |
parent | 75f587d3dffd268a21aa5f24e462642b99f4fd44 (diff) | |
download | serenity-a3e4dfdf9859a9b955bf4728328f740a47de5851.zip |
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.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/FileSystemPath.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/AK/FileSystemPath.cpp b/AK/FileSystemPath.cpp index ef0e824d7b..21bb5fd3b3 100644 --- a/AK/FileSystemPath.cpp +++ b/AK/FileSystemPath.cpp @@ -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; |