|
26 | 26 | #include <brpc/server.h> |
27 | 27 | #include <brpc/redis_command.h> |
28 | 28 | #include <gtest/gtest.h> |
| 29 | +#include <gflags/gflags.h> |
29 | 30 |
|
30 | 31 | namespace brpc { |
31 | 32 | DECLARE_int32(idle_timeout_second); |
| 33 | +DECLARE_int32(redis_max_allocation_size); |
32 | 34 | } |
33 | 35 |
|
34 | 36 | int main(int argc, char* argv[]) { |
@@ -1329,4 +1331,97 @@ TEST_F(RedisTest, server_handle_pipeline) { |
1329 | 1331 | ASSERT_STREQ(response.reply(7).c_str(), "world"); |
1330 | 1332 | } |
1331 | 1333 |
|
| 1334 | +TEST_F(RedisTest, memory_allocation_limits) { |
| 1335 | + int32_t original_limit = brpc::FLAGS_redis_max_allocation_size; |
| 1336 | + brpc::FLAGS_redis_max_allocation_size = 1024; |
| 1337 | + |
| 1338 | + butil::Arena arena; |
| 1339 | + |
| 1340 | + // Test redis_reply.cpp limits |
| 1341 | + { |
| 1342 | + // Test bulk string exceeding limit |
| 1343 | + butil::IOBuf buf; |
| 1344 | + std::string large_string = "*1\r\n$2000\r\n"; |
| 1345 | + large_string.append(2000, 'a'); |
| 1346 | + large_string.append("\r\n"); |
| 1347 | + buf.append(large_string); |
| 1348 | + |
| 1349 | + brpc::RedisReply reply(&arena); |
| 1350 | + brpc::ParseError err = reply.ConsumePartialIOBuf(buf); |
| 1351 | + ASSERT_EQ(brpc::PARSE_ERROR_ABSOLUTELY_WRONG, err); |
| 1352 | + } |
| 1353 | + |
| 1354 | + { |
| 1355 | + // Test array allocation exceeding limit |
| 1356 | + butil::IOBuf buf; |
| 1357 | + int32_t large_count = brpc::FLAGS_redis_max_allocation_size / sizeof(brpc::RedisReply) + 1; |
| 1358 | + std::string large_array = "*" + std::to_string(large_count) + "\r\n"; |
| 1359 | + buf.append(large_array); |
| 1360 | + |
| 1361 | + brpc::RedisReply reply(&arena); |
| 1362 | + brpc::ParseError err = reply.ConsumePartialIOBuf(buf); |
| 1363 | + ASSERT_EQ(brpc::PARSE_ERROR_ABSOLUTELY_WRONG, err); |
| 1364 | + } |
| 1365 | + |
| 1366 | + // Test redis_command.cpp limits |
| 1367 | + { |
| 1368 | + // Test command string exceeding limit |
| 1369 | + brpc::RedisCommandParser parser; |
| 1370 | + butil::IOBuf buf; |
| 1371 | + std::string large_cmd = "*2\r\n$3\r\nget\r\n$2000\r\n"; |
| 1372 | + large_cmd.append(2000, 'b'); |
| 1373 | + large_cmd.append("\r\n"); |
| 1374 | + buf.append(large_cmd); |
| 1375 | + |
| 1376 | + std::vector<butil::StringPiece> args; |
| 1377 | + brpc::ParseError err = parser.Consume(buf, &args, &arena); |
| 1378 | + ASSERT_EQ(brpc::PARSE_ERROR_ABSOLUTELY_WRONG, err); |
| 1379 | + } |
| 1380 | + |
| 1381 | + { |
| 1382 | + // Test command array size exceeding limit |
| 1383 | + brpc::RedisCommandParser parser; |
| 1384 | + butil::IOBuf buf; |
| 1385 | + int32_t large_array_size = brpc::FLAGS_redis_max_allocation_size / sizeof(butil::StringPiece) + 1; |
| 1386 | + std::string large_array_cmd = "*" + std::to_string(large_array_size) + "\r\n"; |
| 1387 | + buf.append(large_array_cmd); |
| 1388 | + |
| 1389 | + std::vector<butil::StringPiece> args; |
| 1390 | + brpc::ParseError err = parser.Consume(buf, &args, &arena); |
| 1391 | + ASSERT_EQ(brpc::PARSE_ERROR_ABSOLUTELY_WRONG, err); |
| 1392 | + } |
| 1393 | + |
| 1394 | + // Test valid cases within limits |
| 1395 | + { |
| 1396 | + // Test small bulk string should work |
| 1397 | + butil::IOBuf buf; |
| 1398 | + std::string small_string = "*1\r\n$10\r\nhelloworld\r\n"; |
| 1399 | + buf.append(small_string); |
| 1400 | + |
| 1401 | + brpc::RedisReply reply(&arena); |
| 1402 | + brpc::ParseError err = reply.ConsumePartialIOBuf(buf); |
| 1403 | + ASSERT_EQ(brpc::PARSE_OK, err); |
| 1404 | + ASSERT_TRUE(reply.is_array()); |
| 1405 | + ASSERT_EQ(1, (int)reply.size()); |
| 1406 | + ASSERT_STREQ("helloworld", reply[0].c_str()); |
| 1407 | + } |
| 1408 | + |
| 1409 | + { |
| 1410 | + // Test small command should work |
| 1411 | + brpc::RedisCommandParser parser; |
| 1412 | + butil::IOBuf buf; |
| 1413 | + std::string small_cmd = "*2\r\n$3\r\nget\r\n$5\r\nmykey\r\n"; |
| 1414 | + buf.append(small_cmd); |
| 1415 | + |
| 1416 | + std::vector<butil::StringPiece> args; |
| 1417 | + brpc::ParseError err = parser.Consume(buf, &args, &arena); |
| 1418 | + ASSERT_EQ(brpc::PARSE_OK, err); |
| 1419 | + ASSERT_EQ(2, (int)args.size()); |
| 1420 | + ASSERT_EQ("get", args[0].as_string()); |
| 1421 | + ASSERT_EQ("mykey", args[1].as_string()); |
| 1422 | + } |
| 1423 | + |
| 1424 | + brpc::FLAGS_redis_max_allocation_size = original_limit; |
| 1425 | +} |
| 1426 | + |
1332 | 1427 | } //namespace |
0 commit comments