From 9346f151380f2ad720f5283a56a3f51de6c6ed5c Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 24 Oct 2023 14:09:08 -0400 Subject: [PATCH] src: use find instead of char-by-char in FromFilePath() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50288 Reviewed-By: Yagiz Nizipli Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: Tobias Nießen --- src/node_url.cc | 19 ++++++++++++++----- src/node_url.h | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/node_url.cc b/src/node_url.cc index 89fcfec20f5685..ccc148386e5a67 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -417,12 +417,21 @@ void BindingData::RegisterExternalReferences( } } -std::string FromFilePath(const std::string_view file_path) { - std::string escaped_file_path; - for (size_t i = 0; i < file_path.length(); ++i) { - escaped_file_path += file_path[i]; - if (file_path[i] == '%') escaped_file_path += "25"; +std::string FromFilePath(std::string_view file_path) { + // Avoid unnecessary allocations. + size_t pos = file_path.empty() ? std::string_view::npos : file_path.find('%'); + if (pos == std::string_view::npos) { + return ada::href_from_file(file_path); } + // Escape '%' characters to a temporary string. + std::string escaped_file_path; + do { + escaped_file_path += file_path.substr(0, pos + 1); + escaped_file_path += "25"; + file_path = file_path.substr(pos + 1); + pos = file_path.empty() ? std::string_view::npos : file_path.find('%'); + } while (pos != std::string_view::npos); + escaped_file_path += file_path; return ada::href_from_file(escaped_file_path); } diff --git a/src/node_url.h b/src/node_url.h index f3aa136a5b538d..ca59a375d1e2af 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -81,7 +81,7 @@ class BindingData : public SnapshotableObject { std::optional base); }; -std::string FromFilePath(const std::string_view file_path); +std::string FromFilePath(std::string_view file_path); } // namespace url