diff --git a/lib/FsHelpers/FsHelpers.cpp b/lib/FsHelpers/FsHelpers.cpp index 1e3c68a6..6b315633 100644 --- a/lib/FsHelpers/FsHelpers.cpp +++ b/lib/FsHelpers/FsHelpers.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace FsHelpers { @@ -36,12 +37,14 @@ std::string decodeUriEscapes(const std::string& path) { } std::string normalisePath(const std::string& path) { - std::vector components; - std::string component; + std::vector components; + components.reserve(8); // Eight nested folders is more than we might expect - for (const auto c : path) { - if (c == '/') { - if (!component.empty()) { + size_t start = 0; + for (size_t i = 0; i <= path.length(); ++i) { + if (i == path.length() || path[i] == '/') { + if (i > start) { + std::string_view component(path.data() + start, i - start); if (component == "..") { if (!components.empty()) { components.pop_back(); @@ -49,23 +52,28 @@ std::string normalisePath(const std::string& path) { } else { components.push_back(component); } - component.clear(); } - } else { - component += c; + start = i + 1; } } - if (!component.empty()) { - components.push_back(component); + if (components.empty()) { + return ""; + } + + size_t total_len = 0; + for (const auto& c : components) { + total_len += c.length() + 1; } std::string result; - for (const auto& c : components) { - if (!result.empty()) { - result += "/"; + result.reserve(total_len - 1); + + for (size_t i = 0; i < components.size(); ++i) { + if (i > 0) { + result += '/'; } - result += c; + result.append(components[i].data(), components[i].length()); } return result;