git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Darcy Burke <acednes@gmail.com>
Subject: [PATCH v4 2/2] date: detect underflow/overflow when parsing dates with timezone offset
Date: Tue, 25 Jun 2024 16:12:48 -0700	[thread overview]
Message-ID: <20240625231248.4070257-3-gitster@pobox.com> (raw)
In-Reply-To: <20240625231248.4070257-1-gitster@pobox.com>

From: Darcy Burke <acednes@gmail.com>

Overriding the date of a commit to be close to "1970-01-01 00:00:00"
with a large enough positive timezone for the equivelant GMT time to be
before the epoch is considered valid by `parse_date_basic`. Similar
behaviour occurs when using a date close to "2099-12-31 23:59:59" (the
maximum date allowed by `tm_to_time_t`) with a large enough negative
timezone offset.

This leads to an integer underflow or underflow respectively in the
commit timestamp, which is not caught by `git-commit`, but will cause
other services to fail, such as `git-fsck`, which, for the first case,
reports "badDateOverflow: invalid author/committer line - date causes
integer overflow".

Instead check the timezone offset and fail if the resulting time comes
before the epoch "1970-01-01T00:00:00Z" or after the maximum date
"2099-12-31T23:59:59Z".

Using the REQUIRE_64BIT_TIME prerequisite, make sure that the tests
near the end of Git time (aka end of year 2099) are not attempted on
purely 32-bit systems, as they cannot express timestamp beyond 2038
anyway.

Signed-off-by: Darcy Burke <acednes@gmail.com>
[jc: fixups for 32-bit platforms]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 date.c          | 12 +++++++++++-
 t/t0006-date.sh | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/date.c b/date.c
index 7365a4ad24..bee9fe8f10 100644
--- a/date.c
+++ b/date.c
@@ -868,6 +868,10 @@ static int match_object_header_date(const char *date, timestamp_t *timestamp, in
 	return 0;
 }
 
+
+/* timestamp of 2099-12-31T23:59:59Z, including 32 leap days */
+static const timestamp_t timestamp_max = (((timestamp_t)2100 - 1970) * 365 + 32) * 24 * 60 * 60 - 1;
+
 /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
    (i.e. English) day/month names, and it doesn't work correctly with %z. */
 int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
@@ -937,8 +941,14 @@ int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
 		}
 	}
 
-	if (!tm_gmt)
+	if (!tm_gmt) {
+		if (*offset > 0 && *offset * 60 > *timestamp)
+			return -1;
+		if (*offset < 0 && -*offset * 60 > timestamp_max - *timestamp)
+			return -1;
 		*timestamp -= *offset * 60;
+	}
+
 	return 0; /* success */
 }
 
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 24e8647f26..fd373e1b39 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -123,6 +123,39 @@ check_parse '2008-02-14 20:30:45 -05:00' '2008-02-14 20:30:45 -0500'
 check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5
 check_parse 'Thu, 7 Apr 2005 15:14:13 -0700' '2005-04-07 15:14:13 -0700'
 
