From 1117284be7f72a22ac841af8f1a91ec853adc900 Mon Sep 17 00:00:00 2001 From: Yarik Briukhovetskyi <114298166+yariks5s@users.noreply.github.com> Date: Fri, 5 Jan 2024 23:43:58 +0000 Subject: [PATCH] fix overflow --- src/Functions/DateTimeTransforms.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index dbe2b11d7b2..e9cee9616fb 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -697,7 +697,12 @@ struct ToStartOfInterval if (origin == 0) return time_zone.toStartOfWeekInterval(time_zone.toDayNum(t / scale_multiplier), weeks); else - return ToStartOfInterval::execute(t, weeks * 7, time_zone, scale_multiplier, origin); + { + if (const auto weeks_to_days = weeks * 7; weeks_to_days / 7 == weeks) // Check if multiplication doesn't overflow Int64 value + return ToStartOfInterval::execute(t, weeks_to_days, time_zone, scale_multiplier, origin); + else + throw Exception(ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, "Value {} * 7 is out of bounds for type Int64", weeks); + } } }; @@ -728,11 +733,8 @@ struct ToStartOfInterval months_to_add = days < 0 ? months_to_add - 1 : months_to_add; months_to_add += years * 12; Int64 month_multiplier = (months_to_add / months) * months; - Int64 a = 0; - a = time_zone.addMonths(time_zone.toDate(origin), month_multiplier); - // a += time_zone.toTime(origin); - return a - time_zone.toDate(origin); + return time_zone.addMonths(time_zone.toDate(origin), month_multiplier) - time_zone.toDate(origin); } } }; @@ -757,7 +759,12 @@ struct ToStartOfInterval if (origin == 0) return time_zone.toStartOfQuarterInterval(time_zone.toDayNum(t / scale_multiplier), quarters); else - return ToStartOfInterval::execute(t, quarters * 3, time_zone, scale_multiplier, origin); + { + if (const auto quarters_to_months = quarters * 3; quarters_to_months / 3 == quarters) // Check if multiplication doesn't overflow Int64 value + return ToStartOfInterval::execute(t, quarters_to_months, time_zone, scale_multiplier, origin); + else + throw Exception(ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, "Value {} * 3 is out of bounds for type Int64", quarters); + } } }; @@ -782,8 +789,10 @@ struct ToStartOfInterval return time_zone.toStartOfYearInterval(time_zone.toDayNum(t / scale_multiplier), years); else { - auto a = ToStartOfInterval::execute(t, years * 12, time_zone, scale_multiplier, origin); - return a; + if (const auto years_to_months = years * 12; years_to_months / 12 == years) // Check if multiplication doesn't overflow Int64 value + return ToStartOfInterval::execute(t, years_to_months, time_zone, scale_multiplier, origin); + else + throw Exception(ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, "Value {} * 12 is out of bounds for type Int64", years); } } };