Skip to content

Commit ff1b1bf

Browse files
committed
GH-50472: [C++][Gandiva] check overflow in mask output size
1 parent 5815dc0 commit ff1b1bf

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

cpp/src/gandiva/gdv_function_stubs.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,14 @@ const char* mask_utf8_utf8_utf8_utf8(int64_t context, const char* data, int32_t
648648
return nullptr;
649649
}
650650

651-
int32_t max_length =
652-
std::max(upper_length, std::max(lower_length, num_length)) * data_len;
651+
int32_t max_repl_length = std::max(upper_length, std::max(lower_length, num_length));
652+
int32_t max_length = 0;
653+
if (ARROW_PREDICT_FALSE(arrow::internal::MultiplyWithOverflow(max_repl_length, data_len,
654+
&max_length))) {
655+
gdv_fn_context_set_error_msg(context, "Would overflow maximum output size");
656+
*out_len = 0;
657+
return nullptr;
658+
}
653659
char* out = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, max_length));
654660
if (out == nullptr) {
655661
gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");

cpp/src/gandiva/gdv_function_stubs_test.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,20 @@ TEST(TestGdvFnStubs, TestMask) {
14791479
result = mask_utf8_utf8_utf8_utf8(ctx_ptr, data.c_str(), data_len, "\?", 1, "*", 1, "#",
14801480
1, &out_len);
14811481
EXPECT_EQ(std::string(result, out_len), expected);
1482+
1483+
// A replacement length that overflows int32 when multiplied by the input
1484+
// length must be rejected instead of under-allocating the output buffer.
1485+
std::string big_data(65536, 'A');
1486+
std::string big_repl(65537, 'Z');
1487+
data_len = static_cast<int32_t>(big_data.length());
1488+
out_len = -1;
1489+
result = mask_utf8_utf8_utf8_utf8(ctx_ptr, big_data.c_str(), data_len, big_repl.c_str(),
1490+
static_cast<int32_t>(big_repl.length()), "x", 1, "n",
1491+
1, &out_len);
1492+
EXPECT_EQ(result, nullptr);
1493+
EXPECT_EQ(out_len, 0);
1494+
EXPECT_TRUE(ctx.has_error());
1495+
ctx.Reset();
14821496
}
14831497

14841498
TEST(TestGdvFnStubs, TestAesEncryptDecrypt16) {

0 commit comments

Comments
 (0)