From a39367577efcbe7e0837e2888ba12638e0b09c12 Mon Sep 17 00:00:00 2001 From: abdul rawoof Date: Thu, 9 Jul 2026 12:21:11 +0530 Subject: [PATCH] GH-50440: [C++][Gandiva] fix out-of-bounds read in set_error_for_date --- cpp/src/gandiva/precompiled/time.cc | 2 +- cpp/src/gandiva/precompiled/time_test.cc | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cpp/src/gandiva/precompiled/time.cc b/cpp/src/gandiva/precompiled/time.cc index 2b60f63651db..9a66e41bbb13 100644 --- a/cpp/src/gandiva/precompiled/time.cc +++ b/cpp/src/gandiva/precompiled/time.cc @@ -631,7 +631,7 @@ void set_error_for_date(gdv_int32 length, const char* input, const char* msg, int64_t execution_context) { int size = length + static_cast(strlen(msg)) + 1; char* error = reinterpret_cast(malloc(size)); - snprintf(error, size, "%s%s", msg, input); + snprintf(error, size, "%s%.*s", msg, length, input); gdv_fn_context_set_error_msg(execution_context, error); free(error); } diff --git a/cpp/src/gandiva/precompiled/time_test.cc b/cpp/src/gandiva/precompiled/time_test.cc index 4310490a228b..d2bd673b724e 100644 --- a/cpp/src/gandiva/precompiled/time_test.cc +++ b/cpp/src/gandiva/precompiled/time_test.cc @@ -18,6 +18,10 @@ #include #include +#include +#include +#include + #include "arrow/util/logging_internal.h" #include "gandiva/execution_context.h" #include "gandiva/precompiled/testing.h" @@ -59,6 +63,24 @@ TEST(TestTime, TestCastDate) { EXPECT_EQ(castDATE_date32(1), 86400000); } +TEST(TestTime, TestCastDateInvalidUnterminated) { + ExecutionContext context; + int64_t context_ptr = reinterpret_cast(&context); + + // The invalid-value error message is built from the raw input pointer. Hold + // the input in an exactly-sized heap buffer with no trailing NUL so that + // formatting the error must respect `length` instead of scanning for a NUL; + // any over-read past the buffer trips AddressSanitizer. + const char bytes[] = {'1', '9', '7', '2', '2', '2', '2', '2', '2', '2'}; + const auto length = static_cast(sizeof(bytes)); + std::unique_ptr input(new char[length]); + std::memcpy(input.get(), bytes, length); + + EXPECT_EQ(castDATE_utf8(context_ptr, input.get(), length), 0); + EXPECT_EQ(context.get_error(), "Not a valid date value 1972222222"); + context.Reset(); +} + TEST(TestTime, TestCastTimestamp) { ExecutionContext context; int64_t context_ptr = reinterpret_cast(&context);