Skip to content

Commit 4e16a1a

Browse files
kouraulcd
authored andcommitted
GH-49159: [C++][Gandiva] Detect overflow in repeat() (#49160)
### Rationale for this change `repeat()` can only generate `< 2147483647` size output. So output larger than `2147483647` must be rejected. ### What changes are included in this PR? Add overflow check in `repeat()`. ### Are these changes tested? Yes. ### Are there any user-facing changes? Yes. * GitHub Issue: #49159 Lead-authored-by: Sutou Kouhei <kou@cozmixng.org> Co-authored-by: Sutou Kouhei <kou@clear-code.com> Signed-off-by: Raúl Cumplido <raulcumplido@gmail.com>
1 parent 985621d commit 4e16a1a

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

cpp/src/gandiva/precompiled/string_ops.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,12 @@ const char* repeat_utf8_int32(gdv_int64 context, const char* in, gdv_int32 in_le
841841
*out_len = 0;
842842
return "";
843843
}
844-
*out_len = repeat_number * in_len;
844+
if (ARROW_PREDICT_FALSE(
845+
arrow::internal::MultiplyWithOverflow(repeat_number, in_len, out_len))) {
846+
gdv_fn_context_set_error_msg(context, "Would overflow maximum output size");
847+
*out_len = 0;
848+
return "";
849+
}
845850
char* ret = reinterpret_cast<char*>(gdv_fn_context_arena_malloc(context, *out_len));
846851
if (ret == nullptr) {
847852
gdv_fn_context_set_error_msg(context, "Could not allocate memory for output string");

cpp/src/gandiva/precompiled/string_ops_test.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,13 @@ TEST(TestStringOps, TestRepeat) {
387387
EXPECT_EQ(std::string(out_str, out_len), "");
388388
EXPECT_THAT(ctx.get_error(), ::testing::HasSubstr("Repeat number can't be negative"));
389389
ctx.Reset();
390+
391+
out_str = repeat_utf8_int32(ctx_ptr, "aa", 2,
392+
std::numeric_limits<int32_t>::max() / 2 + 1, &out_len);
393+
EXPECT_EQ(std::string(out_str, out_len), "");
394+
EXPECT_THAT(ctx.get_error(),
395+
::testing::HasSubstr("Would overflow maximum output size"));
396+
ctx.Reset();
390397
}
391398

392399
TEST(TestStringOps, TestCastBoolToVarchar) {

0 commit comments

Comments
 (0)