From 1904d1a9ff54343471998523816c9e0a00f46797 Mon Sep 17 00:00:00 2001 From: "Robert (Bobby) Evans" Date: Wed, 1 Dec 2021 13:00:16 -0600 Subject: [PATCH] Fix overflow for min calculation in strings::from_timestamps (#9793) This fixes #9790 When converting a timestamp to a String it is possible for the %M min calculation to overflow an int32_t part way through casting. This moves that result to be an int64_t which avoids the overflow issues. Authors: - Robert (Bobby) Evans (https://github.com/revans2) Approvers: - Bradley Dice (https://github.com/bdice) - David Wendt (https://github.com/davidwendt) URL: https://github.com/rapidsai/cudf/pull/9793 --- cpp/src/strings/convert/convert_datetime.cu | 4 ++-- cpp/tests/strings/datetime_tests.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cpp/src/strings/convert/convert_datetime.cu b/cpp/src/strings/convert/convert_datetime.cu index 51a6a796ba3..8d0c5704a7b 100644 --- a/cpp/src/strings/convert/convert_datetime.cu +++ b/cpp/src/strings/convert/convert_datetime.cu @@ -707,9 +707,9 @@ struct from_timestamp_base { * scale( 61,60) -> 1 * @endcode */ - __device__ int32_t scale_time(int64_t time, int64_t base) const + __device__ int64_t scale_time(int64_t time, int64_t base) const { - return static_cast((time - ((time < 0) * (base - 1L))) / base); + return (time - ((time < 0) * (base - 1L))) / base; }; __device__ time_components get_time_components(int64_t tstamp) const diff --git a/cpp/tests/strings/datetime_tests.cpp b/cpp/tests/strings/datetime_tests.cpp index 4543607614f..9a01d5dd041 100644 --- a/cpp/tests/strings/datetime_tests.cpp +++ b/cpp/tests/strings/datetime_tests.cpp @@ -311,13 +311,14 @@ TEST_F(StringsDatetimeTest, FromTimestampAmPm) TEST_F(StringsDatetimeTest, FromTimestampMillisecond) { cudf::test::fixed_width_column_wrapper timestamps_ms{ - 1530705600123, 1582934461007, 1451430122421, 1318302183999, -6106017600047}; + 1530705600123, 1582934461007, 1451430122421, 1318302183999, -6106017600047, 128849018880000}; auto results = cudf::strings::from_timestamps(timestamps_ms, "%Y-%m-%d %H:%M:%S.%3f"); cudf::test::strings_column_wrapper expected_ms{"2018-07-04 12:00:00.123", "2020-02-29 00:01:01.007", "2015-12-29 23:02:02.421", "2011-10-11 03:03:03.999", - "1776-07-04 11:59:59.953"}; + "1776-07-04 11:59:59.953", + "6053-01-23 02:08:00.000"}; CUDF_TEST_EXPECT_COLUMNS_EQUAL(*results, expected_ms); results = cudf::strings::from_timestamps(timestamps_ms, "%Y-%m-%d %H:%M:%S.%f"); @@ -325,7 +326,8 @@ TEST_F(StringsDatetimeTest, FromTimestampMillisecond) "2020-02-29 00:01:01.007000", "2015-12-29 23:02:02.421000", "2011-10-11 03:03:03.999000", - "1776-07-04 11:59:59.953000"}; + "1776-07-04 11:59:59.953000", + "6053-01-23 02:08:00.000000"}; CUDF_TEST_EXPECT_COLUMNS_EQUAL(*results, expected_ms_6f); cudf::test::fixed_width_column_wrapper timestamps_ns{