Skip to content

Commit 4ce00aa

Browse files
committed
Merge branch 'PHP-8.2'
2 parents f06da77 + 629d774 commit 4ce00aa

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

ext/date/lib/timelib.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
# include "timelib_config.h"
3131
#endif
3232

33-
#define TIMELIB_VERSION 202206
34-
#define TIMELIB_EXTENDED_VERSION 20220601
35-
#define TIMELIB_ASCII_VERSION "2022.06"
33+
#define TIMELIB_VERSION 202207
34+
#define TIMELIB_EXTENDED_VERSION 20220701
35+
#define TIMELIB_ASCII_VERSION "2022.07"
3636

3737
#include <stdlib.h>
3838
#include <stdbool.h>

ext/date/lib/tm2unixtime.c

+19-5
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,16 @@ static int days_in_month[13] = { 31, 31, 28, 31, 30, 31, 30, 31, 3
3232
static void do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, timelib_sll *a, timelib_sll *b)
3333
{
3434
if (*a < start) {
35-
*b -= (start - *a - 1) / adj + 1;
36-
*a += adj * ((start - *a - 1) / adj + 1);
35+
/* We calculate 'a + 1' first as 'start - *a - 1' causes an int64_t overflows if *a is
36+
* LONG_MIN. 'start' is 0 in this context, and '0 - LONG_MIN > LONG_MAX'. */
37+
timelib_sll a_plus_1 = *a + 1;
38+
39+
*b -= (start - a_plus_1) / adj + 1;
40+
41+
/* This code add the extra 'adj' separately, as otherwise this can overflow int64_t in
42+
* situations where *b is near LONG_MIN. */
43+
*a += adj * ((start - a_plus_1) / adj);
44+
*a += adj;
3745
}
3846
if (*a >= end) {
3947
*b += *a / adj;
@@ -462,9 +470,15 @@ void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi)
462470
do_adjust_relative(time);
463471
do_adjust_special(time);
464472

465-
time->sse =
466-
(timelib_epoch_days_from_time(time) * SECS_PER_DAY) +
467-
timelib_hms_to_seconds(time->h, time->i, time->s);
473+
/* You might be wondering, why this code does this in two steps. This is because
474+
* timelib_epoch_days_from_time(time) * SECS_PER_DAY with the lowest limit of
475+
* timelib_epoch_days_from_time() is less than the range of an int64_t. This then overflows. In
476+
* order to be able to still allow for any time in that day that only halfly fits in the int64_t
477+
* range, we add the time element first, which is always positive, and then twice half the value
478+
* of the earliest day as expressed as unix timestamp. */
479+
time->sse = timelib_hms_to_seconds(time->h, time->i, time->s);
480+
time->sse += timelib_epoch_days_from_time(time) * (SECS_PER_DAY / 2);
481+
time->sse += timelib_epoch_days_from_time(time) * (SECS_PER_DAY / 2);
468482

469483
// This modifies time->sse, if needed
470484
do_adjust_timezone(time, tzi);

0 commit comments

Comments
 (0)