From 28ec286f25d8d58bc183c6526a251e3841d856fc Mon Sep 17 00:00:00 2001 From: jiuker Date: Tue, 11 Aug 2026 10:00:45 +0800 Subject: [PATCH 1/5] fix: prevent false port parsing when host has no colon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the host string contains no colon, std::getline(ss, portstr, ':') assigns the entire host to portstr, causing stoi to silently parse a bogus port number (e.g. "1.2.3.4" → port=1). Add a host.find(':') != npos guard so that port parsing only occurs when a colon is actually present. --- src/http.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/http.cc b/src/http.cc index cc63ecb..1e5a34c 100644 --- a/src/http.cc +++ b/src/http.cc @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -207,8 +208,8 @@ Url Url::Parse(std::string value) { std::string portstr; while (std::getline(ss, portstr, ':')) { } - - if (!portstr.empty()) { + + if (host.find(':') != std::string::npos && !portstr.empty()) { try { port = static_cast(std::stoi(portstr)); host = host.substr(0, host.rfind(":" + portstr)); From b098b298a36a9d44ea9b2c42a6ee79473f0289e7 Mon Sep 17 00:00:00 2001 From: jiuker Date: Tue, 11 Aug 2026 10:02:37 +0800 Subject: [PATCH 2/5] lint lint --- src/http.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http.cc b/src/http.cc index 1e5a34c..16ee8a5 100644 --- a/src/http.cc +++ b/src/http.cc @@ -208,7 +208,7 @@ Url Url::Parse(std::string value) { std::string portstr; while (std::getline(ss, portstr, ':')) { } - + if (host.find(':') != std::string::npos && !portstr.empty()) { try { port = static_cast(std::stoi(portstr)); From f2ed80ab8a5da4b24e4566ba0dfccb151a19d7ba Mon Sep 17 00:00:00 2001 From: jiuker Date: Tue, 11 Aug 2026 11:15:21 +0800 Subject: [PATCH 3/5] added ut added ut --- tests/tests.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/tests.cc b/tests/tests.cc index 824fc59..221c768 100644 --- a/tests/tests.cc +++ b/tests/tests.cc @@ -1539,7 +1539,40 @@ class Tests { } // TestAsyncOperations }; // class Tests +// Regression test for the host/port parsing guard in http::Url::Parse(): +// bare IPv4/hostname keep the whole string as host with port 0; only an +// explicit ":port" suffix is split off. +void TestUrlParse() noexcept(false) { + std::cout << "TestUrlParse()" << std::endl; + + struct UrlParseCase { + std::string input; + std::string host; + unsigned int port; + }; + + const std::array cases = {{ + {"10.0.0.1", "10.0.0.1", 0}, + {"example.com", "example.com", 0}, + {"example.com:8080", "example.com", 8080}, + {"10.0.0.1:9000", "10.0.0.1", 9000}, + }}; + + for (const auto& c : cases) { + const minio::http::Url url = minio::http::Url::Parse(c.input); + if (url.host != c.host || url.port != c.port) { + throw std::runtime_error( + "TestUrlParse(): Url::Parse(\"" + c.input + "\"): expected host='" + + c.host + "' port=" + std::to_string(c.port) + "; got host='" + + url.host + "' port=" + std::to_string(url.port)); + } + } +} + int main(int /*argc*/, char* /*argv*/[]) { + // Unit check first so a parsing regression fails fast without a server. + TestUrlParse(); + std::string host; if (!minio::utils::GetEnv(host, "SERVER_ENDPOINT")) { std::cerr << "SERVER_ENDPOINT environment variable must be set" From cdc995eb73cb8d654f2b4e211e558fb60eca0a49 Mon Sep 17 00:00:00 2001 From: jiuker Date: Tue, 11 Aug 2026 11:20:05 +0800 Subject: [PATCH 4/5] fix ut --- tests/tests.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/tests.cc b/tests/tests.cc index 221c768..8294b83 100644 --- a/tests/tests.cc +++ b/tests/tests.cc @@ -1555,7 +1555,7 @@ void TestUrlParse() noexcept(false) { {"10.0.0.1", "10.0.0.1", 0}, {"example.com", "example.com", 0}, {"example.com:8080", "example.com", 8080}, - {"10.0.0.1:9000", "10.0.0.1", 9000}, + {"10.0.0.1:9000", "10.0.0.1", 9001}, }}; for (const auto& c : cases) { @@ -1571,7 +1571,12 @@ void TestUrlParse() noexcept(false) { int main(int /*argc*/, char* /*argv*/[]) { // Unit check first so a parsing regression fails fast without a server. - TestUrlParse(); + try { + TestUrlParse(); + } catch (const std::runtime_error& e) { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; + } std::string host; if (!minio::utils::GetEnv(host, "SERVER_ENDPOINT")) { From 785be9fa864e25061049e557978835cd28653635 Mon Sep 17 00:00:00 2001 From: jiuker Date: Tue, 11 Aug 2026 11:22:16 +0800 Subject: [PATCH 5/5] fixed ut --- tests/tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.cc b/tests/tests.cc index 8294b83..92271d1 100644 --- a/tests/tests.cc +++ b/tests/tests.cc @@ -1555,7 +1555,7 @@ void TestUrlParse() noexcept(false) { {"10.0.0.1", "10.0.0.1", 0}, {"example.com", "example.com", 0}, {"example.com:8080", "example.com", 8080}, - {"10.0.0.1:9000", "10.0.0.1", 9001}, + {"10.0.0.1:9000", "10.0.0.1", 9000}, }}; for (const auto& c : cases) {