From 8c417f16dc08303619cc733c18e5275549223f83 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 25 Sep 2025 09:44:57 +0200 Subject: update to 8.5.0RC1 bump ABI/API numbers to 20240925 drop opcache subpackage, extension is build statically add lexbor and uri extension (always static) move /usr/share/fpm/status.html to /usr/share/php/fpm/status.html --- 10-opcache.ini | 14 +- failed.txt | 28 +- php-8.3.0-openssl-ec-param.patch | 47 --- php-8.3.3-parser.patch | 16 - php-8.4.0-ldap_r.patch | 19 - php-8.4.0-systzdata-v24.patch | 742 --------------------------------------- php-8.4.6-embed.patch | 43 --- php-8.5.0-embed.patch | 30 ++ php-8.5.0-ldap_r.patch | 19 + php-8.5.0-openssl-ec-param.patch | 35 ++ php-8.5.0-parser.patch | 16 + php-8.5.0-systzdata-v24.patch | 742 +++++++++++++++++++++++++++++++++++++++ php.ini | 106 +++--- php85.spec | 251 +++++++------ 14 files changed, 1061 insertions(+), 1047 deletions(-) delete mode 100644 php-8.3.0-openssl-ec-param.patch delete mode 100644 php-8.3.3-parser.patch delete mode 100644 php-8.4.0-ldap_r.patch delete mode 100644 php-8.4.0-systzdata-v24.patch delete mode 100644 php-8.4.6-embed.patch create mode 100644 php-8.5.0-embed.patch create mode 100644 php-8.5.0-ldap_r.patch create mode 100644 php-8.5.0-openssl-ec-param.patch create mode 100644 php-8.5.0-parser.patch create mode 100644 php-8.5.0-systzdata-v24.patch diff --git a/10-opcache.ini b/10-opcache.ini index b3d4e6e..252303a 100644 --- a/10-opcache.ini +++ b/10-opcache.ini @@ -1,6 +1,3 @@ -; Enable Zend OPcache extension module -zend_extension=opcache - ; Determines if Zend OPCache is enabled opcache.enable=1 @@ -54,8 +51,6 @@ opcache.enable_cli=1 ; passes ;opcache.optimization_level=0x7FFFBFFF -; This hack should only be enabled to work around "Cannot redeclare class" -; errors. ;opcache.dups_fix=0 ; The location of the OPcache blacklist file (wildcards allowed). @@ -99,6 +94,15 @@ opcache.blacklist_filename=/etc/php.d/opcache*.blacklist ; for php-fpm, see /etc/php-fpm.d/*conf ;opcache.file_cache= +; Enables or disables read-only mode for the second level cache directory. +; It should improve performance for read-only containers, +; when the cache is pre-warmed and packaged alongside the application. +; Best used with `opcache.validate_timestamps=0`, `opcache.enable_file_override=1` +; and `opcache.file_cache_consistency_checks=0`. +; Note: A cache generated with a different build of PHP, a different file path, +; or different settings (including which extensions are loaded), may be ignored. +;opcache.file_cache_read_only=0 + ; Enables or disables opcode caching in shared memory. ;opcache.file_cache_only=0 diff --git a/failed.txt b/failed.txt index 8134818..585d11b 100644 --- a/failed.txt +++ b/failed.txt @@ -1,23 +1,21 @@ -===== 8.4.13 (2025-09-25) +===== 8.5.0RC1 (2025-09-25) $ grep -ar 'Tests failed' /var/lib/mock/*/build.log -/var/lib/mock/el8a84/build.log:Tests failed : 1 -/var/lib/mock/el8x84/build.log:Tests failed : 1 -/var/lib/mock/el9a84/build.log:Tests failed : 1 -/var/lib/mock/el9x84/build.log:Tests failed : 1 -/var/lib/mock/el10a84/build.log:Tests failed : 1 -/var/lib/mock/el10x84/build.log:Tests failed : 1 -/var/lib/mock/fc41a84/build.log:Tests failed : 1 -/var/lib/mock/fc41x84/build.log:Tests failed : 1 -/var/lib/mock/fc42a84/build.log:Tests failed : 1 -/var/lib/mock/fc42x84/build.log:Tests failed : 1 -/var/lib/mock/fc43a84/build.log:Tests failed : 1 -/var/lib/mock/fc43x84/build.log:Tests failed : 1 +/var/lib/mock/el8a85/build.log:Tests failed : 0 +/var/lib/mock/el8x85/build.log:Tests failed : 0 +/var/lib/mock/el9a85/build.log:Tests failed : 0 +/var/lib/mock/el9x85/build.log:Tests failed : 0 +/var/lib/mock/el10a85/build.log:Tests failed : 0 +/var/lib/mock/el10x85/build.log:Tests failed : 0 +/var/lib/mock/fc41a85/build.log:Tests failed : 0 +/var/lib/mock/fc41x85/build.log:Tests failed : 0 +/var/lib/mock/fc42a85/build.log:Tests failed : 0 +/var/lib/mock/fc42x85/build.log:Tests failed : 0 +/var/lib/mock/fc43a85/build.log:Tests failed : 0 +/var/lib/mock/fc43x85/build.log:Tests failed : 0 -all - 2 sapi/cli/tests/php_cli_server_ipv4_error_message.phpt 1 proc_open give erratic test results :( diff --git a/php-8.3.0-openssl-ec-param.patch b/php-8.3.0-openssl-ec-param.patch deleted file mode 100644 index 94e4037..0000000 --- a/php-8.3.0-openssl-ec-param.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 21f9d16e130b412b6839494dcf30a2f1d7dcee0f Mon Sep 17 00:00:00 2001 -From: Remi Collet -Date: Mon, 24 Jul 2023 10:54:49 +0200 -Subject: [PATCH] Always warn about missing curve_name - -Both Fedora and RHEL do not support arbitrary EC parameters -See https://bugzilla.redhat.com/2223953 ---- - ext/openssl/openssl.c | 13 ++----------- - 1 file changed, 2 insertions(+), 11 deletions(-) - -diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c -index 33f51bfa4d..340b0467d3 100644 ---- a/ext/openssl/openssl.c -+++ b/ext/openssl/openssl.c -@@ -4299,13 +4299,8 @@ static bool php_openssl_pkey_init_legacy_ec(EC_KEY *eckey, zval *data, bool *is_ - OPENSSL_PKEY_SET_BN(data, b); - OPENSSL_PKEY_SET_BN(data, order); - -+ php_error_docref(NULL, E_WARNING, "Missing params: curve_name (params only is not supported by OpenSSL)"); - if (!(p && a && b && order)) { -- if (!p && !a && !b && !order) { -- php_error_docref(NULL, E_WARNING, "Missing params: curve_name"); -- } else { -- php_error_docref( -- NULL, E_WARNING, "Missing params: curve_name or p, a, b, order"); -- } - goto clean_exit; - } - -@@ -4455,12 +4450,8 @@ static EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) { - OPENSSL_PKEY_SET_BN(data, b); - OPENSSL_PKEY_SET_BN(data, order); - -+ php_error_docref(NULL, E_WARNING, "Missing params: curve_name"); - if (!(p && a && b && order)) { -- if (!p && !a && !b && !order) { -- php_error_docref(NULL, E_WARNING, "Missing params: curve_name"); -- } else { -- php_error_docref(NULL, E_WARNING, "Missing params: curve_name or p, a, b, order"); -- } - goto cleanup; - } - --- -2.41.0 - diff --git a/php-8.3.3-parser.patch b/php-8.3.3-parser.patch deleted file mode 100644 index 49f7d5e..0000000 --- a/php-8.3.3-parser.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -up ./build/gen_stub.php.syslib ./build/gen_stub.php ---- ./build/gen_stub.php.syslib 2020-06-25 08:11:51.782046813 +0200 -+++ ./build/gen_stub.php 2020-06-25 08:13:11.188860368 +0200 -@@ -3265,6 +3265,12 @@ function initPhpParser() { - } - - $isInitialized = true; -+ -+ if (file_exists('/usr/share/php/PhpParser5/autoload.php')) { -+ require_once '/usr/share/php/PhpParser5/autoload.php'; -+ return; -+ } -+ - $version = "5.0.0"; - $phpParserDir = __DIR__ . "/PHP-Parser-$version"; - if (!is_dir($phpParserDir)) { diff --git a/php-8.4.0-ldap_r.patch b/php-8.4.0-ldap_r.patch deleted file mode 100644 index a574751..0000000 --- a/php-8.4.0-ldap_r.patch +++ /dev/null @@ -1,19 +0,0 @@ - -Use -lldap_r by default. - -diff -up php-8.4.0beta1/ext/ldap/config.m4.ldap_r php-8.4.0beta1/ext/ldap/config.m4 ---- php-8.4.0beta1/ext/ldap/config.m4.ldap_r 2024-08-13 15:48:12.000000000 +0200 -+++ php-8.4.0beta1/ext/ldap/config.m4 2024-08-13 16:23:24.744311776 +0200 -@@ -72,7 +72,11 @@ if test "$PHP_LDAP" != "no"; then - AH_TEMPLATE([HAVE_ORALDAP], - [Define to 1 if the ldap extension uses the Oracle Instant Client.]) - -- if test -f $LDAP_LIBDIR/liblber.a || test -f $LDAP_LIBDIR/liblber.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.a || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.$SHLIB_SUFFIX_NAME; then -+ if test -f $LDAP_LIBDIR/libldap_r.$SHLIB_SUFFIX_NAME; then -+ PHP_ADD_LIBRARY_WITH_PATH(lber, [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) -+ PHP_ADD_LIBRARY_WITH_PATH(ldap_r, [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) -+ -+ elif test -f $LDAP_LIBDIR/liblber.a || test -f $LDAP_LIBDIR/liblber.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.a || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.$SHLIB_SUFFIX_NAME; then - PHP_ADD_LIBRARY_WITH_PATH([lber], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) - PHP_ADD_LIBRARY_WITH_PATH([ldap], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) - diff --git a/php-8.4.0-systzdata-v24.patch b/php-8.4.0-systzdata-v24.patch deleted file mode 100644 index 6176a8b..0000000 --- a/php-8.4.0-systzdata-v24.patch +++ /dev/null @@ -1,742 +0,0 @@ -# License: MIT -# http://opensource.org/licenses/MIT - -Add support for use of the system timezone database, rather -than embedding a copy. Discussed upstream but was not desired. - -History: -r24: add internal UTC if tzdata is missing -r23: fix possible buffer overflow -r22: retrieve tzdata version from /usr/share/zoneinfo/tzdata.zi -r21: adapt for timelib 2021.03 (in 8.1.0) -r20: adapt for timelib 2020.03 (in 8.0.10RC1) -r19: adapt for timelib 2020.02 (in 8.0.0beta2) -r18: adapt for autotool change in 7.3.3RC1 -r17: adapt for timelib 2018.01 (in 7.3.2RC1) -r16: adapt for timelib 2017.06 (in 7.2.3RC1) -r15: adapt for timelib 2017.05beta7 (in 7.2.0RC1) -r14: improve check for valid tz file -r13: adapt for upstream changes to use PHP allocator -r12: adapt for upstream changes for new zic -r11: use canonical names to avoid more case sensitivity issues - round lat/long from zone.tab towards zero per builtin db -r10: make timezone case insensitive -r9: fix another compile error without --with-system-tzdata configured (Michael Heimpold) -r8: fix compile error without --with-system-tzdata configured -r7: improve check for valid timezone id to exclude directories -r6: fix fd leak in r5, fix country code/BC flag use in - timezone_identifiers_list() using system db, - fix use of PECL timezonedb to override system db, -r5: reverts addition of "System/Localtime" fake tzname. - updated for 5.3.0, parses zone.tab to pick up mapping between - timezone name, country code and long/lat coords -r4: added "System/Localtime" tzname which uses /etc/localtime -r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert) -r2: add filesystem trawl to set up name alias index -r1: initial revision - - -diff -up ./ext/date/config0.m4.systzdata ./ext/date/config0.m4 ---- ./ext/date/config0.m4.systzdata 2024-07-03 16:21:20.240786848 +0200 -+++ ./ext/date/config0.m4 2024-07-03 16:25:14.838995464 +0200 -@@ -8,6 +8,18 @@ - [PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) - -+PHP_ARG_WITH(system-tzdata, for use of system timezone data, -+ [AS_HELP_STRING([--with-system-tzdata[=DIR]],[to specify use of system timezone data])], no, no) -+ -+if test "$PHP_SYSTEM_TZDATA" != "no"; then -+ AC_DEFINE(HAVE_SYSTEM_TZDATA, 1, [Define if system timezone data is used]) -+ -+ if test "$PHP_SYSTEM_TZDATA" != "yes"; then -+ AC_DEFINE_UNQUOTED(HAVE_SYSTEM_TZDATA_PREFIX, "$PHP_SYSTEM_TZDATA", -+ [Define for location of system timezone data]) -+ fi -+fi -+ - PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1" - timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c lib/parse_posix.c - lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c" -diff -up ./ext/date/lib/parse_tz.c.systzdata ./ext/date/lib/parse_tz.c ---- ./ext/date/lib/parse_tz.c.systzdata 2024-07-02 15:43:13.000000000 +0200 -+++ ./ext/date/lib/parse_tz.c 2024-07-03 16:21:20.240786848 +0200 -@@ -26,9 +26,33 @@ - #include "timelib.h" - #include "timelib_private.h" - -+#ifdef HAVE_SYSTEM_TZDATA -+#include -+#include -+#include -+#include -+#include -+ -+#include "php_scandir.h" -+ -+static const unsigned char internal_utc[] = { -+ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x0a, 0x55, 0x54, 0x43, -+ 0x30, 0x0a -+}; -+ -+#else - #define TIMELIB_SUPPORTS_V2DATA - #define TIMELIB_SUPPORT_SLIM_FILE - #include "timezonedb.h" -+#endif -+ -+#include - - #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) - # if defined(__LITTLE_ENDIAN__) -@@ -95,6 +119,11 @@ static int read_php_preamble(const unsig - { - uint32_t version; - -+ if (memcmp(*tzf, "TZif", 4) == 0) { -+ *tzf += 20; -+ return 0; -+ } -+ - /* read ID */ - version = (*tzf)[3] - '0'; - *tzf += 4; -@@ -577,7 +606,475 @@ void timelib_dump_tzinfo(timelib_tzinfo - } - } - --static int seek_to_tz_position(const unsigned char **tzf, const char *timezone, const timelib_tzdb *tzdb) -+#ifdef HAVE_SYSTEM_TZDATA -+ -+#ifdef HAVE_SYSTEM_TZDATA_PREFIX -+#define ZONEINFO_PREFIX HAVE_SYSTEM_TZDATA_PREFIX -+#else -+#define ZONEINFO_PREFIX "/usr/share/zoneinfo" -+#endif -+ -+/* System timezone database pointer. */ -+static const timelib_tzdb *timezonedb_system; -+ -+/* Hash table entry for the cache of the zone.tab mapping table. */ -+struct location_info { -+ char code[2]; -+ double latitude, longitude; -+ char name[64]; -+ char *comment; -+ struct location_info *next; -+}; -+ -+/* Cache of zone.tab. */ -+static struct location_info **system_location_table; -+ -+/* Size of the zone.tab hash table; a random-ish prime big enough to -+ * prevent too many collisions. */ -+#define LOCINFO_HASH_SIZE (1021) -+ -+/* Compute a case insensitive hash of str */ -+static uint32_t tz_hash(const char *str) -+{ -+ const unsigned char *p = (const unsigned char *)str; -+ uint32_t hash = 5381; -+ int c; -+ -+ while ((c = tolower(*p++)) != '\0') { -+ hash = (hash << 5) ^ hash ^ c; -+ } -+ -+ return hash % LOCINFO_HASH_SIZE; -+} -+ -+/* Parse an ISO-6709 date as used in zone.tab. Returns end of the -+ * parsed string on success, or NULL on parse error. On success, -+ * writes the parsed number to *result. */ -+static char *parse_iso6709(char *p, double *result) -+{ -+ double v, sign; -+ char *pend; -+ size_t len; -+ -+ if (*p == '+') -+ sign = 1.0; -+ else if (*p == '-') -+ sign = -1.0; -+ else -+ return NULL; -+ -+ p++; -+ for (pend = p; *pend >= '0' && *pend <= '9'; pend++) -+ ;; -+ -+ /* Annoying encoding used by zone.tab has no decimal point, so use -+ * the length to determine the format: -+ * -+ * 4 = DDMM -+ * 5 = DDDMM -+ * 6 = DDMMSS -+ * 7 = DDDMMSS -+ */ -+ len = pend - p; -+ if (len < 4 || len > 7) { -+ return NULL; -+ } -+ -+ /* p => [D]DD */ -+ v = (p[0] - '0') * 10.0 + (p[1] - '0'); -+ p += 2; -+ if (len == 5 || len == 7) -+ v = v * 10.0 + (*p++ - '0'); -+ /* p => MM[SS] */ -+ v += (10.0 * (p[0] - '0') -+ + p[1] - '0') / 60.0; -+ p += 2; -+ /* p => [SS] */ -+ if (len > 5) { -+ v += (10.0 * (p[0] - '0') -+ + p[1] - '0') / 3600.0; -+ p += 2; -+ } -+ -+ /* Round to five decimal place, not because it's a good idea, -+ * but, because the builtin data uses rounded data, so, match -+ * that. */ -+ *result = trunc(v * sign * 100000.0) / 100000.0; -+ -+ return p; -+} -+ -+/* This function parses the zone.tab file to build up the mapping of -+ * timezone to country code and geographic location, and returns a -+ * hash table. The hash table is indexed by the function: -+ * -+ * tz_hash(timezone-name) -+ */ -+static struct location_info **create_location_table(void) -+{ -+ struct location_info **li, *i; -+ char zone_tab[PATH_MAX]; -+ char line[512]; -+ FILE *fp; -+ -+ strncpy(zone_tab, ZONEINFO_PREFIX "/zone.tab", sizeof zone_tab); -+ -+ fp = fopen(zone_tab, "r"); -+ if (!fp) { -+ return NULL; -+ } -+ -+ li = calloc(LOCINFO_HASH_SIZE, sizeof *li); -+ -+ while (fgets(line, sizeof line, fp)) { -+ char *p = line, *code, *name, *comment; -+ uint32_t hash; -+ double latitude, longitude; -+ -+ while (isspace(*p)) -+ p++; -+ -+ if (*p == '#' || *p == '\0' || *p == '\n') -+ continue; -+ -+ if (!isalpha(p[0]) || !isalpha(p[1]) || p[2] != '\t') -+ continue; -+ -+ /* code => AA */ -+ code = p; -+ p[2] = 0; -+ p += 3; -+ -+ /* coords => [+-][D]DDMM[SS][+-][D]DDMM[SS] */ -+ p = parse_iso6709(p, &latitude); -+ if (!p) { -+ continue; -+ } -+ p = parse_iso6709(p, &longitude); -+ if (!p) { -+ continue; -+ } -+ -+ if (!p || *p != '\t') { -+ continue; -+ } -+ -+ /* name = string */ -+ name = ++p; -+ while (*p != '\t' && *p && *p != '\n') -+ p++; -+ -+ *p++ = '\0'; -+ -+ /* comment = string */ -+ comment = p; -+ while (*p != '\t' && *p && *p != '\n') -+ p++; -+ -+ if (*p == '\n' || *p == '\t') -+ *p = '\0'; -+ -+ hash = tz_hash(name); -+ i = malloc(sizeof *i); -+ memcpy(i->code, code, 2); -+ strncpy(i->name, name, sizeof i->name); -+ i->comment = strdup(comment); -+ i->longitude = longitude; -+ i->latitude = latitude; -+ i->next = li[hash]; -+ li[hash] = i; -+ /* printf("%s [%u, %f, %f]\n", name, hash, latitude, longitude); */ -+ } -+ -+ fclose(fp); -+ -+ return li; -+} -+ -+/* Return location info from hash table, using given timezone name. -+ * Returns NULL if the name could not be found. */ -+const struct location_info *find_zone_info(struct location_info **li, -+ const char *name) -+{ -+ uint32_t hash = tz_hash(name); -+ const struct location_info *l; -+ -+ if (!li) { -+ return NULL; -+ } -+ -+ for (l = li[hash]; l; l = l->next) { -+ if (timelib_strcasecmp(l->name, name) == 0) -+ return l; -+ } -+ -+ return NULL; -+} -+ -+/* Filter out some non-tzdata files and the posix/right databases, if -+ * present. */ -+static int index_filter(const struct dirent *ent) -+{ -+ return strcmp(ent->d_name, ".") != 0 -+ && strcmp(ent->d_name, "..") != 0 -+ && strcmp(ent->d_name, "posix") != 0 -+ && strcmp(ent->d_name, "posixrules") != 0 -+ && strcmp(ent->d_name, "right") != 0 -+ && strstr(ent->d_name, ".list") == NULL -+ && strstr(ent->d_name, ".tab") == NULL; -+} -+ -+static int sysdbcmp(const void *first, const void *second) -+{ -+ const timelib_tzdb_index_entry *alpha = first, *beta = second; -+ -+ return timelib_strcasecmp(alpha->id, beta->id); -+} -+ -+/* Retrieve tzdata version. */ -+static void retrieve_zone_version(timelib_tzdb *db) -+{ -+ static char buf[30]; -+ char path[PATH_MAX]; -+ FILE *fp; -+ -+ strncpy(path, ZONEINFO_PREFIX "/tzdata.zi", sizeof(path)); -+ -+ fp = fopen(path, "r"); -+ if (fp) { -+ if (fgets(buf, sizeof(buf), fp)) { -+ if (!memcmp(buf, "# version ", 10) && -+ isdigit(buf[10]) && -+ isdigit(buf[11]) && -+ isdigit(buf[12]) && -+ isdigit(buf[13]) && -+ islower(buf[14])) { -+ if (buf[14] >= 't') { /* 2022t = 2022.20 */ -+ buf[17] = 0; -+ buf[16] = buf[14] - 't' + '0'; -+ buf[15] = '2'; -+ } else if (buf[14] >= 'j') { /* 2022j = 2022.10 */ -+ buf[17] = 0; -+ buf[16] = buf[14] - 'j' + '0'; -+ buf[15] = '1'; -+ } else { /* 2022a = 2022.1 */ -+ buf[16] = 0; -+ buf[15] = buf[14] - 'a' + '1'; -+ } -+ buf[14] = '.'; -+ db->version = buf+10; -+ } -+ } -+ fclose(fp); -+ } -+} -+ -+ -+/* Create the zone identifier index by trawling the filesystem. */ -+static void create_zone_index(timelib_tzdb *db) -+{ -+ size_t dirstack_size, dirstack_top; -+ size_t index_size, index_next; -+ timelib_tzdb_index_entry *db_index; -+ char **dirstack; -+ -+ /* LIFO stack to hold directory entries to scan; each slot is a -+ * directory name relative to the zoneinfo prefix. */ -+ dirstack_size = 32; -+ dirstack = malloc(dirstack_size * sizeof *dirstack); -+ dirstack_top = 1; -+ dirstack[0] = strdup(""); -+ -+ /* Index array. */ -+ index_size = 64; -+ db_index = malloc(index_size * sizeof *db_index); -+ index_next = 0; -+ -+ do { -+ struct dirent **ents; -+ char name[PATH_MAX], *top; -+ int count; -+ -+ /* Pop the top stack entry, and iterate through its contents. */ -+ top = dirstack[--dirstack_top]; -+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s", top); -+ -+ count = php_scandir(name, &ents, index_filter, php_alphasort); -+ -+ while (count > 0) { -+ struct stat st; -+ const char *leaf = ents[count - 1]->d_name; -+ -+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s/%s", -+ top, leaf); -+ -+ if (strlen(name) && stat(name, &st) == 0) { -+ /* Name, relative to the zoneinfo prefix. */ -+ const char *root = top; -+ -+ if (root[0] == '/') root++; -+ -+ snprintf(name, sizeof name, "%s%s%s", root, -+ *root ? "/": "", leaf); -+ -+ if (S_ISDIR(st.st_mode)) { -+ if (dirstack_top == dirstack_size) { -+ dirstack_size *= 2; -+ dirstack = realloc(dirstack, -+ dirstack_size * sizeof *dirstack); -+ } -+ dirstack[dirstack_top++] = strdup(name); -+ } -+ else { -+ if (index_next == index_size) { -+ index_size *= 2; -+ db_index = realloc(db_index, -+ index_size * sizeof *db_index); -+ } -+ -+ db_index[index_next++].id = strdup(name); -+ } -+ } -+ -+ free(ents[--count]); -+ } -+ -+ if (count != -1) free(ents); -+ free(top); -+ } while (dirstack_top); -+ -+ qsort(db_index, index_next, sizeof *db_index, sysdbcmp); -+ -+ if (!index_next) { -+ db_index[index_next++].id = strdup("UTC"); -+ } -+ db->index = db_index; -+ db->index_size = index_next; -+ -+ free(dirstack); -+} -+ -+#define FAKE_HEADER "1234\0??\1??" -+#define FAKE_UTC_POS (7 - 4) -+ -+/* Create a fake data segment for database 'sysdb'. */ -+static void fake_data_segment(timelib_tzdb *sysdb, -+ struct location_info **info) -+{ -+ size_t n; -+ char *data, *p; -+ -+ data = malloc(3 * sysdb->index_size + sizeof(FAKE_HEADER) - 1); -+ -+ p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1); -+ -+ for (n = 0; n < sysdb->index_size; n++) { -+ const struct location_info *li; -+ timelib_tzdb_index_entry *ent; -+ -+ ent = (timelib_tzdb_index_entry *)&sysdb->index[n]; -+ -+ /* Lookup the timezone name in the hash table. */ -+ if (strcmp(ent->id, "UTC") == 0) { -+ ent->pos = FAKE_UTC_POS; -+ continue; -+ } -+ -+ li = find_zone_info(info, ent->id); -+ if (li) { -+ /* If found, append the BC byte and the -+ * country code; set the position for this -+ * section of timezone data. */ -+ ent->pos = (p - data) - 4; -+ *p++ = '\1'; -+ *p++ = li->code[0]; -+ *p++ = li->code[1]; -+ } -+ else { -+ /* If not found, the timezone data can -+ * point at the header. */ -+ ent->pos = 0; -+ } -+ } -+ -+ sysdb->data = (unsigned char *)data; -+} -+ -+/* Returns true if the passed-in stat structure describes a -+ * probably-valid timezone file. */ -+static int is_valid_tzfile(const struct stat *st, int fd) -+{ -+ if (fd) { -+ char buf[20]; -+ if (read(fd, buf, 20)!=20) { -+ return 0; -+ } -+ lseek(fd, SEEK_SET, 0); -+ if (memcmp(buf, "TZif", 4)) { -+ return 0; -+ } -+ } -+ return S_ISREG(st->st_mode) && st->st_size > 20; -+} -+ -+/* To allow timezone names to be used case-insensitively, find the -+ * canonical name for this timezone, if possible. */ -+static const char *canonical_tzname(const char *timezone) -+{ -+ if (timezonedb_system) { -+ timelib_tzdb_index_entry *ent, lookup; -+ -+ lookup.id = (char *)timezone; -+ -+ ent = bsearch(&lookup, timezonedb_system->index, -+ timezonedb_system->index_size, sizeof lookup, -+ sysdbcmp); -+ if (ent) { -+ return ent->id; -+ } -+ } -+ -+ return timezone; -+} -+ -+/* Return the mmap()ed tzfile if found, else NULL. On success, the -+ * length of the mapped data is placed in *length. */ -+static char *map_tzfile(const char *timezone, size_t *length) -+{ -+ char fname[PATH_MAX]; -+ struct stat st; -+ char *p; -+ int fd; -+ -+ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { -+ return NULL; -+ } -+ -+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); -+ -+ fd = open(fname, O_RDONLY); -+ if (fd == -1) { -+ if (strcmp(timezone, "UTC")) { -+ return NULL; -+ } else { -+ *length = sizeof(internal_utc); -+ return internal_utc; -+ } -+ } else if (fstat(fd, &st) != 0 || !is_valid_tzfile(&st, fd)) { -+ close(fd); -+ return NULL; -+ } -+ -+ *length = st.st_size; -+ p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); -+ close(fd); -+ -+ return p != MAP_FAILED ? p : NULL; -+} -+ -+#endif -+ -+static int inmem_seek_to_tz_position(const unsigned char **tzf, const char *timezone, const timelib_tzdb *tzdb) - { - int left = 0, right = tzdb->index_size - 1; - -@@ -603,9 +1100,49 @@ static int seek_to_tz_position(const uns - return 0; - } - -+static int seek_to_tz_position(const unsigned char **tzf, const char *timezone, -+ char **map, size_t *maplen, -+ const timelib_tzdb *tzdb) -+{ -+#ifdef HAVE_SYSTEM_TZDATA -+ if (tzdb == timezonedb_system) { -+ char *orig; -+ -+ orig = map_tzfile(timezone, maplen); -+ if (orig == NULL) { -+ return 0; -+ } -+ -+ (*tzf) = (unsigned char *)orig; -+ *map = orig; -+ return 1; -+ } -+ else -+#endif -+ { -+ return inmem_seek_to_tz_position(tzf, timezone, tzdb); -+ } -+} -+ - const timelib_tzdb *timelib_builtin_db(void) - { -+#ifdef HAVE_SYSTEM_TZDATA -+ if (timezonedb_system == NULL) { -+ timelib_tzdb *tmp = malloc(sizeof *tmp); -+ -+ tmp->version = "0"; -+ tmp->data = NULL; -+ create_zone_index(tmp); -+ retrieve_zone_version(tmp); -+ system_location_table = create_location_table(); -+ fake_data_segment(tmp, system_location_table); -+ timezonedb_system = tmp; -+ } -+ -+ return timezonedb_system; -+#else - return &timezonedb_builtin; -+#endif - } - - const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count) -@@ -617,7 +1154,32 @@ const timelib_tzdb_index_entry *timelib_ - int timelib_timezone_id_is_valid(const char *timezone, const timelib_tzdb *tzdb) - { - const unsigned char *tzf; -- return (seek_to_tz_position(&tzf, timezone, tzdb)); -+ -+#ifdef HAVE_SYSTEM_TZDATA -+ if (tzdb == timezonedb_system) { -+ char fname[PATH_MAX]; -+ struct stat st; -+ -+ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { -+ return 0; -+ } -+ if (!strcmp(timezone, "UTC")) { -+ return 1; -+ } -+ if (system_location_table) { -+ if (find_zone_info(system_location_table, timezone) != NULL) { -+ /* found in cache */ -+ return 1; -+ } -+ } -+ -+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); -+ -+ return stat(fname, &st) == 0 && is_valid_tzfile(&st, 0); -+ } -+#endif -+ -+ return (inmem_seek_to_tz_position(&tzf, timezone, tzdb)); - } - - static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz) -@@ -662,6 +1224,8 @@ static timelib_tzinfo* timelib_tzinfo_ct - timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *tzdb, int *error_code) - { - const unsigned char *tzf; -+ char *memmap = NULL; -+ size_t maplen; - timelib_tzinfo *tmp; - int version; - int transitions_result, types_result; -@@ -669,7 +1233,7 @@ timelib_tzinfo *timelib_parse_tzfile(con - - *error_code = TIMELIB_ERROR_NO_ERROR; - -- if (seek_to_tz_position(&tzf, timezone, tzdb)) { -+ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) { - tmp = timelib_tzinfo_ctor(timezone); - - version = read_preamble(&tzf, tmp, &type); -@@ -712,11 +1276,38 @@ timelib_tzinfo *timelib_parse_tzfile(con - return NULL; - } - -+#ifdef HAVE_SYSTEM_TZDATA -+ if (memmap) { -+ const struct location_info *li; -+ -+ /* TZif-style - grok the location info from the system database, -+ * if possible. */ -+ -+ if ((li = find_zone_info(system_location_table, timezone)) != NULL) { -+ tmp->location.comments = timelib_strdup(li->comment); -+ strncpy(tmp->location.country_code, li->code, 2); -+ tmp->location.longitude = li->longitude; -+ tmp->location.latitude = li->latitude; -+ tmp->bc = 1; -+ } -+ else { -+ set_default_location_and_comments(&tzf, tmp); -+ } -+ -+ /* Now done with the mmap segment - discard it. */ -+ if (memmap != internal_utc) { -+ munmap(memmap, maplen); -+ } -+ } else { -+#endif - if (type == TIMELIB_TZINFO_PHP) { - read_location(&tzf, tmp); - } else { - set_default_location_and_comments(&tzf, tmp); - } -+#ifdef HAVE_SYSTEM_TZDATA -+ } -+#endif - } else { - *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; - tmp = NULL; -diff -up ./ext/date/php_date.c.systzdata ./ext/date/php_date.c ---- ./ext/date/php_date.c.systzdata 2024-07-02 15:43:13.000000000 +0200 -+++ ./ext/date/php_date.c 2024-07-03 16:21:20.240786848 +0200 -@@ -487,7 +487,11 @@ PHP_MINFO_FUNCTION(date) - php_info_print_table_row(2, "date/time support", "enabled"); - php_info_print_table_row(2, "timelib version", TIMELIB_ASCII_VERSION); - php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version); -+#ifdef HAVE_SYSTEM_TZDATA -+ php_info_print_table_row(2, "Timezone Database", "system"); -+#else - php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal"); -+#endif - php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb)); - php_info_print_table_end(); - diff --git a/php-8.4.6-embed.patch b/php-8.4.6-embed.patch deleted file mode 100644 index 829a535..0000000 --- a/php-8.4.6-embed.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -up ./sapi/embed/config.m4.embed ./sapi/embed/config.m4 ---- ./sapi/embed/config.m4.embed 2025-06-03 18:29:26.000000000 +0200 -+++ ./sapi/embed/config.m4 2025-06-05 07:18:33.662824247 +0200 -@@ -10,12 +10,12 @@ AC_MSG_CHECKING([for embedded SAPI libra - if test "$PHP_EMBED" != "no"; then - AS_CASE([$PHP_EMBED], - [yes|shared], [ -- LIBPHP_CFLAGS="-shared" -+ LIBPHP_CFLAGS="-shared -release \$(PHP_MAJOR_VERSION).\$(PHP_MINOR_VERSION)" - AS_CASE(["$host_alias"], [*darwin*], [ - SAPI_SHARED="libs/libphp.dylib" - PHP_EMBED_TYPE=shared-dylib - ], [PHP_EMBED_TYPE=shared]) -- INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0755 $SAPI_SHARED \$(INSTALL_ROOT)\$(orig_libdir)" -+ INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(LIBTOOL) --mode=install \$(INSTALL) -m 0755 \$(OVERALL_TARGET) \$(INSTALL_ROOT)\$(orig_libdir)" - ], - [static], [ - LIBPHP_CFLAGS="-static" -diff -up ./scripts/php-config.in.embed ./scripts/php-config.in ---- ./scripts/php-config.in.embed 2025-03-25 19:59:01.000000000 +0100 -+++ ./scripts/php-config.in 2025-03-26 07:14:03.223870699 +0100 -@@ -19,7 +19,7 @@ exe_extension="@EXEEXT@" - php_cli_binary=NONE - php_cgi_binary=NONE - configure_options="@CONFIGURE_OPTIONS@" --php_sapis="@PHP_INSTALLED_SAPIS@" -+php_sapis="apache2handler litespeed phpdbg @PHP_INSTALLED_SAPIS@" - ini_dir="@EXPANDED_PHP_CONFIG_FILE_SCAN_DIR@" - ini_path="@EXPANDED_PHP_CONFIG_FILE_PATH@" - php_embed_type="@PHP_EMBED_TYPE@" -diff --git a/configure.ac b/configure.ac -index 6dc1e45b34f..895c5153a2d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1306,7 +1306,7 @@ AS_VAR_IF([program_suffix], [NONE], [program_suffix=]) - - orig_libdir=$libdir - AS_CASE([$libdir], -- ['${exec_prefix}/lib'], [libdir=$libdir/php]) -+ [${prefix}/${PHP_LIBDIR}], [libdir=$libdir/php]) - - AS_CASE([$(eval echo $datadir)], - ['${prefix}/share'], [datadir=$datadir/php]) diff --git a/php-8.5.0-embed.patch b/php-8.5.0-embed.patch new file mode 100644 index 0000000..8df4a81 --- /dev/null +++ b/php-8.5.0-embed.patch @@ -0,0 +1,30 @@ +diff -up ./sapi/embed/config.m4.embed ./sapi/embed/config.m4 +--- ./sapi/embed/config.m4.embed 2025-06-03 18:29:26.000000000 +0200 ++++ ./sapi/embed/config.m4 2025-06-05 07:18:33.662824247 +0200 +@@ -10,12 +10,12 @@ AC_MSG_CHECKING([for embedded SAPI libra + if test "$PHP_EMBED" != "no"; then + AS_CASE([$PHP_EMBED], + [yes|shared], [ +- LIBPHP_CFLAGS="-shared" ++ LIBPHP_CFLAGS="-shared -release \$(PHP_MAJOR_VERSION).\$(PHP_MINOR_VERSION)" + AS_CASE(["$host_alias"], [*darwin*], [ + SAPI_SHARED="libs/libphp.dylib" + PHP_EMBED_TYPE=shared-dylib + ], [PHP_EMBED_TYPE=shared]) +- INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0755 $SAPI_SHARED \$(INSTALL_ROOT)\$(orig_libdir)" ++ INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(LIBTOOL) --mode=install \$(INSTALL) -m 0755 \$(OVERALL_TARGET) \$(INSTALL_ROOT)\$(orig_libdir)" + ], + [static], [ + LIBPHP_CFLAGS="-static" +diff -up ./scripts/php-config.in.embed ./scripts/php-config.in +--- ./scripts/php-config.in.embed 2025-03-25 19:59:01.000000000 +0100 ++++ ./scripts/php-config.in 2025-03-26 07:14:03.223870699 +0100 +@@ -19,7 +19,7 @@ exe_extension="@EXEEXT@" + php_cli_binary=NONE + php_cgi_binary=NONE + configure_options="@CONFIGURE_OPTIONS@" +-php_sapis="@PHP_INSTALLED_SAPIS@" ++php_sapis="apache2handler litespeed phpdbg @PHP_INSTALLED_SAPIS@" + ini_dir="@EXPANDED_PHP_CONFIG_FILE_SCAN_DIR@" + ini_path="@EXPANDED_PHP_CONFIG_FILE_PATH@" + php_embed_type="@PHP_EMBED_TYPE@" diff --git a/php-8.5.0-ldap_r.patch b/php-8.5.0-ldap_r.patch new file mode 100644 index 0000000..9a9887e --- /dev/null +++ b/php-8.5.0-ldap_r.patch @@ -0,0 +1,19 @@ + +Use -lldap_r by default. + +diff -up ./ext/ldap/config.m4.ldap_r ./ext/ldap/config.m4 +--- ./ext/ldap/config.m4.ldap_r 2025-06-30 15:52:59.464676379 +0200 ++++ ./ext/ldap/config.m4 2025-06-30 15:53:57.499266397 +0200 +@@ -76,7 +76,11 @@ if test "$PHP_LDAP" != "no"; then + AH_TEMPLATE([HAVE_ORALDAP], + [Define to 1 if the ldap extension uses the Oracle Instant Client.]) + +- if test -f $LDAP_LIBDIR/liblber.a || test -f $LDAP_LIBDIR/liblber.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.a || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.$SHLIB_SUFFIX_NAME; then ++ if test -f $LDAP_LIBDIR/libldap_r.$SHLIB_SUFFIX_NAME; then ++ PHP_ADD_LIBRARY_WITH_PATH(lber, [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) ++ PHP_ADD_LIBRARY_WITH_PATH(ldap_r, [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) ++ ++ elif test -f $LDAP_LIBDIR/liblber.a || test -f $LDAP_LIBDIR/liblber.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.a || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.$SHLIB_SUFFIX_NAME; then + PHP_ADD_LIBRARY_WITH_PATH([lber], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) + PHP_ADD_LIBRARY_WITH_PATH([ldap], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) + diff --git a/php-8.5.0-openssl-ec-param.patch b/php-8.5.0-openssl-ec-param.patch new file mode 100644 index 0000000..223d34e --- /dev/null +++ b/php-8.5.0-openssl-ec-param.patch @@ -0,0 +1,35 @@ +diff -up ./ext/openssl/openssl_backend_v1.c.ec-param ./ext/openssl/openssl_backend_v1.c +--- ./ext/openssl/openssl_backend_v1.c.ec-param 2025-06-30 15:57:32.345876147 +0200 ++++ ./ext/openssl/openssl_backend_v1.c 2025-06-30 15:59:43.380395611 +0200 +@@ -256,13 +256,8 @@ static bool php_openssl_pkey_init_ec_dat + OPENSSL_PKEY_SET_BN(data, b); + OPENSSL_PKEY_SET_BN(data, order); + ++ php_error_docref(NULL, E_WARNING, "Missing params: curve_name (params only is not supported by OpenSSL)"); + if (!(p && a && b && order)) { +- if (!p && !a && !b && !order) { +- php_error_docref(NULL, E_WARNING, "Missing params: curve_name"); +- } else { +- php_error_docref( +- NULL, E_WARNING, "Missing params: curve_name or p, a, b, order"); +- } + goto clean_exit; + } + +diff -up ./ext/openssl/openssl_backend_v3.c.ec-param ./ext/openssl/openssl_backend_v3.c +--- ./ext/openssl/openssl_backend_v3.c.ec-param 2025-06-30 15:57:38.753560492 +0200 ++++ ./ext/openssl/openssl_backend_v3.c 2025-06-30 16:01:02.221616267 +0200 +@@ -312,12 +312,8 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval + OPENSSL_PKEY_SET_BN(data, b); + OPENSSL_PKEY_SET_BN(data, order); + ++ php_error_docref(NULL, E_WARNING, "Missing params: curve_name (params only is not supported by OpenSSL)"); + if (!(p && a && b && order)) { +- if (!p && !a && !b && !order) { +- php_error_docref(NULL, E_WARNING, "Missing params: curve_name"); +- } else { +- php_error_docref(NULL, E_WARNING, "Missing params: curve_name or p, a, b, order"); +- } + goto cleanup; + } + diff --git a/php-8.5.0-parser.patch b/php-8.5.0-parser.patch new file mode 100644 index 0000000..d103ff0 --- /dev/null +++ b/php-8.5.0-parser.patch @@ -0,0 +1,16 @@ +diff -up ./build/gen_stub.php.syslib ./build/gen_stub.php +--- ./build/gen_stub.php.syslib 2025-06-30 12:31:27.000000000 +0200 ++++ ./build/gen_stub.php 2025-06-30 15:49:00.751144274 +0200 +@@ -6082,6 +6082,12 @@ function initPhpParser() { + } + + $isInitialized = true; ++ ++ if (file_exists('/usr/share/php/PhpParser5/autoload.php')) { ++ require_once '/usr/share/php/PhpParser5/autoload.php'; ++ return; ++ } ++ + $version = "5.6.1"; + $phpParserDir = __DIR__ . "/PHP-Parser-$version"; + if (!is_dir($phpParserDir)) { diff --git a/php-8.5.0-systzdata-v24.patch b/php-8.5.0-systzdata-v24.patch new file mode 100644 index 0000000..75a73d3 --- /dev/null +++ b/php-8.5.0-systzdata-v24.patch @@ -0,0 +1,742 @@ +# License: MIT +# http://opensource.org/licenses/MIT + +Add support for use of the system timezone database, rather +than embedding a copy. Discussed upstream but was not desired. + +History: +r24: add internal UTC if tzdata is missing +r23: fix possible buffer overflow +r22: retrieve tzdata version from /usr/share/zoneinfo/tzdata.zi +r21: adapt for timelib 2021.03 (in 8.1.0) +r20: adapt for timelib 2020.03 (in 8.0.10RC1) +r19: adapt for timelib 2020.02 (in 8.0.0beta2) +r18: adapt for autotool change in 7.3.3RC1 +r17: adapt for timelib 2018.01 (in 7.3.2RC1) +r16: adapt for timelib 2017.06 (in 7.2.3RC1) +r15: adapt for timelib 2017.05beta7 (in 7.2.0RC1) +r14: improve check for valid tz file +r13: adapt for upstream changes to use PHP allocator +r12: adapt for upstream changes for new zic +r11: use canonical names to avoid more case sensitivity issues + round lat/long from zone.tab towards zero per builtin db +r10: make timezone case insensitive +r9: fix another compile error without --with-system-tzdata configured (Michael Heimpold) +r8: fix compile error without --with-system-tzdata configured +r7: improve check for valid timezone id to exclude directories +r6: fix fd leak in r5, fix country code/BC flag use in + timezone_identifiers_list() using system db, + fix use of PECL timezonedb to override system db, +r5: reverts addition of "System/Localtime" fake tzname. + updated for 5.3.0, parses zone.tab to pick up mapping between + timezone name, country code and long/lat coords +r4: added "System/Localtime" tzname which uses /etc/localtime +r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert) +r2: add filesystem trawl to set up name alias index +r1: initial revision + + +diff -up ./ext/date/config0.m4.systzdata ./ext/date/config0.m4 +--- ./ext/date/config0.m4.systzdata 2025-06-30 15:46:30.352141304 +0200 ++++ ./ext/date/config0.m4 2025-06-30 15:47:33.855594597 +0200 +@@ -7,6 +7,18 @@ + AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], + [PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -Wno-implicit-fallthrough"]) + ++PHP_ARG_WITH(system-tzdata, for use of system timezone data, ++ [AS_HELP_STRING([--with-system-tzdata[=DIR]],[to specify use of system timezone data])], no, no) ++ ++if test "$PHP_SYSTEM_TZDATA" != "no"; then ++ AC_DEFINE(HAVE_SYSTEM_TZDATA, 1, [Define if system timezone data is used]) ++ ++ if test "$PHP_SYSTEM_TZDATA" != "yes"; then ++ AC_DEFINE_UNQUOTED(HAVE_SYSTEM_TZDATA_PREFIX, "$PHP_SYSTEM_TZDATA", ++ [Define for location of system timezone data]) ++ fi ++fi ++ + PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -DHAVE_TIMELIB_CONFIG_H=1" + PHP_TIMELIB_CFLAGS="$PHP_DATE_CFLAGS" + PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" +diff -up ./ext/date/lib/parse_tz.c.systzdata ./ext/date/lib/parse_tz.c +--- ./ext/date/lib/parse_tz.c.systzdata 2025-06-30 12:31:27.000000000 +0200 ++++ ./ext/date/lib/parse_tz.c 2025-06-30 15:46:30.352327539 +0200 +@@ -26,9 +26,33 @@ + #include "timelib.h" + #include "timelib_private.h" + ++#ifdef HAVE_SYSTEM_TZDATA ++#include ++#include ++#include ++#include ++#include ++ ++#include "php_scandir.h" ++ ++static const unsigned char internal_utc[] = { ++ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x0a, 0x55, 0x54, 0x43, ++ 0x30, 0x0a ++}; ++ ++#else + #define TIMELIB_SUPPORTS_V2DATA + #define TIMELIB_SUPPORT_SLIM_FILE + #include "timezonedb.h" ++#endif ++ ++#include + + #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) + # if defined(__LITTLE_ENDIAN__) +@@ -95,6 +119,11 @@ static int read_php_preamble(const unsig + { + uint32_t version; + ++ if (memcmp(*tzf, "TZif", 4) == 0) { ++ *tzf += 20; ++ return 0; ++ } ++ + /* read ID */ + version = (*tzf)[3] - '0'; + *tzf += 4; +@@ -577,7 +606,475 @@ void timelib_dump_tzinfo(timelib_tzinfo + } + } + +-static int seek_to_tz_position(const unsigned char **tzf, const char *timezone, const timelib_tzdb *tzdb) ++#ifdef HAVE_SYSTEM_TZDATA ++ ++#ifdef HAVE_SYSTEM_TZDATA_PREFIX ++#define ZONEINFO_PREFIX HAVE_SYSTEM_TZDATA_PREFIX ++#else ++#define ZONEINFO_PREFIX "/usr/share/zoneinfo" ++#endif ++ ++/* System timezone database pointer. */ ++static const timelib_tzdb *timezonedb_system; ++ ++/* Hash table entry for the cache of the zone.tab mapping table. */ ++struct location_info { ++ char code[2]; ++ double latitude, longitude; ++ char name[64]; ++ char *comment; ++ struct location_info *next; ++}; ++ ++/* Cache of zone.tab. */ ++static struct location_info **system_location_table; ++ ++/* Size of the zone.tab hash table; a random-ish prime big enough to ++ * prevent too many collisions. */ ++#define LOCINFO_HASH_SIZE (1021) ++ ++/* Compute a case insensitive hash of str */ ++static uint32_t tz_hash(const char *str) ++{ ++ const unsigned char *p = (const unsigned char *)str; ++ uint32_t hash = 5381; ++ int c; ++ ++ while ((c = tolower(*p++)) != '\0') { ++ hash = (hash << 5) ^ hash ^ c; ++ } ++ ++ return hash % LOCINFO_HASH_SIZE; ++} ++ ++/* Parse an ISO-6709 date as used in zone.tab. Returns end of the ++ * parsed string on success, or NULL on parse error. On success, ++ * writes the parsed number to *result. */ ++static char *parse_iso6709(char *p, double *result) ++{ ++ double v, sign; ++ char *pend; ++ size_t len; ++ ++ if (*p == '+') ++ sign = 1.0; ++ else if (*p == '-') ++ sign = -1.0; ++ else ++ return NULL; ++ ++ p++; ++ for (pend = p; *pend >= '0' && *pend <= '9'; pend++) ++ ;; ++ ++ /* Annoying encoding used by zone.tab has no decimal point, so use ++ * the length to determine the format: ++ * ++ * 4 = DDMM ++ * 5 = DDDMM ++ * 6 = DDMMSS ++ * 7 = DDDMMSS ++ */ ++ len = pend - p; ++ if (len < 4 || len > 7) { ++ return NULL; ++ } ++ ++ /* p => [D]DD */ ++ v = (p[0] - '0') * 10.0 + (p[1] - '0'); ++ p += 2; ++ if (len == 5 || len == 7) ++ v = v * 10.0 + (*p++ - '0'); ++ /* p => MM[SS] */ ++ v += (10.0 * (p[0] - '0') ++ + p[1] - '0') / 60.0; ++ p += 2; ++ /* p => [SS] */ ++ if (len > 5) { ++ v += (10.0 * (p[0] - '0') ++ + p[1] - '0') / 3600.0; ++ p += 2; ++ } ++ ++ /* Round to five decimal place, not because it's a good idea, ++ * but, because the builtin data uses rounded data, so, match ++ * that. */ ++ *result = trunc(v * sign * 100000.0) / 100000.0; ++ ++ return p; ++} ++ ++/* This function parses the zone.tab file to build up the mapping of ++ * timezone to country code and geographic location, and returns a ++ * hash table. The hash table is indexed by the function: ++ * ++ * tz_hash(timezone-name) ++ */ ++static struct location_info **create_location_table(void) ++{ ++ struct location_info **li, *i; ++ char zone_tab[PATH_MAX]; ++ char line[512]; ++ FILE *fp; ++ ++ strncpy(zone_tab, ZONEINFO_PREFIX "/zone.tab", sizeof zone_tab); ++ ++ fp = fopen(zone_tab, "r"); ++ if (!fp) { ++ return NULL; ++ } ++ ++ li = calloc(LOCINFO_HASH_SIZE, sizeof *li); ++ ++ while (fgets(line, sizeof line, fp)) { ++ char *p = line, *code, *name, *comment; ++ uint32_t hash; ++ double latitude, longitude; ++ ++ while (isspace(*p)) ++ p++; ++ ++ if (*p == '#' || *p == '\0' || *p == '\n') ++ continue; ++ ++ if (!isalpha(p[0]) || !isalpha(p[1]) || p[2] != '\t') ++ continue; ++ ++ /* code => AA */ ++ code = p; ++ p[2] = 0; ++ p += 3; ++ ++ /* coords => [+-][D]DDMM[SS][+-][D]DDMM[SS] */ ++ p = parse_iso6709(p, &latitude); ++ if (!p) { ++ continue; ++ } ++ p = parse_iso6709(p, &longitude); ++ if (!p) { ++ continue; ++ } ++ ++ if (!p || *p != '\t') { ++ continue; ++ } ++ ++ /* name = string */ ++ name = ++p; ++ while (*p != '\t' && *p && *p != '\n') ++ p++; ++ ++ *p++ = '\0'; ++ ++ /* comment = string */ ++ comment = p; ++ while (*p != '\t' && *p && *p != '\n') ++ p++; ++ ++ if (*p == '\n' || *p == '\t') ++ *p = '\0'; ++ ++ hash = tz_hash(name); ++ i = malloc(sizeof *i); ++ memcpy(i->code, code, 2); ++ strncpy(i->name, name, sizeof i->name); ++ i->comment = strdup(comment); ++ i->longitude = longitude; ++ i->latitude = latitude; ++ i->next = li[hash]; ++ li[hash] = i; ++ /* printf("%s [%u, %f, %f]\n", name, hash, latitude, longitude); */ ++ } ++ ++ fclose(fp); ++ ++ return li; ++} ++ ++/* Return location info from hash table, using given timezone name. ++ * Returns NULL if the name could not be found. */ ++const struct location_info *find_zone_info(struct location_info **li, ++ const char *name) ++{ ++ uint32_t hash = tz_hash(name); ++ const struct location_info *l; ++ ++ if (!li) { ++ return NULL; ++ } ++ ++ for (l = li[hash]; l; l = l->next) { ++ if (timelib_strcasecmp(l->name, name) == 0) ++ return l; ++ } ++ ++ return NULL; ++} ++ ++/* Filter out some non-tzdata files and the posix/right databases, if ++ * present. */ ++static int index_filter(const struct dirent *ent) ++{ ++ return strcmp(ent->d_name, ".") != 0 ++ && strcmp(ent->d_name, "..") != 0 ++ && strcmp(ent->d_name, "posix") != 0 ++ && strcmp(ent->d_name, "posixrules") != 0 ++ && strcmp(ent->d_name, "right") != 0 ++ && strstr(ent->d_name, ".list") == NULL ++ && strstr(ent->d_name, ".tab") == NULL; ++} ++ ++static int sysdbcmp(const void *first, const void *second) ++{ ++ const timelib_tzdb_index_entry *alpha = first, *beta = second; ++ ++ return timelib_strcasecmp(alpha->id, beta->id); ++} ++ ++/* Retrieve tzdata version. */ ++static void retrieve_zone_version(timelib_tzdb *db) ++{ ++ static char buf[30]; ++ char path[PATH_MAX]; ++ FILE *fp; ++ ++ strncpy(path, ZONEINFO_PREFIX "/tzdata.zi", sizeof(path)); ++ ++ fp = fopen(path, "r"); ++ if (fp) { ++ if (fgets(buf, sizeof(buf), fp)) { ++ if (!memcmp(buf, "# version ", 10) && ++ isdigit(buf[10]) && ++ isdigit(buf[11]) && ++ isdigit(buf[12]) && ++ isdigit(buf[13]) && ++ islower(buf[14])) { ++ if (buf[14] >= 't') { /* 2022t = 2022.20 */ ++ buf[17] = 0; ++ buf[16] = buf[14] - 't' + '0'; ++ buf[15] = '2'; ++ } else if (buf[14] >= 'j') { /* 2022j = 2022.10 */ ++ buf[17] = 0; ++ buf[16] = buf[14] - 'j' + '0'; ++ buf[15] = '1'; ++ } else { /* 2022a = 2022.1 */ ++ buf[16] = 0; ++ buf[15] = buf[14] - 'a' + '1'; ++ } ++ buf[14] = '.'; ++ db->version = buf+10; ++ } ++ } ++ fclose(fp); ++ } ++} ++ ++ ++/* Create the zone identifier index by trawling the filesystem. */ ++static void create_zone_index(timelib_tzdb *db) ++{ ++ size_t dirstack_size, dirstack_top; ++ size_t index_size, index_next; ++ timelib_tzdb_index_entry *db_index; ++ char **dirstack; ++ ++ /* LIFO stack to hold directory entries to scan; each slot is a ++ * directory name relative to the zoneinfo prefix. */ ++ dirstack_size = 32; ++ dirstack = malloc(dirstack_size * sizeof *dirstack); ++ dirstack_top = 1; ++ dirstack[0] = strdup(""); ++ ++ /* Index array. */ ++ index_size = 64; ++ db_index = malloc(index_size * sizeof *db_index); ++ index_next = 0; ++ ++ do { ++ struct dirent **ents; ++ char name[PATH_MAX], *top; ++ int count; ++ ++ /* Pop the top stack entry, and iterate through its contents. */ ++ top = dirstack[--dirstack_top]; ++ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s", top); ++ ++ count = php_scandir(name, &ents, index_filter, php_alphasort); ++ ++ while (count > 0) { ++ struct stat st; ++ const char *leaf = ents[count - 1]->d_name; ++ ++ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s/%s", ++ top, leaf); ++ ++ if (strlen(name) && stat(name, &st) == 0) { ++ /* Name, relative to the zoneinfo prefix. */ ++ const char *root = top; ++ ++ if (root[0] == '/') root++; ++ ++ snprintf(name, sizeof name, "%s%s%s", root, ++ *root ? "/": "", leaf); ++ ++ if (S_ISDIR(st.st_mode)) { ++ if (dirstack_top == dirstack_size) { ++ dirstack_size *= 2; ++ dirstack = realloc(dirstack, ++ dirstack_size * sizeof *dirstack); ++ } ++ dirstack[dirstack_top++] = strdup(name); ++ } ++ else { ++ if (index_next == index_size) { ++ index_size *= 2; ++ db_index = realloc(db_index, ++ index_size * sizeof *db_index); ++ } ++ ++ db_index[index_next++].id = strdup(name); ++ } ++ } ++ ++ free(ents[--count]); ++ } ++ ++ if (count != -1) free(ents); ++ free(top); ++ } while (dirstack_top); ++ ++ qsort(db_index, index_next, sizeof *db_index, sysdbcmp); ++ ++ if (!index_next) { ++ db_index[index_next++].id = strdup("UTC"); ++ } ++ db->index = db_index; ++ db->index_size = index_next; ++ ++ free(dirstack); ++} ++ ++#define FAKE_HEADER "1234\0??\1??" ++#define FAKE_UTC_POS (7 - 4) ++ ++/* Create a fake data segment for database 'sysdb'. */ ++static void fake_data_segment(timelib_tzdb *sysdb, ++ struct location_info **info) ++{ ++ size_t n; ++ char *data, *p; ++ ++ data = malloc(3 * sysdb->index_size + sizeof(FAKE_HEADER) - 1); ++ ++ p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1); ++ ++ for (n = 0; n < sysdb->index_size; n++) { ++ const struct location_info *li; ++ timelib_tzdb_index_entry *ent; ++ ++ ent = (timelib_tzdb_index_entry *)&sysdb->index[n]; ++ ++ /* Lookup the timezone name in the hash table. */ ++ if (strcmp(ent->id, "UTC") == 0) { ++ ent->pos = FAKE_UTC_POS; ++ continue; ++ } ++ ++ li = find_zone_info(info, ent->id); ++ if (li) { ++ /* If found, append the BC byte and the ++ * country code; set the position for this ++ * section of timezone data. */ ++ ent->pos = (p - data) - 4; ++ *p++ = '\1'; ++ *p++ = li->code[0]; ++ *p++ = li->code[1]; ++ } ++ else { ++ /* If not found, the timezone data can ++ * point at the header. */ ++ ent->pos = 0; ++ } ++ } ++ ++ sysdb->data = (unsigned char *)data; ++} ++ ++/* Returns true if the passed-in stat structure describes a ++ * probably-valid timezone file. */ ++static int is_valid_tzfile(const struct stat *st, int fd) ++{ ++ if (fd) { ++ char buf[20]; ++ if (read(fd, buf, 20)!=20) { ++ return 0; ++ } ++ lseek(fd, SEEK_SET, 0); ++ if (memcmp(buf, "TZif", 4)) { ++ return 0; ++ } ++ } ++ return S_ISREG(st->st_mode) && st->st_size > 20; ++} ++ ++/* To allow timezone names to be used case-insensitively, find the ++ * canonical name for this timezone, if possible. */ ++static const char *canonical_tzname(const char *timezone) ++{ ++ if (timezonedb_system) { ++ timelib_tzdb_index_entry *ent, lookup; ++ ++ lookup.id = (char *)timezone; ++ ++ ent = bsearch(&lookup, timezonedb_system->index, ++ timezonedb_system->index_size, sizeof lookup, ++ sysdbcmp); ++ if (ent) { ++ return ent->id; ++ } ++ } ++ ++ return timezone; ++} ++ ++/* Return the mmap()ed tzfile if found, else NULL. On success, the ++ * length of the mapped data is placed in *length. */ ++static char *map_tzfile(const char *timezone, size_t *length) ++{ ++ char fname[PATH_MAX]; ++ struct stat st; ++ char *p; ++ int fd; ++ ++ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { ++ return NULL; ++ } ++ ++ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); ++ ++ fd = open(fname, O_RDONLY); ++ if (fd == -1) { ++ if (strcmp(timezone, "UTC")) { ++ return NULL; ++ } else { ++ *length = sizeof(internal_utc); ++ return internal_utc; ++ } ++ } else if (fstat(fd, &st) != 0 || !is_valid_tzfile(&st, fd)) { ++ close(fd); ++ return NULL; ++ } ++ ++ *length = st.st_size; ++ p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); ++ close(fd); ++ ++ return p != MAP_FAILED ? p : NULL; ++} ++ ++#endif ++ ++static int inmem_seek_to_tz_position(const unsigned char **tzf, const char *timezone, const timelib_tzdb *tzdb) + { + int left = 0, right = tzdb->index_size - 1; + +@@ -603,9 +1100,49 @@ static int seek_to_tz_position(const uns + return 0; + } + ++static int seek_to_tz_position(const unsigned char **tzf, const char *timezone, ++ char **map, size_t *maplen, ++ const timelib_tzdb *tzdb) ++{ ++#ifdef HAVE_SYSTEM_TZDATA ++ if (tzdb == timezonedb_system) { ++ char *orig; ++ ++ orig = map_tzfile(timezone, maplen); ++ if (orig == NULL) { ++ return 0; ++ } ++ ++ (*tzf) = (unsigned char *)orig; ++ *map = orig; ++ return 1; ++ } ++ else ++#endif ++ { ++ return inmem_seek_to_tz_position(tzf, timezone, tzdb); ++ } ++} ++ + const timelib_tzdb *timelib_builtin_db(void) + { ++#ifdef HAVE_SYSTEM_TZDATA ++ if (timezonedb_system == NULL) { ++ timelib_tzdb *tmp = malloc(sizeof *tmp); ++ ++ tmp->version = "0"; ++ tmp->data = NULL; ++ create_zone_index(tmp); ++ retrieve_zone_version(tmp); ++ system_location_table = create_location_table(); ++ fake_data_segment(tmp, system_location_table); ++ timezonedb_system = tmp; ++ } ++ ++ return timezonedb_system; ++#else + return &timezonedb_builtin; ++#endif + } + + const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count) +@@ -617,7 +1154,32 @@ const timelib_tzdb_index_entry *timelib_ + int timelib_timezone_id_is_valid(const char *timezone, const timelib_tzdb *tzdb) + { + const unsigned char *tzf; +- return (seek_to_tz_position(&tzf, timezone, tzdb)); ++ ++#ifdef HAVE_SYSTEM_TZDATA ++ if (tzdb == timezonedb_system) { ++ char fname[PATH_MAX]; ++ struct stat st; ++ ++ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { ++ return 0; ++ } ++ if (!strcmp(timezone, "UTC")) { ++ return 1; ++ } ++ if (system_location_table) { ++ if (find_zone_info(system_location_table, timezone) != NULL) { ++ /* found in cache */ ++ return 1; ++ } ++ } ++ ++ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); ++ ++ return stat(fname, &st) == 0 && is_valid_tzfile(&st, 0); ++ } ++#endif ++ ++ return (inmem_seek_to_tz_position(&tzf, timezone, tzdb)); + } + + static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz) +@@ -662,6 +1224,8 @@ static timelib_tzinfo* timelib_tzinfo_ct + timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *tzdb, int *error_code) + { + const unsigned char *tzf; ++ char *memmap = NULL; ++ size_t maplen; + timelib_tzinfo *tmp; + int version; + int transitions_result, types_result; +@@ -669,7 +1233,7 @@ timelib_tzinfo *timelib_parse_tzfile(con + + *error_code = TIMELIB_ERROR_NO_ERROR; + +- if (seek_to_tz_position(&tzf, timezone, tzdb)) { ++ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) { + tmp = timelib_tzinfo_ctor(timezone); + + version = read_preamble(&tzf, tmp, &type); +@@ -712,11 +1276,38 @@ timelib_tzinfo *timelib_parse_tzfile(con + return NULL; + } + ++#ifdef HAVE_SYSTEM_TZDATA ++ if (memmap) { ++ const struct location_info *li; ++ ++ /* TZif-style - grok the location info from the system database, ++ * if possible. */ ++ ++ if ((li = find_zone_info(system_location_table, timezone)) != NULL) { ++ tmp->location.comments = timelib_strdup(li->comment); ++ strncpy(tmp->location.country_code, li->code, 2); ++ tmp->location.longitude = li->longitude; ++ tmp->location.latitude = li->latitude; ++ tmp->bc = 1; ++ } ++ else { ++ set_default_location_and_comments(&tzf, tmp); ++ } ++ ++ /* Now done with the mmap segment - discard it. */ ++ if (memmap != internal_utc) { ++ munmap(memmap, maplen); ++ } ++ } else { ++#endif + if (type == TIMELIB_TZINFO_PHP) { + read_location(&tzf, tmp); + } else { + set_default_location_and_comments(&tzf, tmp); + } ++#ifdef HAVE_SYSTEM_TZDATA ++ } ++#endif + } else { + *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; + tmp = NULL; +diff -up ./ext/date/php_date.c.systzdata ./ext/date/php_date.c +--- ./ext/date/php_date.c.systzdata 2025-06-30 12:31:27.000000000 +0200 ++++ ./ext/date/php_date.c 2025-06-30 15:46:30.352655217 +0200 +@@ -491,7 +491,11 @@ PHP_MINFO_FUNCTION(date) + php_info_print_table_row(2, "date/time support", "enabled"); + php_info_print_table_row(2, "timelib version", TIMELIB_ASCII_VERSION); + php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version); ++#ifdef HAVE_SYSTEM_TZDATA ++ php_info_print_table_row(2, "Timezone Database", "system"); ++#else + php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal"); ++#endif + php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb)); + php_info_print_table_end(); + diff --git a/php.ini b/php.ini index cdd2c0b..1d8e01a 100644 --- a/php.ini +++ b/php.ini @@ -107,7 +107,7 @@ ; error_reporting ; Default Value: E_ALL ; Development Value: E_ALL -; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT +; Production Value: E_ALL & ~E_DEPRECATED ; log_errors ; Default Value: Off @@ -119,16 +119,16 @@ ; Development Value: 60 (60 seconds) ; Production Value: 60 (60 seconds) +; mysqlnd.collect_memory_statistics +; Default Value: Off +; Development Value: On +; Production Value: Off + ; output_buffering ; Default Value: Off ; Development Value: 4096 ; Production Value: 4096 -; register_argc_argv -; Default Value: On -; Development Value: Off -; Production Value: Off - ; request_order ; Default Value: None ; Development Value: "GP" @@ -322,11 +322,6 @@ serialize_precision = -1 ; https://php.net/disable-functions disable_functions = -; This directive allows you to disable certain classes. -; It receives a comma-delimited list of class names. -; https://php.net/disable-classes -disable_classes = - ; Colors for Syntax Highlighting mode. Anything that's acceptable in ; would work. ; https://php.net/syntax-highlighting @@ -433,6 +428,7 @@ max_input_time = 60 ; Maximum amount of memory a script may consume ; https://php.net/memory-limit memory_limit = 128M +max_memory_limit = -1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; @@ -444,7 +440,7 @@ memory_limit = 128M ; operators. The error level constants are below here for convenience as well as ; some common settings and their meanings. ; By default, PHP is set to take action on all errors, notices and warnings EXCEPT -; those related to E_NOTICE and E_STRICT, which together cover best practices and +; those related to E_NOTICE, which together cover best practices and ; recommended coding standards in PHP. For performance reasons, this is the ; recommend error reporting setting. Your production server shouldn't be wasting ; resources complaining about best practices and coding standards. That's what @@ -464,9 +460,6 @@ memory_limit = 128M ; intentional (e.g., using an uninitialized variable and ; relying on the fact it is automatically initialized to an ; empty string) -; E_STRICT - run-time notices, enable to have PHP suggest changes -; to your code which will ensure the best interoperability -; and forward compatibility of your code ; E_CORE_ERROR - fatal errors that occur during PHP's initial startup ; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's ; initial startup @@ -482,13 +475,12 @@ memory_limit = 128M ; Common Values: ; E_ALL (Show all errors, warnings and notices including coding standards.) ; E_ALL & ~E_NOTICE (Show all errors, except for notices) -; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.) ; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) ; Default Value: E_ALL ; Development Value: E_ALL -; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT +; Production Value: E_ALL & ~E_DEPRECATED ; https://php.net/error-reporting -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +error_reporting = E_ALL & ~E_DEPRECATED ; This directive controls whether or not and where PHP will output errors, ; notices and warnings too. Error output is very useful during development, but @@ -537,12 +529,6 @@ ignore_repeated_errors = Off ; https://php.net/ignore-repeated-source ignore_repeated_source = Off -; If this parameter is set to Off, then memory leaks will not be shown (on -; stdout or in the log). This is only effective in a debug compile, and if -; error reporting includes E_WARNING in the allowed list -; https://php.net/report-memleaks -report_memleaks = On - ; This setting is off by default. ;report_zend_debug = 0 @@ -621,6 +607,12 @@ report_memleaks = On ; Development value: 0 ; Production value: 0 +; This directive controls whether PHP will output the backtrace of fatal errors. +; Default Value: On +; Development Value: On +; Production Value: On +;fatal_error_backtraces = On + ;;;;;;;;;;;;;;;;; ; Data Handling ; ;;;;;;;;;;;;;;;;; @@ -670,14 +662,12 @@ request_order = "GP" ; that were passed when the script was invoked. These arrays are extremely ; useful when running scripts from the command line. When this directive is ; enabled, registering these variables consumes CPU cycles and memory each time -; a script is executed. For performance reasons, this feature should be disabled -; on production servers. -; Note: This directive is hardcoded to On for the CLI SAPI -; Default Value: On -; Development Value: Off -; Production Value: Off +; a script is executed. For security reasons, this feature should be disabled +; for non-CLI SAPIs. +; Note: This directive is ignored for the CLI SAPI +; This directive is deprecated. ; https://php.net/register-argc-argv -register_argc_argv = Off +;register_argc_argv = Off ; When enabled, the ENV, REQUEST and SERVER variables are created when they're ; first used (Just In Time) instead of when the script starts. If these @@ -818,6 +808,12 @@ enable_dl = Off ; https://php.net/fastcgi.impersonate ;fastcgi.impersonate = 1 +; Prevent decoding of SCRIPT_FILENAME when using Apache ProxyPass or +; ProxyPassMatch. This should only be used if script file paths are already +; stored in an encoded format on the file system. +; Default is 0. +;fastcgi.script_path_encoded = 1 + ; Disable logging through FastCGI connection. PHP's default behavior is to enable ; this feature. ;fastcgi.logging = 0 @@ -968,20 +964,17 @@ cli_server.color = On ; otherwise output encoding conversion cannot be performed. ;iconv.output_encoding = -[imap] -; rsh/ssh logins are disabled by default. Use this INI entry if you want to -; enable them. Note that the IMAP library does not filter mailbox names before -; passing them to rsh/ssh command, thus passing untrusted data to this function -; with rsh/ssh enabled is insecure. -;imap.enable_insecure_rsh=0 - [intl] ;intl.default_locale = ; This directive allows you to produce PHP errors when some error ; happens within intl functions. The value is the level of the error produced. ; Default is 0, which does not produce any errors. +; This directive is deprecated. ;intl.error_level = E_WARNING -;intl.use_exceptions = 0 +; If enabled this directive indicates that when an error occurs within an +; intl function a IntlException should be thrown. +; Default is Off, which means errors need to be handled manually. +;intl.use_exceptions = On [sqlite3] ; Directory pointing to SQLite3 extensions @@ -1049,6 +1042,14 @@ mail.add_x_header = Off ; RFC 2822 non conformant MTA. mail.mixed_lf_and_crlf = Off +; Control line ending mode for mail messages and headers. +; Possible values: "crlf" (default), "lf", "mixed", "os" +; - crlf: Use CRLF line endings +; - lf: Use LF line endings only (converts CRLF in message to LF) +; - mixed: Same as mail.mixed_lf_and_crlf = On +; - os: Use CRLF on Windows, LF on other systems +mail.cr_lf_mode = crlf + ; The path to a log file that will log all mail() calls. Log entries include ; the full path of the script, line number, To address and headers. ;mail.log = @@ -1118,10 +1119,7 @@ mysqli.allow_persistent = On ; https://php.net/mysqli.max-links mysqli.max_links = -1 -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. +; Default port number for mysqli_connect(). ; https://php.net/mysqli.default-port mysqli.default_port = 3306 @@ -1130,15 +1128,15 @@ mysqli.default_port = 3306 ; https://php.net/mysqli.default-socket mysqli.default_socket = -; Default host for mysqli_connect() (doesn't apply in safe mode). +; Default host for mysqli_connect(). ; https://php.net/mysqli.default-host mysqli.default_host = -; Default user for mysqli_connect() (doesn't apply in safe mode). +; Default user for mysqli_connect(). ; https://php.net/mysqli.default-user mysqli.default_user = -; Default password for mysqli_connect() (doesn't apply in safe mode). +; Default password for mysqli_connect(). ; Note that this is generally a *bad* idea to store passwords in this file. ; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") ; and reveal this password! And of course, any users with read access to this @@ -1158,6 +1156,9 @@ mysqlnd.collect_statistics = On ; Enable / Disable collection of memory usage statistics by mysqlnd which can be ; used to tune and monitor MySQL operations. +; Default Value: Off +; Development Value: On +; Production Value: Off mysqlnd.collect_memory_statistics = Off ; Records communication from all extensions using mysqlnd to the specified log @@ -1276,6 +1277,9 @@ session.use_cookies = 1 ; https://php.net/session.cookie-secure ;session.cookie_secure = +; https://php.net/session.cookie-partitioned +;session.cookie_partitioned = 0 + ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating ; session hijacking when not specifying and managing your own session id. It is @@ -1541,7 +1545,7 @@ zend.assertions = -1 ; With mbstring support this will automatically be converted into the encoding ; given by corresponding encode setting. When empty mbstring.internal_encoding ; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. +; intel byte order. A decode setting must not be empty. ; https://php.net/exif.encode-unicode ;exif.encode_unicode = ISO-8859-15 @@ -1629,5 +1633,13 @@ ldap.max_links = -1 ; SSL stream context option. ;openssl.capath= +; The libctx is an OpenSSL library context. OpenSSL defines a default library +; context, but PHP OpenSSL also defines its own library context to avoid +; interference with other libraries using OpenSSL and to provide an independent +; context for each thread in ZTS. Possible values: +; "custom" - use a custom library context (default) +; "default" - use the default OpenSSL library context +;openssl.libctx=custom + [ffi] ; see /etc/php.d/20-ffi.ini diff --git a/php85.spec b/php85.spec index 9d86885..fe61977 100644 --- a/php85.spec +++ b/php85.spec @@ -8,8 +8,8 @@ # Please preserve changelog entries # # API/ABI check -%global apiver 20240924 -%global zendver 20240924 +%global apiver 20250925 +%global zendver 20250925 %global pdover 20240423 # Extension version %global fileinfover 1.0.5 @@ -19,7 +19,7 @@ %global _hardened_build 1 # version used for php embedded library soname -%global embed_version 8.4 +%global embed_version 8.5 %global mysql_sock %(mysql_config --socket 2>/dev/null || echo /var/lib/mysql/mysql.sock) @@ -64,6 +64,13 @@ %else %bcond_with openssl32 %endif +%if 0%{?fedora} >= 44 +# liburiparser version 0.9.9 required +%bcond_without liburiparser +%else +# use bundled library instead +%bcond_with liburiparser +%endif # /usr/sbin/apsx with httpd < 2.4 and defined as /usr/bin/apxs with httpd >= 2.4 %{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}} @@ -80,8 +87,8 @@ %bcond_without libgd %bcond_with zip -%global upver 8.4.13 -#global rcver RC1 +%global upver 8.5.0 +%global rcver RC1 # TODO set PHP_EXTRA_VERSION for EOL version Summary: PHP scripting language for creating dynamic web sites @@ -121,19 +128,19 @@ Source53: 20-ffi.ini # Build fixes Patch1: php-8.4.0-httpd.patch Patch5: php-8.4.0-includedir.patch -Patch6: php-8.4.6-embed.patch +Patch6: php-8.5.0-embed.patch Patch8: php-8.4.0-libdb.patch # Functional changes # Use system nikic/php-parser -Patch41: php-8.3.3-parser.patch +Patch41: php-8.5.0-parser.patch # use system tzdata -Patch42: php-8.4.0-systzdata-v24.patch +Patch42: php-8.5.0-systzdata-v24.patch # See http://bugs.php.net/53436 # + display PHP version backported from 8.4 Patch43: php-8.4.0-phpize.patch # Use -lldap_r for OpenLDAP -Patch45: php-8.4.0-ldap_r.patch +Patch45: php-8.5.0-ldap_r.patch # Ignore unsupported "threads" option on password_hash Patch46: php-8.0.7-argon2.patch # drop "Configure command" from phpinfo output @@ -141,7 +148,7 @@ Patch46: php-8.0.7-argon2.patch Patch47: php-8.4.0-phpinfo.patch # Always warn about missing curve_name # Both Fedora and RHEL do not support arbitrary EC parameters -Patch48: php-8.3.0-openssl-ec-param.patch +Patch48: php-8.5.0-openssl-ec-param.patch # RC Patch @@ -180,6 +187,7 @@ BuildRequires: pkgconfig(libpcre2-8) >= 10.30 %else Provides: bundled(pcre2) = 10.40 %endif +BuildRequires: pkgconfig(capstone) >= 3.0 %if %{with libxcrypt} BuildRequires: pkgconfig(libxcrypt) %endif @@ -198,6 +206,11 @@ BuildRequires: %{?dtsprefix}systemtap-sdt-devel BuildRequires: %{?dtsprefix}systemtap-sdt-dtrace %endif %endif +%if %{with liburiparser} +BuildRequires: pkgconfig(liburiparser) >= 0.9.9 +%else +Provides: bundled(liburiparser) = 0.9.9 +%endif #BuildRequires: bison #BuildRequires: re2c >= 1.0.3 # used for tests @@ -225,15 +238,15 @@ Recommends: php-cli%{?_isa} = %{version}-%{release} Recommends: php-fpm%{?_isa} = %{version}-%{release} # as "php" is now mostly a meta-package, commonly used extensions Recommends: php-mbstring%{?_isa} = %{version}-%{release} -Recommends: php-opcache%{?_isa} = %{version}-%{release} Recommends: php-pdo%{?_isa} = %{version}-%{release} Recommends: php-sodium%{?_isa} = %{version}-%{release} Recommends: php-xml%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4 < %{version}-%{release} -Provides: php8.4 = %{version}-%{release} -Provides: php8.4%{?_isa} = %{version}-%{release} +Obsoletes: php8.5 < %{version}-%{release} +Provides: php8.5 = %{version}-%{release} +Provides: php8.5%{?_isa} = %{version}-%{release} %endif @@ -258,8 +271,9 @@ Provides: php-pcntl, php-pcntl%{?_isa} Provides: php-readline, php-readline%{?_isa} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-cli < %{version}-%{release} -Provides: php8.4-cli = %{version}-%{release} -Provides: php8.4-cli%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-cli < %{version}-%{release} +Provides: php8.5-cli = %{version}-%{release} +Provides: php8.5-cli%{?_isa} = %{version}-%{release} %endif %description cli @@ -272,8 +286,9 @@ Summary: The interactive PHP debugger Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-dbg < %{version}-%{release} -Provides: php8.4-dbg = %{version}-%{release} -Provides: php8.4-dbg%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-dbg < %{version}-%{release} +Provides: php8.5-dbg = %{version}-%{release} +Provides: php8.5-dbg%{?_isa} = %{version}-%{release} %endif %description dbg @@ -303,8 +318,9 @@ Provides: php(httpd) Recommends: nginx-filesystem %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-fpm < %{version}-%{release} -Provides: php8.4-fpm = %{version}-%{release} -Provides: php8.4-fpm%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-fpm < %{version}-%{release} +Provides: php8.5-fpm = %{version}-%{release} +Provides: php8.5-fpm%{?_isa} = %{version}-%{release} %endif %description fpm @@ -318,8 +334,9 @@ Summary: LiteSpeed Web Server PHP support Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-litespeed < %{version}-%{release} -Provides: php8.4-litespeed = %{version}-%{release} -Provides: php8.4-litespeed%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-litespeed < %{version}-%{release} +Provides: php8.5-litespeed = %{version}-%{release} +Provides: php8.5-litespeed%{?_isa} = %{version}-%{release} %endif %description litespeed @@ -361,6 +378,7 @@ Provides: php-filter, php-filter%{?_isa} Provides: php-ftp, php-ftp%{?_isa} Provides: php-gettext, php-gettext%{?_isa} Provides: php-hash, php-hash%{?_isa} +Provides: php-lexbor, php-lexbor%{?_isa} Provides: php-mhash = %{version}, php-mhash%{?_isa} = %{version} Provides: php-iconv, php-iconv%{?_isa} Obsoletes: php-json < 8 @@ -368,6 +386,8 @@ Obsoletes: php-pecl-json < 8 Obsoletes: php-pecl-jsonc < 8 Provides: php-json = %{upver}, php-json%{?_isa} = %{upver} Provides: php-libxml, php-libxml%{?_isa} +Obsoletes: php-opcache < 8.5.0 +Provides: php-opcache = %{upver}, php-opcache%{?_isa} = %{upver} Provides: php-openssl, php-openssl%{?_isa} Provides: php-phar, php-phar%{?_isa} Provides: php-pcre, php-pcre%{?_isa} @@ -378,6 +398,7 @@ Provides: php-sockets, php-sockets%{?_isa} Provides: php-spl, php-spl%{?_isa} Provides: php-standard = %{version}, php-standard%{?_isa} = %{version} Provides: php-tokenizer, php-tokenizer%{?_isa} +Provides: php-uri, php-uri%{?_isa} Provides: php-zlib, php-zlib%{?_isa} Obsoletes: php-pecl-phar < 1.2.4 @@ -387,8 +408,9 @@ Provides: php-pecl(Fileinfo) = %{fileinfover}, php-pecl(Fileinfo)%{?_isa} = %{f Obsoletes: php-mhash < 5.3.0 %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-common < %{version}-%{release} -Provides: php8.4-common = %{version}-%{release} -Provides: php8.4-common%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-common < %{version}-%{release} +Provides: php8.5-common = %{version}-%{release} +Provides: php8.5-common%{?_isa} = %{version}-%{release} %endif %description common @@ -419,11 +441,13 @@ Obsoletes: php-pecl-jsonc-devel < %{version} Provides: php-zts-devel = %{version}-%{release} Provides: php-zts-devel%{?_isa} = %{version}-%{release} %endif -Recommends: php-nikic-php-parser5 >= 5.0.0 +Recommends: php-nikic-php-parser5 >= 5.6.1 +Conflicts: php-nikic-php-parser5 < 5.6.1 %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-devel < %{version}-%{release} -Provides: php8.4-devel = %{version}-%{release} -Provides: php8.4-devel%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-devel < %{version}-%{release} +Provides: php8.5-devel = %{version}-%{release} +Provides: php8.5-devel%{?_isa} = %{version}-%{release} %endif %description devel @@ -431,29 +455,6 @@ The php-devel package contains the files needed for building PHP extensions. If you need to compile your own PHP extensions, you will need to install this package. -%package opcache -Summary: The Zend OPcache -License: PHP-3.01 -BuildRequires: pkgconfig(capstone) >= 3.0 -Requires: php-common%{?_isa} = %{version}-%{release} -Obsoletes: php-pecl-zendopcache < 7.0.6 -Provides: php-pecl-zendopcache = %{version} -Provides: php-pecl-zendopcache%{?_isa} = %{version} -Provides: php-pecl(opcache) = %{version} -Provides: php-pecl(opcache)%{?_isa} = %{version} -%if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" -Obsoletes: php8.4-opcache < %{version}-%{release} -Provides: php8.4-opcache = %{version}-%{release} -Provides: php8.4-opcache%{?_isa} = %{version}-%{release} -%endif - -%description opcache -The Zend OPcache provides faster PHP execution through opcode caching and -optimization. It improves PHP performance by storing precompiled script -bytecode in the shared memory. This eliminates the stages of reading code from -the disk and compiling it on future access. In addition, it applies a few -bytecode optimization patterns that make code execution faster. - %package ldap Summary: A module for PHP applications that use LDAP # All files licensed under PHP version 3.01 @@ -464,8 +465,9 @@ BuildRequires: openldap-devel BuildRequires: openssl-devel >= 1.0.2 %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-ldap < %{version}-%{release} -Provides: php8.4-ldap = %{version}-%{release} -Provides: php8.4-ldap%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-ldap < %{version}-%{release} +Provides: php8.5-ldap = %{version}-%{release} +Provides: php8.5-ldap%{?_isa} = %{version}-%{release} %endif %description ldap @@ -486,8 +488,9 @@ Provides: php-sqlite3, php-sqlite3%{?_isa} Provides: php-pdo_sqlite, php-pdo_sqlite%{?_isa} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-pdo < %{version}-%{release} -Provides: php8.4-pdo = %{version}-%{release} -Provides: php8.4-pdo%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-pdo < %{version}-%{release} +Provides: php8.5-pdo = %{version}-%{release} +Provides: php8.5-pdo%{?_isa} = %{version}-%{release} %endif %description pdo @@ -508,8 +511,9 @@ Provides: php-pdo_mysql, php-pdo_mysql%{?_isa} Obsoletes: php-mysql < %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-mysqlnd < %{version}-%{release} -Provides: php8.4-mysqlnd = %{version}-%{release} -Provides: php8.4-mysqlnd%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-mysqlnd < %{version}-%{release} +Provides: php8.5-mysqlnd = %{version}-%{release} +Provides: php8.5-mysqlnd%{?_isa} = %{version}-%{release} %endif %description mysqlnd @@ -533,8 +537,9 @@ BuildRequires: openssl-devel >= 1.0.2 BuildRequires: postgresql-devel %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-pgsql < %{version}-%{release} -Provides: php8.4-pgsql = %{version}-%{release} -Provides: php8.4-pgsql%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-pgsql < %{version}-%{release} +Provides: php8.5-pgsql = %{version}-%{release} +Provides: php8.5-pgsql%{?_isa} = %{version}-%{release} %endif %description pgsql @@ -557,8 +562,9 @@ Provides: php-sysvshm, php-sysvshm%{?_isa} Provides: php-sysvmsg, php-sysvmsg%{?_isa} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-process < %{version}-%{release} -Provides: php8.4-process = %{version}-%{release} -Provides: php8.4-process%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-process < %{version}-%{release} +Provides: php8.5-process = %{version}-%{release} +Provides: php8.5-process%{?_isa} = %{version}-%{release} %endif %description process @@ -581,8 +587,9 @@ BuildRequires: pkgconfig(odbc) %endif %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-odbc < %{version}-%{release} -Provides: php8.4-odbc = %{version}-%{release} -Provides: php8.4-odbc%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-odbc < %{version}-%{release} +Provides: php8.5-odbc = %{version}-%{release} +Provides: php8.5-odbc%{?_isa} = %{version}-%{release} %endif %description odbc @@ -605,8 +612,9 @@ Requires: php-common%{?_isa} = %{version}-%{release} BuildRequires: pkgconfig(libxml-2.0) %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-soap < %{version}-%{release} -Provides: php8.4-soap = %{version}-%{release} -Provides: php8.4-soap%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-soap < %{version}-%{release} +Provides: php8.5-soap = %{version}-%{release} +Provides: php8.5-soap%{?_isa} = %{version}-%{release} %endif %description soap @@ -624,8 +632,9 @@ Provides: php_database Provides: php-pdo_firebird, php-pdo_firebird%{?_isa} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-pdo-firebird < %{version}-%{release} -Provides: php8.4-pdo-firebird = %{version}-%{release} -Provides: php8.4-pdo-firebird%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-pdo-firebird < %{version}-%{release} +Provides: php8.5-pdo-firebird = %{version}-%{release} +Provides: php8.5-pdo-firebird%{?_isa} = %{version}-%{release} %endif %description pdo-firebird @@ -641,8 +650,9 @@ Requires: php-common%{?_isa} = %{version}-%{release}, net-snmp BuildRequires: net-snmp-devel %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-snmp < %{version}-%{release} -Provides: php8.4-snmp = %{version}-%{release} -Provides: php8.4-snmp%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-snmp < %{version}-%{release} +Provides: php8.5-snmp = %{version}-%{release} +Provides: php8.5-snmp%{?_isa} = %{version}-%{release} %endif %description snmp @@ -667,8 +677,9 @@ BuildRequires: pkgconfig(libexslt) BuildRequires: pkgconfig(libxml-2.0) >= 2.7.6 %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-xml < %{version}-%{release} -Provides: php8.4-xml = %{version}-%{release} -Provides: php8.4-xml%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-xml < %{version}-%{release} +Provides: php8.5-xml = %{version}-%{release} +Provides: php8.5-xml%{?_isa} = %{version}-%{release} %endif %description xml @@ -692,8 +703,9 @@ Provides: bundled(libmbfl) = 1.3.2 Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-mbstring < %{version}-%{release} -Provides: php8.4-mbstring = %{version}-%{release} -Provides: php8.4-mbstring%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-mbstring < %{version}-%{release} +Provides: php8.5-mbstring = %{version}-%{release} +Provides: php8.5-mbstring%{?_isa} = %{version}-%{release} %endif %description mbstring @@ -729,8 +741,9 @@ Provides: bundled(gd) = 2.0.35 %endif %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-gd < %{version}-%{release} -Provides: php8.4-gd = %{version}-%{release} -Provides: php8.4-gd%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-gd < %{version}-%{release} +Provides: php8.5-gd = %{version}-%{release} +Provides: php8.5-gd%{?_isa} = %{version}-%{release} %endif %description gd @@ -746,8 +759,9 @@ Requires: php-common%{?_isa} = %{version}-%{release} Provides: bundled(libbcmath) %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-bcmath < %{version}-%{release} -Provides: php8.4-bcmath = %{version}-%{release} -Provides: php8.4-bcmath%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-bcmath < %{version}-%{release} +Provides: php8.5-bcmath = %{version}-%{release} +Provides: php8.5-bcmath%{?_isa} = %{version}-%{release} %endif %description bcmath @@ -762,8 +776,9 @@ BuildRequires: gmp-devel Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-gmp < %{version}-%{release} -Provides: php8.4-gmp = %{version}-%{release} -Provides: php8.4-gmp%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-gmp < %{version}-%{release} +Provides: php8.5-gmp = %{version}-%{release} +Provides: php8.5-gmp%{?_isa} = %{version}-%{release} %endif %description gmp @@ -783,8 +798,9 @@ BuildRequires: qdbm-devel Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-dba < %{version}-%{release} -Provides: php8.4-dba = %{version}-%{release} -Provides: php8.4-dba%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-dba < %{version}-%{release} +Provides: php8.5-dba = %{version}-%{release} +Provides: php8.5-dba%{?_isa} = %{version}-%{release} %endif %description dba @@ -799,8 +815,9 @@ Requires: php-common%{?_isa} = %{version}-%{release} BuildRequires: libtidy-devel %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-tidy < %{version}-%{release} -Provides: php8.4-tidy = %{version}-%{release} -Provides: php8.4-tidy%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-tidy < %{version}-%{release} +Provides: php8.5-tidy = %{version}-%{release} +Provides: php8.5-tidy%{?_isa} = %{version}-%{release} %endif %description tidy @@ -817,8 +834,9 @@ Provides: php-pdo_dblib, php-pdo_dblib%{?_isa} Obsoletes: php-mssql < %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-pdo-dblib < %{version}-%{release} -Provides: php8.4-pdo-dblib = %{version}-%{release} -Provides: php8.4-pdo-dblib%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-pdo-dblib < %{version}-%{release} +Provides: php8.5-pdo-dblib = %{version}-%{release} +Provides: php8.5-pdo-dblib%{?_isa} = %{version}-%{release} %endif %description pdo-dblib @@ -834,8 +852,9 @@ Provides: php-embedded-devel = %{version}-%{release} Provides: php-embedded-devel%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-embedded < %{version}-%{release} -Provides: php8.4-embedded = %{version}-%{release} -Provides: php8.4-embedded%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-embedded < %{version}-%{release} +Provides: php8.5-embedded = %{version}-%{release} +Provides: php8.5-embedded%{?_isa} = %{version}-%{release} %endif %description embedded @@ -852,8 +871,9 @@ BuildRequires: pkgconfig(icu-io) >= 74 BuildRequires: pkgconfig(icu-uc) >= 74 %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-intl < %{version}-%{release} -Provides: php8.4-intl = %{version}-%{release} -Provides: php8.4-intl%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-intl < %{version}-%{release} +Provides: php8.5-intl = %{version}-%{release} +Provides: php8.5-intl%{?_isa} = %{version}-%{release} %endif %description intl @@ -868,8 +888,9 @@ Requires: php-common%{?_isa} = %{version}-%{release} BuildRequires: pkgconfig(enchant-2) %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-enchant < %{version}-%{release} -Provides: php8.4-enchant = %{version}-%{release} -Provides: php8.4-enchant%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-enchant < %{version}-%{release} +Provides: php8.5-enchant = %{version}-%{release} +Provides: php8.5-enchant%{?_isa} = %{version}-%{release} %endif %description enchant @@ -907,8 +928,9 @@ Provides: php-pecl(libsodium) = %{version} Provides: php-pecl(libsodium)%{?_isa} = %{version} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-sodium < %{version}-%{release} -Provides: php8.4-sodium = %{version}-%{release} -Provides: php8.4-sodium%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-sodium < %{version}-%{release} +Provides: php8.5-sodium = %{version}-%{release} +Provides: php8.5-sodium%{?_isa} = %{version}-%{release} %endif %description sodium @@ -925,8 +947,9 @@ BuildRequires: pkgconfig(libffi) Requires: php-common%{?_isa} = %{version}-%{release} %if 0%{?rhel} >= 10 && "%{?vendeur}" == "remi" Obsoletes: php8.4-ffi < %{version}-%{release} -Provides: php8.4-ffi = %{version}-%{release} -Provides: php8.4-ffi%{?_isa} = %{version}-%{release} +Obsoletes: php8.5-ffi < %{version}-%{release} +Provides: php8.5-ffi = %{version}-%{release} +Provides: php8.5-ffi%{?_isa} = %{version}-%{release} %endif %description ffi @@ -1038,16 +1061,13 @@ rm ext/date/tests/bug73837.phpt rm ext/standard/tests/file/file_get_contents_error001.phpt # fails sometime rm ext/sockets/tests/mcast_ipv?_recv.phpt -# cause stack exhausion -rm Zend/tests/bug54268.phpt -rm Zend/tests/bug68412.phpt # slow and erratic result rm sapi/cli/tests/upload_2G.phpt -# tar issue -rm ext/zlib/tests/004-mb.phpt # Both Fedora and RHEL do not support arbitrary EC parameters # https://bugzilla.redhat.com/2223953 rm ext/openssl/tests/ecc_custom_params.phpt +# Failing when build with PHP installed +rm ext/opcache/tests/zzz_basic_logging.phpt # avoid issue when 2 builds run simultaneously (keep 64321 for the SCL) %ifarch x86_64 @@ -1194,6 +1214,7 @@ ln -sf ../configure --without-pear \ --with-exec-dir=%{_bindir} \ --without-gdbm \ + --enable-opcache-file \ --with-openssl \ %if %{with openssl32} --with-openssl-argon2 \ @@ -1204,6 +1225,9 @@ ln -sf ../configure %endif %if %{with libxcrypt} --with-external-libcrypt \ +%endif +%if %{with liburiparser} + --with-external-uriparser \ %endif --with-zlib \ --with-layout=GNU \ @@ -1234,8 +1258,6 @@ make %{?_smp_mflags} pushd build-cgi build --enable-pcntl \ - --enable-opcache \ - --enable-opcache-file \ --with-capstone \ --enable-phpdbg --enable-phpdbg-readline \ --enable-mbstring=shared \ @@ -1315,7 +1337,6 @@ without_shared="--disable-gd \ --disable-dom --disable-dba --without-unixODBC \ --without-mysqli \ --disable-pdo \ - --disable-opcache \ --disable-phpdbg \ --without-ffi \ --disable-xmlreader --disable-xmlwriter \ @@ -1358,9 +1379,6 @@ build --includedir=%{_includedir}/php-zts \ --program-prefix=zts- \ --disable-cgi \ --with-config-file-scan-dir=%{_sysconfdir}/php-zts.d \ - --enable-pcntl \ - --enable-opcache \ - --enable-opcache-file \ --with-capstone \ --enable-mbstring=shared \ --enable-mbregex \ @@ -1587,8 +1605,7 @@ for mod in pgsql odbc ldap snmp \ do case $mod in opcache) - # Zend extensions - TESTCMD="$TESTCMD --define zend_extension=$mod" + # static extension ini=10-${mod}.ini;; pdo_*|mysqli|xmlreader) # Extensions with dependencies on 20-* @@ -1658,6 +1675,7 @@ cat files.curl files.phar files.fileinfo \ files.tokenizer > files.common # The default Zend OPcache blacklist file +rm files.opcache install -m 644 %{SOURCE51} $RPM_BUILD_ROOT%{_sysconfdir}/php.d/opcache-default.blacklist %if %{with zts} install -m 644 %{SOURCE51} $RPM_BUILD_ROOT%{_sysconfdir}/php-zts.d/opcache-default.blacklist @@ -1724,6 +1742,11 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %license timelib_LICENSE %doc php.ini-* %config(noreplace) %{_sysconfdir}/php.ini +%config(noreplace) %{_sysconfdir}/php.d/10-opcache.ini +%config(noreplace) %{_sysconfdir}/php.d/opcache-default.blacklist +%if %{with zts} +%config(noreplace) %{_sysconfdir}/php-zts.d/opcache-default.blacklist +%endif %dir %{_sysconfdir}/php.d %dir %{_libdir}/php %dir %{_libdir}/php/modules @@ -1788,8 +1811,8 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : # log owned by apache for log %attr(770,apache,root) %dir %{_localstatedir}/log/php-fpm %{_mandir}/man8/php-fpm.8* -%dir %{_datadir}/fpm -%{_datadir}/fpm/status.html +%dir %{_datadir}/php/fpm +%{_datadir}/php/fpm/status.html %if %{with lsws} %files litespeed @@ -1837,11 +1860,6 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %endif %files enchant -f files.enchant %files mysqlnd -f files.mysqlnd -%files opcache -f files.opcache -%config(noreplace) %{_sysconfdir}/php.d/opcache-default.blacklist -%if %{with zts} -%config(noreplace) %{_sysconfdir}/php-zts.d/opcache-default.blacklist -%endif %if %{with zip} %files zip -f files.zip %endif @@ -1851,6 +1869,13 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %changelog +* Wed Sep 24 2025 Remi Collet - 8.5.0~RC1-1 +- update to 8.5.0RC1 +- bump ABI/API numbers to 20240925 +- drop opcache subpackage, extension is build statically +- add lexbor and uri extension (always static) +- move /usr/share/fpm/status.html to /usr/share/php/fpm/status.html + * Wed Sep 24 2025 Remi Collet - 8.4.13-1 - Update to 8.4.13 - http://www.php.net/releases/8_4_13.php -- cgit