Commit d83851dae86 for php.net
commit d83851dae86dbfbf4370ec42750b606e79de7ac3
Author: Derick Rethans <github@derickrethans.nl>
Date: Thu Jul 9 15:29:05 2026 +0100
Update timelib to 2022.17, which has fixes for PHP bugs
diff --git a/NEWS b/NEWS
index cdd6a48a487..d64ce32ab99 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,13 @@ PHP NEWS
. Fixed bug GH-22602 (gregoriantojd() and juliantojd() integer overflow with
INT_MAX year). (arshidkv12)
+- Date:
+ . Update timelib to 2022.17. (Derick)
+ . Fixed bug GH-19803 (Parsing a string with a single white space does create
+ an error). (Derick)
+ . Fixed Unix timestamps in February of the year 0 are misparsed with
+ @-notation. (LukasGelbmann)
+
- DBA:
. Fixed OOB read on malformed length field in dba flatfile handler. (alhudz)
diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re
index f4a39275324..07d9c0e7348 100644
--- a/ext/date/lib/parse_date.re
+++ b/ext/date/lib/parse_date.re
@@ -555,7 +555,6 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l
int len = 0;
/* Skip over non-numeric chars */
-
while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
if (**ptr == '\0') {
add_error(s, TIMELIB_ERR_UNEXPECTED_DATA, "Found unexpected data");
@@ -569,6 +568,7 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l
str[0] = '+'; /* First position is the sign */
str_ptr = str + 1;
+
while ((**ptr == '+') || (**ptr == '-')) {
if (**ptr == '-') {
str[0] = str[0] == '+' ? '-' : '+';
@@ -2020,7 +2020,7 @@ timelib_time *timelib_strtotime(const char *s, size_t len, timelib_error_contain
in.errors->error_messages = NULL;
if (len > 0) {
- while (isspace((unsigned char)*s) && s < e) {
+ while (isspace((unsigned char)*s) && s <= e) {
s++;
}
while (isspace((unsigned char)*e) && e > s) {
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h
index acae8e32533..d08aa77ea5e 100644
--- a/ext/date/lib/timelib.h
+++ b/ext/date/lib/timelib.h
@@ -30,9 +30,9 @@
# include "timelib_config.h"
#endif
-#define TIMELIB_VERSION 202215
-#define TIMELIB_EXTENDED_VERSION 20221501
-#define TIMELIB_ASCII_VERSION "2022.15"
+#define TIMELIB_VERSION 202217
+#define TIMELIB_EXTENDED_VERSION 20221701
+#define TIMELIB_ASCII_VERSION "2022.17"
#include <stdlib.h>
#include <stdbool.h>
diff --git a/ext/date/lib/timelib_private.h b/ext/date/lib/timelib_private.h
index 3c5f9b22147..42cbaa68dbb 100644
--- a/ext/date/lib/timelib_private.h
+++ b/ext/date/lib/timelib_private.h
@@ -135,6 +135,7 @@
#ifndef TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW
# define TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW 0
#endif
+
struct _ttinfo
{
int32_t offset;
@@ -165,6 +166,7 @@ extern "C" {
#endif
/* From unixtime2tm.c */
+void timelib_date_from_epoch_days(timelib_sll epoch_days, timelib_sll *y, timelib_sll *m, timelib_sll *d);
int timelib_apply_localtime(timelib_time *t, unsigned int localtime);
/* From parse_posix.c */
diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c
index f13a9412406..4c0252e244d 100644
--- a/ext/date/lib/tm2unixtime.c
+++ b/ext/date/lib/tm2unixtime.c
@@ -197,32 +197,6 @@ void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt)
do_range_limit(0, 12, 12, &rt->m, &rt->y);
}
-static void magic_date_calc(timelib_time *time)
-{
- timelib_sll y, ddd, mi, mm, dd, g;
-
- /* The algorithm doesn't work before the year 1 */
- if (time->d < -719498) {
- return;
- }
-
- g = time->d + HINNANT_EPOCH_SHIFT - 1;
-
- y = (10000 * g + 14780) / 3652425;
- ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
- if (ddd < 0) {
- y--;
- ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
- }
- mi = (100 * ddd + 52) / 3060;
- mm = ((mi + 2) % 12) + 1;
- y = y + (mi + 2) / 12;
- dd = ddd - ((mi * 306 + 5) / 10) + 1;
- time->y = y;
- time->m = mm;
- time->d = dd;
-}
-
void timelib_do_normalize(timelib_time* time)
{
if (time->us != TIMELIB_UNSET) do_range_limit(0, 1000000, 1000000, &time->us, &time->s);
@@ -232,8 +206,9 @@ void timelib_do_normalize(timelib_time* time)
do_range_limit(1, 13, 12, &time->m, &time->y);
/* Short cut if we're doing things against the Epoch */
- if (time->y == 1970 && time->m == 1 && time->d != 1) {
- magic_date_calc(time);
+ if (time->y == 1970 && time->m == 1) {
+ timelib_date_from_epoch_days(time->d - 1, &time->y, &time->m, &time->d);
+ return;
}
do {} while (do_range_limit_days(&time->y, &time->m, &time->d));
diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c
index 30b3d00c7f4..9c4ba901a93 100644
--- a/ext/date/lib/unixtime2tm.c
+++ b/ext/date/lib/unixtime2tm.c
@@ -26,20 +26,16 @@
#include "timelib.h"
#include "timelib_private.h"
-void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timelib_sll *d)
+/* Converts Unix epoch days (days since 1970-01-01) to a date. Algorithm from:
+ * http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
+void timelib_date_from_epoch_days(timelib_sll epoch_days, timelib_sll *y, timelib_sll *m, timelib_sll *d)
{
- timelib_sll days, era, t;
+ timelib_sll days, era;
timelib_ull day_of_era, year_of_era, day_of_year, month_portion;
/* Calculate days since algorithm's epoch (0000-03-01) */
- days = ts / SECS_PER_DAY + HINNANT_EPOCH_SHIFT;
-
- /* Adjustment for a negative time portion */
- t = ts % SECS_PER_DAY;
- days += (t < 0) ? -1 : 0;
+ days = epoch_days + HINNANT_EPOCH_SHIFT;
- /* Calculate year, month, and day. Algorithm from:
- * http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
era = (days >= 0 ? days : days - DAYS_PER_ERA + 1) / DAYS_PER_ERA;
day_of_era = days - era * DAYS_PER_ERA;
year_of_era = (day_of_era - day_of_era / 1460 + day_of_era / 36524 - day_of_era / 146096) / DAYS_PER_YEAR;
@@ -49,6 +45,19 @@ void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timel
*d = day_of_year - (153 * month_portion + 2) / 5 + 1;
*m = month_portion + (month_portion < 10 ? 3 : -9);
*y += (*m <= 2);
+}
+
+void timelib_unixtime2date(timelib_sll ts, timelib_sll *y, timelib_sll *m, timelib_sll *d)
+{
+ timelib_sll epoch_days, t;
+
+ epoch_days = ts / SECS_PER_DAY;
+
+ /* Adjustment for a negative time portion */
+ t = ts % SECS_PER_DAY;
+ epoch_days += (t < 0) ? -1 : 0;
+
+ timelib_date_from_epoch_days(epoch_days, y, m, d);
TIMELIB_DEBUG(printf("A: ts=%lld, year=%lld, month=%lld, day=%lld,", ts, *y, *m, *d););
}