From e0953ba8f805203e7b61cf2993c8d60bdb409af8 Mon Sep 17 00:00:00 2001 From: abdul rawoof Date: Sun, 19 Jul 2026 13:30:45 +0530 Subject: [PATCH] check round precision bound before negating --- cpp/src/gandiva/precompiled/extended_math_ops.cc | 14 ++++++++------ .../gandiva/precompiled/extended_math_ops_test.cc | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cpp/src/gandiva/precompiled/extended_math_ops.cc b/cpp/src/gandiva/precompiled/extended_math_ops.cc index 348d595faf49..206295f06dd4 100644 --- a/cpp/src/gandiva/precompiled/extended_math_ops.cc +++ b/cpp/src/gandiva/precompiled/extended_math_ops.cc @@ -324,12 +324,13 @@ gdv_int32 round_int32_int32(gdv_int32 number, gdv_int32 precision) { if (precision >= 0) { return number; } - gdv_int32 abs_precision = -precision; // This is to ensure that there is no overflow while calculating 10^precision, 9 is - // the smallest N for which 10^N does not fit into 32 bits, so we can safely return 0 - if (abs_precision > 9) { + // the smallest N for which 10^N does not fit into 32 bits, so we can safely return 0. + // The bound is checked before negating because -INT32_MIN is still negative. + if (precision < -9) { return 0; } + gdv_int32 abs_precision = -precision; gdv_int32 num_sign = (number > 0) ? 1 : -1; gdv_int32 abs_number = number * num_sign; gdv_int32 power_of_10 = static_cast(get_power_of_10(abs_precision)); @@ -349,12 +350,13 @@ gdv_int64 round_int64_int32(gdv_int64 number, gdv_int32 precision) { if (precision >= 0) { return number; } - gdv_int32 abs_precision = -precision; // This is to ensure that there is no overflow while calculating 10^precision, 19 is - // the smallest N for which 10^N does not fit into 64 bits, so we can safely return 0 - if (abs_precision > 18) { + // the smallest N for which 10^N does not fit into 64 bits, so we can safely return 0. + // The bound is checked before negating because -INT32_MIN is still negative. + if (precision < -18) { return 0; } + gdv_int32 abs_precision = -precision; gdv_int32 num_sign = (number > 0) ? 1 : -1; gdv_int64 abs_number = number * num_sign; gdv_int64 power_of_10 = get_power_of_10(abs_precision); diff --git a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc index e7a0f74c1b45..3e54a359395c 100644 --- a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc +++ b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc @@ -203,6 +203,11 @@ TEST(TestExtendedMathOps, TestRound) { EXPECT_EQ(round_int64_int32(-23453462343, -4), -23453460000); EXPECT_EQ(round_int64_int32(-23453462343, -5), -23453500000); EXPECT_EQ(round_int64_int32(345353425343, -12), 0); + + // The most negative precision must be rejected by the range check rather than + // negated into an out-of-range table index. + EXPECT_EQ(round_int32_int32(1234, std::numeric_limits::min()), 0); + EXPECT_EQ(round_int64_int32(345353425343, std::numeric_limits::min()), 0); } TEST(TestExtendedMathOps, TestTruncate) {