Skip to content

Commit cfb1ac1

Browse files
committed
date: avoid overflow in approxidate relative-time multiplication
approxidate_alpha() multiplies a time unit length (e.g., 604800 for weeks) by a user-supplied number to compute a time offset in seconds. Both operands are int, and the product is passed to update_tm() as time_t. For inputs like "99999 weeks ago", the int multiplication overflows (604800 * 99999 = ~60 billion, far beyond INT_MAX), producing a wrapped value that results in a wrong date. Widen the operands to time_t before multiplying and use mult_overflows() to detect when even the wider product would overflow. On overflow, clamp to the maximum value of time_t (using is_unsigned_type to select the appropriate maximum). The clamped value causes update_tm to produce a date at the epoch boundary, which is a reasonable degraded behavior for an absurdly large relative offset. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 691459d commit cfb1ac1

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

date.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,13 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
12721272
while (tl->type) {
12731273
size_t len = strlen(tl->type);
12741274
if (match_string(date, tl->type) >= len-1) {
1275-
update_tm(tm, now, tl->length * *num);
1275+
time_t length = tl->length, num_t = *num;
1276+
time_t max_val = is_unsigned_type(length)
1277+
? maximum_unsigned_value_of_type(length)
1278+
: maximum_signed_value_of_type(length);
1279+
time_t seconds = mult_overflows(length, num_t)
1280+
? max_val : length * num_t;
1281+
update_tm(tm, now, seconds);
12761282
*num = 0;
12771283
*touched = 1;
12781284
return end;

0 commit comments

Comments
 (0)