Skip to content

Commit 1576e82

Browse files
authored
Bugfix: fixed stack overflow issue when parsing deeply nested JSON with RapidJSON. (#230)
- use 'rapidjson::kParseIterativeFlag' to avoid stack overlow.
1 parent 0e5a67f commit 1576e82

8 files changed

Lines changed: 18 additions & 18 deletions

File tree

trpc/admin/admin_service_test.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ TEST_F(TestAdminService, CheckAdminService) {
7474
r.Handle("/cmds", context, req1, reply1);
7575
std::cout << reply1.GetContent() << std::endl;
7676
rapidjson::Document rsp1_json;
77-
rsp1_json.Parse(reply1.GetContent());
77+
rsp1_json.Parse<rapidjson::kParseIterativeFlag>(reply1.GetContent());
7878
ASSERT_FALSE(rsp1_json.HasParseError());
7979
const rapidjson::Value& cmds = rsp1_json["cmds"];
8080
ASSERT_TRUE(cmds.IsArray());
@@ -96,7 +96,7 @@ TEST_F(TestAdminService, CheckAdminService) {
9696
r.Handle("/cmds/loglevel", context, req3, reply3);
9797
std::cout << reply3.GetContent() << std::endl;
9898
rapidjson::Document rsp3_json;
99-
rsp3_json.Parse(reply3.GetContent());
99+
rsp3_json.Parse<rapidjson::kParseIterativeFlag>(reply3.GetContent());
100100
ASSERT_FALSE(rsp3_json.HasParseError());
101101
ASSERT_STREQ(rsp3_json["level"].GetString(), "INFO");
102102

@@ -107,7 +107,7 @@ TEST_F(TestAdminService, CheckAdminService) {
107107
r.Handle("/cmds/loglevel", context, req4, reply4);
108108
std::cout << reply4.GetContent() << std::endl;
109109
rapidjson::Document rsp4_json;
110-
rsp4_json.Parse(reply4.GetContent());
110+
rsp4_json.Parse<rapidjson::kParseIterativeFlag>(reply4.GetContent());
111111
ASSERT_FALSE(rsp4_json.HasParseError());
112112
ASSERT_STREQ(rsp4_json["level"].GetString(), "ERROR");
113113

@@ -125,7 +125,7 @@ TEST_F(TestAdminService, CheckAdminService) {
125125
r.Handle("/cmds/reload-config", context, req6, reply6);
126126
std::cout << reply6.GetContent() << std::endl;
127127
rapidjson::Document rsp6_json;
128-
rsp6_json.Parse(reply6.GetContent());
128+
rsp6_json.Parse<rapidjson::kParseIterativeFlag>(reply6.GetContent());
129129
ASSERT_FALSE(rsp6_json.HasParseError());
130130
ASSERT_STREQ(rsp6_json["message"].GetString(), "reload config ok");
131131

@@ -136,7 +136,7 @@ TEST_F(TestAdminService, CheckAdminService) {
136136
r.Handle("/cmds/watch", context, req7, reply7);
137137
std::cout << reply7.GetContent() << std::endl;
138138
rapidjson::Document rsp7_json;
139-
rsp7_json.Parse(reply7.GetContent());
139+
rsp7_json.Parse<rapidjson::kParseIterativeFlag>(reply7.GetContent());
140140
ASSERT_FALSE(rsp7_json.HasParseError());
141141
ASSERT_STREQ(rsp7_json["message"].GetString(), "watching unsupported");
142142

trpc/client/http/http_service_proxy.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ Future<rapidjson::Document> HttpServiceProxy::AsyncHttpUnaryInvokeJson(const Cli
815815
auto* rsp = static_cast<HttpResponseProtocol*>(p.get());
816816
auto rsp_str = FlattenSlow(rsp->GetNonContiguousProtocolBody());
817817
rapidjson::Document rsp_json;
818-
rsp_json.Parse(rsp_str.c_str(), rsp_str.size());
818+
rsp_json.Parse<rapidjson::kParseIterativeFlag>(rsp_str.c_str(), rsp_str.size());
819819
if (!rsp_str.empty() && rsp_json.HasParseError()) {
820820
std::string error{
821821
fmt::format("Http JsonParse Failed: {}", rapidjson::GetParseError_En(rsp_json.GetParseError()))};
@@ -853,7 +853,7 @@ Future<rapidjson::Document> HttpServiceProxy::AsyncHttpUnaryInvokeJson(const Cli
853853
auto* rsp = static_cast<HttpResponseProtocol*>(p.get());
854854
auto rsp_str = FlattenSlow(rsp->GetNonContiguousProtocolBody());
855855
rapidjson::Document rsp_json;
856-
rsp_json.Parse(rsp_str.c_str(), rsp_str.size());
856+
rsp_json.Parse<rapidjson::kParseIterativeFlag>(rsp_str.c_str(), rsp_str.size());
857857
if (!rsp_str.empty() && rsp_json.HasParseError()) {
858858
std::string error{
859859
fmt::format("Http JsonParse Failed: {}", rapidjson::GetParseError_En(rsp_json.GetParseError()))};

trpc/client/http/http_service_proxy_test.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,7 @@ TEST_F(HttpServiceProxyTest, SuccessRspPostJson) {
13571357

13581358
rapidjson::Document data;
13591359
std::string request_json = "{\"age\":\"18\",\"height\":180}";
1360-
data.Parse(request_json);
1360+
data.Parse<rapidjson::kParseIterativeFlag>(request_json);
13611361

13621362
rapidjson::Document doc;
13631363
Status st = proxy->Post(ctx, "http://127.0.0.1:10002/hello", data, &doc);
@@ -1421,7 +1421,7 @@ TEST_F(HttpServiceProxyTest, SuccessRspPostJsonEmpty) {
14211421
ctx->SetAddr("127.0.0.1", 10002);
14221422
rapidjson::Document data;
14231423
std::string request_json = "{\"age\":\"18\",\"height\":180}";
1424-
data.Parse(request_json);
1424+
data.Parse<rapidjson::kParseIterativeFlag>(request_json);
14251425

14261426
rapidjson::Document doc;
14271427
Status st = proxy->Post(ctx, "http://127.0.0.1:10002/hello", data, &doc);
@@ -2051,7 +2051,7 @@ TEST_F(HttpServiceProxyTest, SuccessRspPutJson) {
20512051

20522052
rapidjson::Document data;
20532053
std::string request_json = "{\"age\":\"18\",\"height\":180}";
2054-
data.Parse(request_json);
2054+
data.Parse<rapidjson::kParseIterativeFlag>(request_json);
20552055

20562056
rapidjson::Document doc;
20572057
Status st = proxy->Put(ctx, "http://127.0.0.1:10002/hello", data, &doc);
@@ -2115,7 +2115,7 @@ TEST_F(HttpServiceProxyTest, SuccessRspPutJsonEmpty) {
21152115
ctx->SetAddr("127.0.0.1", 10002);
21162116
rapidjson::Document data;
21172117
std::string request_json = "{\"age\":\"18\",\"height\":180}";
2118-
data.Parse(request_json);
2118+
data.Parse<rapidjson::kParseIterativeFlag>(request_json);
21192119

21202120
rapidjson::Document doc;
21212121
Status st = proxy->Put(ctx, "http://127.0.0.1:10002/hello", data, &doc);

trpc/client/http/testing/http_client_call_testing.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ bool UnaryRpcCallWithPb(const HttpServiceProxyPtr& proxy) {
7575
bool UnaryRpcCallWithPostingJson(const HttpServiceProxyPtr& proxy) {
7676
auto ctx = MakeClientContext(proxy);
7777
rapidjson::Document req_json;
78-
req_json.Parse(R"({"msg": "hello world!"})");
78+
req_json.Parse<rapidjson::kParseIterativeFlag>(R"({"msg": "hello world!"})");
7979
rapidjson::Document rsp_json;
8080
auto status = proxy->Post(ctx, "http://example.com/trpc.test.helloworld.Greeter/SayHello", req_json, &rsp_json);
8181
if (!status.OK()) {
@@ -231,7 +231,7 @@ bool PostString(const HttpServiceProxyPtr& proxy) {
231231
bool PostJson(const HttpServiceProxyPtr& proxy) {
232232
auto ctx = MakeClientContext(proxy);
233233
rapidjson::Document req_json;
234-
req_json.Parse(R"({"msg": "hello world!"})");
234+
req_json.Parse<rapidjson::kParseIterativeFlag>(R"({"msg": "hello world!"})");
235235
rapidjson::Document rsp_json;
236236
auto status = proxy->Post(ctx, "http://example.com/foo", req_json, &rsp_json);
237237
if (!status.OK()) {

trpc/codec/http/http_client_codec_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ TEST_F(HttpClientCodecTest, FillRequestAsJson) {
170170

171171
rapidjson::Document json;
172172
std::string request_json = "{\"age\":\"18\",\"height\":180}";
173-
json.Parse(request_json);
173+
json.Parse<rapidjson::kParseIterativeFlag>(request_json);
174174

175175
ASSERT_TRUE(codec_.FillRequest(context, req_protocol, reinterpret_cast<void*>(&json)));
176176

trpc/codec/http/http_server_codec.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ bool SerializationTypeToContentType(uint32_t serialization_type, std::string* co
8585

8686
void ParseTrpcTransInfo(std::string& value, HttpRequestProtocol* req) {
8787
rapidjson::Document document;
88-
document.Parse(value.c_str());
88+
document.Parse<rapidjson::kParseIterativeFlag>(value.c_str());
8989
if (document.IsObject()) {
9090
for (auto& mem : document.GetObject()) {
9191
std::string key = mem.name.GetString();

trpc/serialization/json/json_serialization_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ TEST(JsonSerializationTest, JsonSerializationRapidjsonTest) {
3838
std::string json_str = "{\"age\":\"18\",\"height\":180}";
3939

4040
rapidjson::Document serialize_document;
41-
serialize_document.Parse(json_str.c_str());
41+
serialize_document.Parse<rapidjson::kParseIterativeFlag>(json_str.c_str());
4242

4343
ASSERT_TRUE(!serialize_document.HasParseError());
4444

@@ -65,7 +65,7 @@ TEST(JsonSerializationTest, EmptyStringJsonDerializationRapidjsonTest) {
6565
std::string json_str = "";
6666

6767
rapidjson::Document serialize_document;
68-
serialize_document.Parse(json_str.c_str());
68+
serialize_document.Parse<rapidjson::kParseIterativeFlag>(json_str.c_str());
6969

7070
ASSERT_TRUE(serialize_document.HasParseError());
7171

trpc/server/rpc/rpc_service_impl_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ TEST_F(RpcServiceImplTest, RapidJsonMessage) {
350350
std::string json_str = "{\"age\":\"18\",\"height\":180}";
351351

352352
rapidjson::Document hello_req;
353-
hello_req.Parse(json_str.c_str());
353+
hello_req.Parse<rapidjson::kParseIterativeFlag>(json_str.c_str());
354354

355355
ASSERT_TRUE(!hello_req.HasParseError());
356356

0 commit comments

Comments
 (0)