Thanks for the bug report. I installed the attached patches to Gnulib
and to Coreutils, and the fix should be in the next Coreutils release.From aa0d1e7800903f2d75432d78aa64a0e9770e83f2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sat, 5 Feb 2022 11:05:44 -0800
Subject: [PATCH] parse-datetime: allow calculations to yield -1
Problem reported by Jeremy Cantrell <https://bugs.gnu.org/50115>.
* lib/parse-datetime.y (parse_datetime_body): When calling mktime,
use an unmodifed and negative tm_wday or tm_yday to detect an error,
as a (time_t) -1 return value is valid on most hosts.
* tests/test-parse-datetime.c (main): Add a test for the bug.
---
ChangeLog | 9 +++++++++
lib/parse-datetime.y | 22 +++++++++++-----------
tests/test-parse-datetime.c | 8 ++++++++
3 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5445802ea2..18dcb3fe3f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2022-02-05 Paul Eggert <egg...@cs.ucla.edu>
+
+ parse-datetime: allow calculations to yield -1
+ Problem reported by Jeremy Cantrell <https://bugs.gnu.org/50115>.
+ * lib/parse-datetime.y (parse_datetime_body): When calling mktime,
+ use an unmodifed and negative tm_wday or tm_yday to detect an error,
+ as a (time_t) -1 return value is valid on most hosts.
+ * tests/test-parse-datetime.c (main): Add a test for the bug.
+
2022-02-04 Paul Eggert <egg...@cs.ucla.edu>
userspec: help fix GNU ‘id’ incompatibility
diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y
index c40fdcef7f..9fc14c9d46 100644
--- a/lib/parse-datetime.y
+++ b/lib/parse-datetime.y
@@ -2076,21 +2076,20 @@ parse_datetime_body (struct timespec *result, char const *p,
if (pc.days_seen && ! pc.dates_seen)
{
intmax_t dayincr;
- if (INT_MULTIPLY_WRAPV ((pc.day_ordinal
- - (0 < pc.day_ordinal
- && tm.tm_wday != pc.day_number)),
- 7, &dayincr)
- || INT_ADD_WRAPV ((pc.day_number - tm.tm_wday + 7) % 7,
- dayincr, &dayincr)
- || INT_ADD_WRAPV (dayincr, tm.tm_mday, &tm.tm_mday))
- Start = -1;
- else
+ tm.tm_yday = -1;
+ if (! (INT_MULTIPLY_WRAPV ((pc.day_ordinal
+ - (0 < pc.day_ordinal
+ && tm.tm_wday != pc.day_number)),
+ 7, &dayincr)
+ || INT_ADD_WRAPV ((pc.day_number - tm.tm_wday + 7) % 7,
+ dayincr, &dayincr)
+ || INT_ADD_WRAPV (dayincr, tm.tm_mday, &tm.tm_mday)))
{
tm.tm_isdst = -1;
Start = mktime_z (tz, &tm);
}
- if (Start == (time_t) -1)
+ if (tm.tm_yday < 0)
{
if (debugging (&pc))
dbg_printf (_("error: day '%s' "
@@ -2156,8 +2155,9 @@ parse_datetime_body (struct timespec *result, char const *p,
tm.tm_min = tm0.tm_min;
tm.tm_sec = tm0.tm_sec;
tm.tm_isdst = tm0.tm_isdst;
+ tm.tm_wday = -1;
Start = mktime_z (tz, &tm);
- if (Start == (time_t) -1)
+ if (tm.tm_wday < 0)
{
if (debugging (&pc))
dbg_printf (_("error: adding relative date resulted "
diff --git a/tests/test-parse-datetime.c b/tests/test-parse-datetime.c
index 059c810cd1..1e7955bc96 100644
--- a/tests/test-parse-datetime.c
+++ b/tests/test-parse-datetime.c
@@ -398,6 +398,14 @@ main (_GL_UNUSED int argc, char **argv)
ASSERT (result.tv_sec == thur2 + ((i + 3) % 7 - 7) * 24 * 3600);
}
+ p = "1970-12-31T23:59:59+00:00 - 1 year"; /* Bug#50115 */
+ now.tv_sec = -1;
+ now.tv_nsec = 0;
+ ASSERT (parse_datetime (&result, p, &now));
+ LOG (p, now, result);
+ ASSERT (result.tv_sec == now.tv_sec
+ && result.tv_nsec == now.tv_nsec);
+
p = "THURSDAY UTC+00"; /* The epoch was on Thursday. */
now.tv_sec = 0;
now.tv_nsec = 0;
--
2.32.0
From cf6c84989968c5081c683bbef77825fc35e03c9d Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sat, 5 Feb 2022 11:08:45 -0800
Subject: [PATCH 1/2] build: update gnulib submodule to latest
---
gnulib | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gnulib b/gnulib
index ff208d546..aa0d1e780 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit ff208d546a26fee39a0191297c11560da74b5dee
+Subproject commit aa0d1e7800903f2d75432d78aa64a0e9770e83f2
--
2.32.0
From 8a3dedfef9479c53cd9016139ce00d58a6006ba2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sat, 5 Feb 2022 13:46:44 -0800
Subject: [PATCH 2/2] date: test against bug#50115
* tests/misc/date.pl: Add test.
---
tests/misc/date.pl | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/misc/date.pl b/tests/misc/date.pl
index e9de8e453..ef7080e33 100755
--- a/tests/misc/date.pl
+++ b/tests/misc/date.pl
@@ -301,6 +301,9 @@ my @Tests =
# https://bugs.gnu.org/34608
['date-century-plus', '-d @0 +.%+4C.', {OUT => '.+019.'}],
+ # https://bugs.gnu.org/50115
+ ['date-epoch-minus-1', '-u -d "1970-12-31T23:59:59+00:00 - 1 year"',
+ {OUT => 'Wed Dec 31 23:59:59 UTC 1969'}],
# Military time zones, new behavior (since 8.32)
# https://lists.gnu.org/r/bug-gnulib/2019-08/msg00005.html
--
2.32.0