Subject: Re: [PATCH v3] date: detect underflow/overflow when parsing dates with timezone offset

From: Junio C Hamano <[email-masked]>
Date: Fri, 07 Jun 2024 10:40:03 -0700

"darcy via GitGitGadget" <[email-masked]> writes:

> From: darcy <[email-masked]>

This ident should match what is used on "Signed-off-by:" line.

> 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

"underflow or underflow respectively"?

> 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".

Nicely described otherwise.

> +
> +/* timestamp of 2099-12-31T23:59:59Z, including 32 leap days */
> +static const time_t timestamp_max = ((2100L - 1970) * 365 + 32) * 24 * 60 * 60 - 1;

I wonder if this should be of timestamp_t type instead, as the check
is done against *timestamp in parse_date_basic() where *timestamp is
of type timestamp_t to match?

>  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 */
>  }

Thanks.