Skip to content

Commit 8283c2a

Browse files
author
ivan-skryabin
committed
feat grpc: enforce move semantics in stream Write
Removed lvalue Write overloads in grpc-proto-structs to prevent unsafe usage patterns where modified objects could be reused after writes. This addresses potential bugs when middlewares mutate objects commit_hash:29b87e821f6a9e64cd810a8fd2ea056eee57756c
1 parent 47285b4 commit 8283c2a

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

libraries/grpc-proto-structs/include/userver/grpc-proto-structs/client/stream.hpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,26 +72,30 @@ class Writer final {
7272
Writer(Writer&&) = default;
7373
Writer& operator=(Writer&&) = default;
7474

75-
/// @brief Write the next outgoing message
76-
[[nodiscard]] bool Write(const StructsRequest& request) {
77-
return writer_.Write(proto_structs::StructToMessage(request));
78-
}
79-
80-
/// @brief Write the next outgoing message
75+
/// @brief Write the next outgoing message.
76+
/// @note This version may move some fields from the request.
8177
[[nodiscard]] bool Write(StructsRequest&& request) {
8278
return writer_.Write(proto_structs::StructToMessage(std::move(request)));
8379
}
8480

85-
/// @brief Write the next outgoing message and check result
86-
void WriteAndCheck(const StructsRequest& request) {
87-
writer_.WriteAndCheck(proto_structs::StructToMessage(request));
81+
/// @brief Write the next outgoing message.
82+
/// @note This version preserves the original request object by copying necessary data.
83+
[[nodiscard]] bool WriteCopy(const StructsRequest& request) {
84+
return writer_.Write(proto_structs::StructToMessage(request));
8885
}
8986

90-
/// @brief Write the next outgoing message and check result
87+
/// @brief Write the next outgoing message and check result.
88+
/// @note This version may move some fields from the request.
9189
void WriteAndCheck(StructsRequest&& request) {
9290
writer_.WriteAndCheck(proto_structs::StructToMessage(std::move(request)));
9391
}
9492

93+
/// @brief Write the next outgoing message and check result.
94+
/// @note This version preserves the original request object by copying necessary data.
95+
void WriteCopyAndCheck(const StructsRequest& request) {
96+
writer_.WriteAndCheck(proto_structs::StructToMessage(request));
97+
}
98+
9599
/// @brief Complete the RPC successfully
96100
StructsResponse Finish() { return proto_structs::MessageToStruct<StructsResponse>(writer_.Finish()); }
97101

libraries/grpc-proto-structs/include/userver/grpc-proto-structs/server/stream.hpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,32 @@ class Writer {
6565

6666
/// @{
6767
/// @brief Write the next outgoing message.
68+
/// @note This version may move some fields from the request.
6869
///
6970
/// Convert response to corresponding protobuf message and pass it to @ref ugrpc::server::Writer::Write.
7071
///
7172
/// @see @ref ugrpc::server::Writer::Write method for details.
72-
void Write(Response& response) { writer_.Write(proto_structs::StructToMessage(response)); }
73-
74-
void Write(Response& response, const grpc::WriteOptions& options) {
75-
writer_.Write(proto_structs::StructToMessage(response), options);
76-
}
77-
7873
void Write(Response&& response) { writer_.Write(proto_structs::StructToMessage(std::move(response))); }
7974

8075
void Write(Response&& response, const grpc::WriteOptions& options) {
8176
writer_.Write(proto_structs::StructToMessage(std::move(response)), options);
8277
}
8378
/// @}
8479

80+
/// @{
81+
/// @brief Write the next outgoing message.
82+
/// @note This version preserves the original request object by copying necessary data.
83+
///
84+
/// Convert response to corresponding protobuf message and pass it to @ref ugrpc::server::Writer::Write.
85+
///
86+
/// @see @ref ugrpc::server::Writer::Write method for details.
87+
void WriteCopy(const Response& response) { writer_.Write(proto_structs::StructToMessage(response)); }
88+
89+
void WriteCopy(const Response& response, const grpc::WriteOptions& options) {
90+
writer_.Write(proto_structs::StructToMessage(response), options);
91+
}
92+
/// @}
93+
8594
private:
8695
ProtobufMessageWriter& writer_;
8796
};

0 commit comments

Comments
 (0)