From 6b5877a17672469151e3c04c7a21f934381761a5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 29 Sep 2025 09:32:42 -0400 Subject: [PATCH] libarchive: Backport "parse_date: handle dates in 2038 and beyond" Backport libarchive commit `2d987e725f` (parse_date: handle dates in 2038 and beyond if time_t is big enough, 2025-09-26). Add a cmake-specific test case. Fixes: #27263 --- Tests/CMakeLib/CMakeLists.txt | 1 + Tests/CMakeLib/testDateTime.cxx | 32 +++++++++++++++++++ .../libarchive/archive_parse_date.c | 4 +-- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 Tests/CMakeLib/testDateTime.cxx diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 7f35f04e21..a50936e7c5 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -15,6 +15,7 @@ set(CMakeLib_TESTS testCTestResourceAllocator.cxx testCTestResourceSpec.cxx testCTestResourceGroups.cxx + testDateTime.cxx testDebug.cxx testDocumentationFormatter.cxx testGccDepfileReader.cxx diff --git a/Tests/CMakeLib/testDateTime.cxx b/Tests/CMakeLib/testDateTime.cxx new file mode 100644 index 0000000000..bce9033b8e --- /dev/null +++ b/Tests/CMakeLib/testDateTime.cxx @@ -0,0 +1,32 @@ +#include + +#include "cm_parse_date.h" + +#include "testCommon.h" + +namespace { + +bool parse_date() +{ + std::cout << "parse_date()\n"; + std::time_t now; + std::time(&now); + { + std::time_t t = cm_parse_date(now, "20000101 00:01:02 -0000"); + ASSERT_EQUAL(t, 946684862); + } + { + std::time_t t = cm_parse_date(now, "20380601 00:01:02 -0000"); + ASSERT_EQUAL(t, sizeof(time_t) <= 4 ? -1 : 2158963262); + } + return true; +} + +} + +int testDateTime(int /*unused*/, char* /*unused*/[]) +{ + return runTests({ + parse_date, + }); +} diff --git a/Utilities/cmlibarchive/libarchive/archive_parse_date.c b/Utilities/cmlibarchive/libarchive/archive_parse_date.c index 05540784b9..9a577f60cd 100644 --- a/Utilities/cmlibarchive/libarchive/archive_parse_date.c +++ b/Utilities/cmlibarchive/libarchive/archive_parse_date.c @@ -705,9 +705,7 @@ Convert(time_t Month, time_t Day, time_t Year, Year += 1900; DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year >= 2038 + if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038) || Month < 1 || Month > 12 /* Lint fluff: "conversion from long may lose accuracy" */ || Day < 1 || Day > DaysInMonth[(int)--Month]