[php-src] PHP-8.4: Update timelib to 2022.17, which has fixes for PHP bugs

Derick Rethans <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Derick Rethans (derickr)
Date: 2026-07-09T15:29:05+01:00

Commit: https://github.com/php/php-src/commit/d83851dae86dbfbf4370ec42750b606e79de7ac3
Raw diff: https://github.com/php/php-src/commit/d83851dae86dbfbf4370ec42750b606e79de7ac3.diff

Update timelib to 2022.17, which has fixes for PHP bugs

Changed paths:
  M  NEWS
  M  ext/date/lib/parse_date.re
  M  ext/date/lib/timelib.h
  M  ext/date/lib/timelib_private.h
  M  ext/date/lib/tm2unixtime.c
  M  ext/date/lib/unixtime2tm.c


Diff:

diff --git a/NEWS b/NEWS
index cdd6a48a4874..d64ce32ab995 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 f4a392753249..07d9c0e73488 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 acae8e32533d..d08aa77ea5e5 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 3c5f9b22147c..42cbaa68dbbf 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 f13a9412406f..4c0252e244dd 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 30b3d00c7f44..9c4ba901a93d 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););
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.