From 15e592192773ea547d9f18f05cb357bc12d2befc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Dec 2025 13:45:21 -0500 Subject: [PATCH] use std::from_chars in UrlDecode --- libi2pd/HTTP.cpp | 31 +++++++++++++++++++++---------- libi2pd/HTTP.h | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 8c7c8491..178ff797 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -536,21 +536,32 @@ namespace http return ptr; } - std::string UrlDecode(std::string_view data, bool allow_null) + std::string UrlDecode(std::string_view url, bool allow_null) { - std::string decoded(data); - size_t pos = 0; - while ((pos = decoded.find('%', pos)) != std::string::npos) + std::string decoded; + decoded.reserve (url.length ()); + size_t start = 0; + for (size_t i = 0; i < url.length (); i++) { - char c = std::stol(decoded.substr(pos + 1, 2), nullptr, 16); - if (!c && !allow_null) + auto c = url[i]; + if (c == '%') { - pos += 3; - continue; + decoded.append (url, start, i - start); + if (i + 2 <= url.length ()) + { + char ch; + auto res = std::from_chars(url.data() + i + 1, url.data() + i + 3, ch, 16); + if (res.ec == std::errc()) + decoded += ch; + i += 2; + start = i + 1; + } + else + break; } - decoded.replace(pos, 3, 1, c); - pos++; } + if (start < url.length ()) + decoded.append (url, start); return decoded; } diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index c65c1ce4..0055211b 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -160,7 +160,7 @@ namespace http * @param null If set to true - decode also %00 sequence, otherwise - skip * @return Decoded string */ - std::string UrlDecode(std::string_view data, bool null = false); + std::string UrlDecode(std::string_view url, bool null = false); /** * @brief Merge HTTP response content with Transfer-Encoding: chunked