Skip to content

Commit 4967deb

Browse files
committed
GH-50380: guard byte_substr length against int32 overflow
1 parent 1ccaa02 commit 4967deb

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

cpp/src/gandiva/precompiled/string_ops.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,8 +2495,11 @@ const char* byte_substr_binary_int32_int32(gdv_int64 context, const char* text,
24952495
return "";
24962496
}
24972497

2498-
// calculate end position from length and truncate to upper value bounds
2499-
if (startPos + length > text_len) {
2498+
// calculate end position from length and truncate to upper value bounds.
2499+
// startPos < text_len is guaranteed above, so text_len - startPos is positive;
2500+
// comparing against it avoids the startPos + length overflow when length is
2501+
// near INT32_MAX, which would otherwise leave *out_len huge for the memcpy.
2502+
if (length > text_len - startPos) {
25002503
*out_len = text_len - startPos;
25012504
} else {
25022505
*out_len = length;

cpp/src/gandiva/precompiled/string_ops_test.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,6 +1910,13 @@ TEST(TestStringOps, TestByteSubstr) {
19101910
EXPECT_EQ(out_len, 0);
19111911
EXPECT_EQ(std::string(out_str, out_len), "");
19121912
EXPECT_FALSE(ctx.has_error());
1913+
1914+
// a huge length must be truncated to the remaining bytes, not overflow
1915+
// startPos + length and copy far past the end of the text
1916+
out_str = byte_substr_binary_int32_int32(ctx_ptr, "TestString", 10, 2,
1917+
2147483647, &out_len);
1918+
EXPECT_EQ(std::string(out_str, out_len), "estString");
1919+
EXPECT_FALSE(ctx.has_error());
19131920
}
19141921

19151922
TEST(TestStringOps, TestStrPos) {

0 commit comments

Comments
 (0)