This is an automated email from the ASF dual-hosted git repository.

chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new e7f08670 Reject out-of-range port in SplitHostAndPort (#3434)
e7f08670 is described below

commit e7f08670688617d51263e391b20d213e8d0af7f2
Author: UB <[email protected]>
AuthorDate: Mon Aug 24 13:36:57 2026 +0530

    Reject out-of-range port in SplitHostAndPort (#3434)
    
    * reject out-of-range port in SplitHostAndPort
    
    Signed-off-by: ubeddulla khan <[email protected]>
    
    * parse port forward and clamp to avoid accumulator wrap
    
    ---------
    
    Signed-off-by: ubeddulla khan <[email protected]>
---
 src/brpc/uri.cpp           | 19 +++++++++++++++----
 test/brpc_uri_unittest.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/brpc/uri.cpp b/src/brpc/uri.cpp
index cb48a43d..2881a8e5 100644
--- a/src/brpc/uri.cpp
+++ b/src/brpc/uri.cpp
@@ -82,13 +82,24 @@ static void ParseQueries(URI::QueryMap& query_map, const 
std::string &query) {
 inline const char* SplitHostAndPort(const char* host_begin,
                                     const char* host_end,
                                     int* port) {
-    uint64_t port_raw = 0;
-    uint64_t multiply = 1;
     for (const char* q = host_end - 1; q > host_begin; --q) {
         if (*q >= '0' && *q <= '9') {
-            port_raw += (*q - '0') * multiply;
-            multiply *= 10;
+            continue;
         } else if (*q == ':') {
+            // [q + 1, host_end) is all digits. Accumulate it forward and clamp
+            // to -1 as soon as it leaves the valid range, so an out-of-range
+            // port never narrows/wraps into a valid-looking wrong one (e.g.
+            // ":4294967377" truncating to 81, or a long run of digits
+            // overflowing the accumulator). This matches the 
port<0||port>65535
+            // rejection in str2endpoint/hostname2endpoint.
+            int64_t port_raw = 0;
+            for (const char* p = q + 1; p < host_end; ++p) {
+                port_raw = port_raw * 10 + (*p - '0');
+                if (port_raw > 65535) {
+                    port_raw = -1;
+                    break;
+                }
+            }
             *port = static_cast<int>(port_raw);
             return q;
         } else {
diff --git a/test/brpc_uri_unittest.cpp b/test/brpc_uri_unittest.cpp
index 14638b86..b9d6b650 100644
--- a/test/brpc_uri_unittest.cpp
+++ b/test/brpc_uri_unittest.cpp
@@ -89,6 +89,50 @@ TEST(URITest, only_host) {
     ASSERT_EQ(0u, uri.QueryCount());
 }
 
+TEST(URITest, out_of_range_port) {
+    brpc::URI uri;
+    // 4294967377 == 2^32 + 81. Without a range check the accumulated value
+    // narrows to int and yields 81, so port() must not return the wrapped 
port.
+    ASSERT_EQ(0, uri.SetHttpURL("foo://www.baidu.com:4294967377/s"));
+    ASSERT_EQ(-1, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+    ASSERT_EQ("/s", uri.path());
+
+    // Just above the valid range is rejected too.
+    ASSERT_EQ(0, uri.SetHttpURL("foo://www.baidu.com:65536/s"));
+    ASSERT_EQ(-1, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+
+    // A very long run of digits must not overflow the accumulator.
+    ASSERT_EQ(0, 
uri.SetHttpURL("foo://www.baidu.com:999999999999999999999999/s"));
+    ASSERT_EQ(-1, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+
+    // An out-of-range value padded with a long run of leading zeros must not
+    // wrap the accumulator into a valid-looking port either.
+    ASSERT_EQ(0, uri.SetHttpURL(
+            "foo://www.baidu.com:1000000000000000000000000000000000000"
+            "0000000000000000000000000000/s"));
+    ASSERT_EQ(-1, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+
+    // Leading zeros on an in-range value still parse to that value.
+    ASSERT_EQ(0, uri.SetHttpURL("foo://www.baidu.com:00080/s"));
+    ASSERT_EQ(80, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+
+    // Boundaries of the valid range still parse.
+    ASSERT_EQ(0, uri.SetHttpURL("foo://www.baidu.com:65535/s"));
+    ASSERT_EQ(65535, uri.port());
+    ASSERT_EQ(0, uri.SetHttpURL("foo://www.baidu.com:0/s"));
+    ASSERT_EQ(0, uri.port());
+
+    // Host header path goes through the same helper.
+    uri.SetHostAndPort("www.baidu.com:4294967377");
+    ASSERT_EQ(-1, uri.port());
+    ASSERT_EQ("www.baidu.com", uri.host());
+}
+
 TEST(URITest, no_scheme) {
     brpc::URI uri;
     ASSERT_EQ(0, uri.SetHttpURL(" 
user:[email protected]/s?wd=uri2&nonkey=22#frag "));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to