From cca605c044d56d722689abd94abc2b02e6cb732b Mon Sep 17 00:00:00 2001 From: PobreGato <315121269+pobregat0@users.noreply.github.com> Date: Sun, 1 Nov 2026 18:52:32 -0500 Subject: [PATCH] Fix IPv6 host parsing when URL has no port or path --- libi2pd/HTTP.cpp | 5 +++-- tests/test-http-url.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index e97c6cfa..a5337b0a 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -135,9 +135,10 @@ namespace http /* hostname[:port][/path] */ if (pos_p >= url.length ()) return false; /* nothing left after schema or user part */ + std::size_t pos_b = std::string::npos; // position of ']' for ipv6 host if (url.at(pos_p) == '[') // ipv6 { - auto pos_b = url.find(']', pos_p); + pos_b = url.find(']', pos_p); if (pos_b == std::string::npos) return false; ipv6 = true; pos_c = url.find_first_of(":/", pos_b); @@ -148,7 +149,7 @@ namespace http if (pos_c == std::string::npos) { /* only hostname, without post and path */ host = ipv6 ? - url.substr(pos_p + 1, url.length() - 1) : + url.substr(pos_p + 1, pos_b - pos_p - 1) : url.substr(pos_p, std::string::npos); return true; } else if (url.at(pos_c) == ':') { diff --git a/tests/test-http-url.cpp b/tests/test-http-url.cpp index 061c83ce..d8bbff29 100644 --- a/tests/test-http-url.cpp +++ b/tests/test-http-url.cpp @@ -125,6 +125,17 @@ int main() { assert(url->frag == "frag"); delete url; + /* ipv6 host without port or path: must not capture the closing ']' */ + url = new URL; + assert(url->parse("http://[2001:db8::1]") == true); + assert(url->schema == "http"); + assert(url->ipv6 == true); + assert(url->host == "2001:db8::1"); + assert(url->port == 0); + assert(url->path == ""); + assert(url->to_string() == "http://[2001:db8::1]"); + delete url; + /* nothing after the schema or the user part: must not throw */ url = new URL; assert(url->parse("http://") == false);