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

wasphin 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 e6afa886e Fix grpc-status validation (#3669)
e6afa886e is described below

commit e6afa886e77dcd67e926d64b07f57d0293d2db88
Author: nkysg <[email protected]>
AuthorDate: Sun Nov 1 13:55:09 2026 +0800

    Fix grpc-status validation (#3669)
    
    * Fix grpc-status validation
    
    * Improve grpc-status parsing
    
    * Reject signed grpc-status values
---
 src/brpc/policy/http_rpc_protocol.cpp    | 19 ++++++++++++++++--
 test/brpc_http_rpc_protocol_unittest.cpp | 34 ++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/brpc/policy/http_rpc_protocol.cpp 
b/src/brpc/policy/http_rpc_protocol.cpp
index eb2ac11b6..dd9abf05d 100644
--- a/src/brpc/policy/http_rpc_protocol.cpp
+++ b/src/brpc/policy/http_rpc_protocol.cpp
@@ -25,6 +25,7 @@
 
 #include "butil/string_printf.h"
 #include "butil/string_splitter.h"                  // StringMultiSplitter
+#include "butil/strings/string_number_conversions.h"
 #include "butil/strings/string_util.h"
 #include "butil/sys_byteorder.h"
 #include "butil/time.h"
@@ -420,8 +421,22 @@ void ProcessHttpResponse(InputMessageBase* msg) {
             }
             const std::string* grpc_status = 
res_header->GetHeader(common->GRPC_STATUS);
             if (grpc_status) {
-                // TODO: More strict parsing
-                GrpcStatus status = (GrpcStatus)strtol(grpc_status->data(), 
nullptr, 10);
+                int code = 0;
+                bool valid = !grpc_status->empty();
+                for (char c : *grpc_status) {
+                    if (c < '0' || c > '9') {
+                        valid = false;
+                        break;
+                    }
+                }
+                if (!valid || !butil::StringToInt(*grpc_status, &code)) {
+                    cntl->SetFailed(ERESPONSE, "Invalid grpc-status header");
+                    break;
+                }
+                const GrpcStatus status =
+                    code >= GRPC_OK && code < GRPC_MAX
+                        ? static_cast<GrpcStatus>(code)
+                        : GRPC_UNKNOWN;
                 if (status != GRPC_OK) {
                     const std::string* grpc_message =
                         res_header->GetHeader(common->GRPC_MESSAGE);
diff --git a/test/brpc_http_rpc_protocol_unittest.cpp 
b/test/brpc_http_rpc_protocol_unittest.cpp
index c9ff7dfb9..af2b43e50 100644
--- a/test/brpc_http_rpc_protocol_unittest.cpp
+++ b/test/brpc_http_rpc_protocol_unittest.cpp
@@ -37,6 +37,7 @@
 #include <brpc/policy/http_rpc_protocol.h>
 #include <butil/base64.h>
 #include "brpc/http_method.h"
+#include "brpc/grpc.h"
 #include "butil/iobuf.h"
 #include "butil/logging.h"
 #include "butil/files/scoped_file.h"
@@ -637,6 +638,39 @@ TEST_F(HttpTest, process_request_wrong_method) {
     CheckResponseCode(false, brpc::HTTP_STATUS_NOT_FOUND);
 }
 
+TEST_F(HttpTest, grpc_response_status_validation) {
+    const std::string invalid[] = {
+        "", "invalid", "0junk", "+0", "-0", "-1", " 0", "0 ",
+        "4294967296",
+        "18446744073709551616", std::string(1000, '9'),
+        std::string("0\0junk", 6),
+    };
+    auto check = [this](const std::string& status, int expected_error) {
+        SCOPED_TRACE(status);
+        brpc::Controller cntl;
+        auto* msg = new brpc::policy::H2StreamContext(false);
+        msg->set_correlation_id(cntl.call_id().value);
+        msg->header().set_status_code(brpc::HTTP_STATUS_OK);
+        msg->header().set_content_type("application/grpc");
+        msg->header().SetHeader("grpc-status", status);
+        // gRPC prefix for an empty, uncompressed message.
+        const char prefix[5] = {};
+        msg->body().append(prefix, sizeof(prefix));
+        ProcessMessage(brpc::policy::ProcessHttpResponse, msg, false);
+        EXPECT_EQ(expected_error, cntl.ErrorCode()) << cntl.ErrorText();
+    };
+    for (const auto& status : invalid) {
+        check(status, brpc::ERESPONSE);
+    }
+    check("000", 0);
+    check("17", brpc::GrpcStatusToErrorCode(brpc::GRPC_UNKNOWN));
+    check("256", brpc::GrpcStatusToErrorCode(brpc::GRPC_UNKNOWN));
+    for (int code = brpc::GRPC_OK; code < brpc::GRPC_MAX; ++code) {
+        check(std::to_string(code),
+              
brpc::GrpcStatusToErrorCode(static_cast<brpc::GrpcStatus>(code)));
+    }
+}
+
 TEST_F(HttpTest, process_response_after_eof) {
     test::EchoResponse res;
     brpc::Controller cntl;


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

Reply via email to