+check_parse '1970-01-01 00:00:00' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 +00' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 Z' '1970-01-01 00:00:00 +0000'
+check_parse '1970-01-01 00:00:00 -01' '1970-01-01 00:00:00 -0100'
+check_parse '1970-01-01 00:00:00 +01' bad
+check_parse '1970-01-01 00:00:00 +11' bad
+check_parse '1970-01-01 00:59:59 +01' bad
+check_parse '1970-01-01 01:00:00 +01' '1970-01-01 01:00:00 +0100'
+check_parse '1970-01-01 01:00:00 +11' bad
+check_parse '1970-01-02 00:00:00 +11' '1970-01-02 00:00:00 +1100'
+check_parse '1969-12-31 23:59:59' bad
+check_parse '1969-12-31 23:59:59 +00' bad
+check_parse '1969-12-31 23:59:59 Z' bad
+check_parse '1969-12-31 23:59:59 +11' bad
+check_parse '1969-12-31 23:59:59 -11' bad
+
+REQUIRE_64BIT_TIME=HAVE_64BIT_TIME
+check_parse '2099-12-31 23:59:59' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 +00' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 Z' '2099-12-31 23:59:59 +0000'
+check_parse '2099-12-31 23:59:59 +01' '2099-12-31 23:59:59 +0100'
+check_parse '2099-12-31 23:59:59 -01' bad
+check_parse '2099-12-31 23:59:59 -11' bad
+check_parse '2099-12-31 23:00:00 -01' bad
+check_parse '2099-12-31 22:59:59 -01' '2099-12-31 22:59:59 -0100'
+check_parse '2100-00-00 00:00:00' bad
+check_parse '2099-12-30 00:00:00 -11' '2099-12-30 00:00:00 -1100'
+check_parse '2100-00-00 00:00:00 +00' bad
+check_parse '2100-00-00 00:00:00 Z' bad
+check_parse '2100-00-00 00:00:00 -11' bad
+check_parse '2100-00-00 00:00:00 +11' bad
+REQUIRE_64BIT_TIME=
+
 check_approxidate() {
 	echo "$1 -> $2 +0000" >expect
 	test_expect_${3:-success} "parse approxidate ($1)" "
-- 
2.45.2-796-g2ef7a3d713


  parent reply	other threads:[~2024-06-25 23:13 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-27  9:17 [PATCH] fix: prevent date underflow when using positive timezone offset darcy via GitGitGadget
2024-05-28 14:05 ` Patrick Steinhardt
2024-05-28 14:49   ` Phillip Wood
2024-05-28 17:06   ` Junio C Hamano
2024-06-02 23:06 ` [PATCH v2] date: detect underflow when parsing dates with " darcy via GitGitGadget
2024-06-03 11:13   ` Junio C Hamano
2024-06-03 11:44     ` darcy
2024-06-03 14:13       ` Phillip Wood
2024-06-04  8:48         ` darcy
2024-06-04  9:33           ` Jeff King
2024-06-05  6:52             ` darcy
2024-06-05 13:10           ` Phillip Wood
2024-06-05 17:27             ` Junio C Hamano
2024-06-06  4:56               ` darcy
2024-06-07  0:17   ` [PATCH v3] date: detect underflow/overflow when parsing dates with " darcy via GitGitGadget
2024-06-07 17:40     ` Junio C Hamano
2024-06-08 18:58       ` Junio C Hamano
2024-06-14  1:20         ` Junio C Hamano
2024-06-15 11:47           ` Karthik Nayak
2024-06-11 23:30       ` Junio C Hamano
2024-06-11 23:49         ` rsbecker
2024-06-11 23:52           ` Junio C Hamano
2024-06-25 23:12         ` [PATCH v4 0/2] Darcy's "date underflow fix" topic, final reroll Junio C Hamano
2024-06-25 23:12           ` [PATCH v4 1/2] t0006: simplify prerequisites Junio C Hamano
2024-06-25 23:30             ` Eric Sunshine
2024-06-26  0:04               ` Junio C Hamano
2024-06-25 23:12           ` Junio C Hamano [this message]
2024-06-26 15:21           ` [PATCH v4 0/2] Darcy's "date underflow fix" topic, final reroll Phillip Wood
2024-06-26 18:32             ` Junio C Hamano
2024-06-12  9:07       ` [PATCH v3] date: detect underflow/overflow when parsing dates with timezone offset Phillip Wood
2024-06-12  9:49     ` Karthik Nayak
2024-06-13 13:31       ` Phillip Wood
2024-06-13 16:16         ` Junio C Hamano
2024-06-14 20:09           ` Karthik Nayak
2024-06-14 21:02             ` Junio C Hamano
2024-06-15 11:49               ` Karthik Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240625231248.4070257-3-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=acednes@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).