Skip to content

Commit ead3d73

Browse files
committed
GH-50380: [C++][Gandiva] fix out-of-bounds read in byte_substr past end
Signed-off-by: abdul rawoof <abdulr@bugqore.com>
1 parent a1ec26f commit ead3d73

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

cpp/src/gandiva/precompiled/string_ops.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,6 +2487,13 @@ const char* byte_substr_binary_int32_int32(gdv_int64 context, const char* text,
24872487
startPos = text_len + offset;
24882488
}
24892489

2490+
// an offset past the end of the text leaves nothing to copy; without this the
2491+
// truncation below yields a negative *out_len that memcpy reads as a huge size
2492+
if (startPos >= text_len) {
2493+
*out_len = 0;
2494+
return "";
2495+
}
2496+
24902497
// calculate end position from length and truncate to upper value bounds
24912498
if (startPos + length > text_len) {
24922499
*out_len = text_len - startPos;

cpp/src/gandiva/precompiled/string_ops_test.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,6 +1903,13 @@ TEST(TestStringOps, TestByteSubstr) {
19031903
out_str = byte_substr_binary_int32_int32(ctx_ptr, "TestString", 10, -100, 10, &out_len);
19041904
EXPECT_EQ(std::string(out_str, out_len), "TestString");
19051905
EXPECT_FALSE(ctx.has_error());
1906+
1907+
// offset past the end of the text must yield an empty result, not a negative
1908+
// length that memcpy reads as an out-of-bounds copy
1909+
out_str = byte_substr_binary_int32_int32(ctx_ptr, "TestString", 10, 15, 10, &out_len);
1910+
EXPECT_EQ(out_len, 0);
1911+
EXPECT_EQ(std::string(out_str, out_len), "");
1912+
EXPECT_FALSE(ctx.has_error());
19061913
}
19071914

19081915
TEST(TestStringOps, TestStrPos) {

0 commit comments

Comments
 (0)