From d33a5348631ffd1ddb7c7c4795fabd77412bb389 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 2 Jan 2024 15:50:36 +0000 Subject: [PATCH 01/51] PHP-8.3 is now for PHP-8.3.3-dev --- NEWS | 5 ++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 70829cbc981a5..35dcf588449a4 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.3.2 +?? ??? ????, PHP 8.3.3 + + +18 Jan 2024, PHP 8.3.2 - Core: . Fixed bug GH-12953 (false positive SSA integrity verification failed when diff --git a/Zend/zend.h b/Zend/zend.h index 694e419b114f1..cddd0f3b04521 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.3.2-dev" +#define ZEND_VERSION "4.3.3-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index c2c15305910f5..f3445c8e94761 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.3.2-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) +AC_INIT([PHP],[8.3.3-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index f6633fe34519b..841fe15f5b2ac 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 3 -#define PHP_RELEASE_VERSION 2 +#define PHP_RELEASE_VERSION 3 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.3.2-dev" -#define PHP_VERSION_ID 80302 +#define PHP_VERSION "8.3.3-dev" +#define PHP_VERSION_ID 80303 From 96ffe6ad7e8b7f73d49fac58a3123344662d0d93 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 22 Dec 2023 19:09:50 +0000 Subject: [PATCH 02/51] ext/intl: fix bug introduced by 5455c3f was meant to fix GH-12943. Close GH-13001. --- ext/intl/dateformat/dateformat_create.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index 399740dbca227..dbb2e8a6f6229 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -112,7 +112,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin } locale = Locale::createFromName(locale_str); /* get*Name accessors being set does not preclude being bogus */ - if (locale.isBogus() || ((locale_len == 1 && locale_str[0] != 'C') && strlen(locale.getISO3Language()) == 0)) { + if (locale.isBogus() || ((locale_len == 1 && locale_str[0] != 'C') || (locale_len > 1 && strlen(locale.getISO3Language()) == 0))) { goto error; } From 85dbbe19e20999a59cbc6707ba524c8055c5d271 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:23:56 +0100 Subject: [PATCH 03/51] Fix #71465: PHAR doesn't know about litespeed We should perhaps look into a generic system to ask the SAPI whether a feature should be supported or not. Or, we should look into making a denylist instead of an allowlist. Anyway, let's not try doing anything fancy on stable branches. Closes GH-13070. --- NEWS | 2 ++ ext/phar/phar_object.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3a6f1b7ce0db9..881c079f29a77 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.16 +- Phar: + . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) 18 Jan 2024, PHP 8.2.15 diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 8cd13e7282b7c..646cf42c4a9c9 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -599,7 +599,8 @@ PHP_METHOD(Phar, webPhar) if ((sapi_mod_name_len == sizeof("cgi-fcgi") - 1 && !strncmp(sapi_module.name, "cgi-fcgi", sizeof("cgi-fcgi") - 1)) || (sapi_mod_name_len == sizeof("fpm-fcgi") - 1 && !strncmp(sapi_module.name, "fpm-fcgi", sizeof("fpm-fcgi") - 1)) - || (sapi_mod_name_len == sizeof("cgi") - 1 && !strncmp(sapi_module.name, "cgi", sizeof("cgi") - 1))) { + || (sapi_mod_name_len == sizeof("cgi") - 1 && !strncmp(sapi_module.name, "cgi", sizeof("cgi") - 1)) + || (sapi_mod_name_len == sizeof("litespeed") - 1 && !strncmp(sapi_module.name, "litespeed", sizeof("litespeed") - 1))) { if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF) { HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); From 2575e6b88c3d3bbd53383fb65057c9b7b029e264 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 4 Jan 2024 19:26:32 +0100 Subject: [PATCH 04/51] Update year to 2024 --- LICENSE | 2 +- ext/oci8/LICENSE | 2 +- ext/phar/phar.1.in | 2 +- sapi/cli/php.1.in | 2 +- sapi/fpm/php-fpm.8.in | 2 +- sapi/phpdbg/phpdbg.1.in | 2 +- scripts/man1/php-config.1.in | 2 +- scripts/man1/phpize.1.in | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/LICENSE b/LICENSE index dffd7eab225d7..0815d7eb79119 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2024 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE index dffd7eab225d7..0815d7eb79119 100644 --- a/ext/oci8/LICENSE +++ b/ext/oci8/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2024 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/phar/phar.1.in b/ext/phar/phar.1.in index ac314fe9d5807..f0046681d32e5 100644 --- a/ext/phar/phar.1.in +++ b/ext/phar/phar.1.in @@ -1,4 +1,4 @@ -.TH PHAR 1 "2022" "The PHP Group" "User Commands" +.TH PHAR 1 "2024" "The PHP Group" "User Commands" .SH NAME phar, phar.phar \- PHAR (PHP archive) command line tool .SH SYNOPSIS diff --git a/sapi/cli/php.1.in b/sapi/cli/php.1.in index f89c93b0c58c9..a49e9cac13fb5 100644 --- a/sapi/cli/php.1.in +++ b/sapi/cli/php.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php 1 "2022" "The PHP Group" "Scripting Language" +.TH @program_prefix@php 1 "2024" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php \- PHP Command Line Interface 'CLI' .P diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index b972a2bdd031e..821fd7390810e 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -1,4 +1,4 @@ -.TH PHP-FPM 8 "2022" "The PHP Group" "Scripting Language" +.TH PHP-FPM 8 "2024" "The PHP Group" "Scripting Language" .SH NAME .TP 15 php-fpm \- PHP FastCGI Process Manager 'PHP-FPM' diff --git a/sapi/phpdbg/phpdbg.1.in b/sapi/phpdbg/phpdbg.1.in index cf43a57be67c3..169f0e46558c4 100644 --- a/sapi/phpdbg/phpdbg.1.in +++ b/sapi/phpdbg/phpdbg.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpdbg 1 "2022" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpdbg 1 "2024" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpdbg \- The interactive PHP debugger .SH SYNOPSIS diff --git a/scripts/man1/php-config.1.in b/scripts/man1/php-config.1.in index 5ed77c574cb42..8ccd171641e14 100644 --- a/scripts/man1/php-config.1.in +++ b/scripts/man1/php-config.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php\-config 1 "2022" "The PHP Group" "Scripting Language" +.TH @program_prefix@php\-config 1 "2024" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php\-config \- get information about PHP configuration and compile options .SH SYNOPSIS diff --git a/scripts/man1/phpize.1.in b/scripts/man1/phpize.1.in index bf50aa0c1df37..410a79c544754 100644 --- a/scripts/man1/phpize.1.in +++ b/scripts/man1/phpize.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpize 1 "2022" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpize 1 "2024" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpize \- prepare a PHP extension for compiling .SH SYNOPSIS From 6342f735b9d72ce266e8f9f3a432c2f72bc48a2d Mon Sep 17 00:00:00 2001 From: Rob Landers Date: Fri, 5 Jan 2024 19:36:19 +0100 Subject: [PATCH 05/51] Fix timer leak (#13027) ts_resource() and php_request_startup() both eventually call zend_max_execution_timer_init(), which didn't have a guard to prevent recreating timers, thus resulting in leaking timers. This adds a guard to prevent the leak. --- Zend/zend_max_execution_timer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 480631dcb169a..48a4d1bd66415 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -35,6 +35,12 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ { + pid_t pid = getpid(); + + if (EG(pid) == pid) { + return; + } + struct sigevent sev; sev.sigev_notify = SIGEV_THREAD_ID; sev.sigev_value.sival_ptr = &EG(max_execution_timer_timer); @@ -48,9 +54,9 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ EG(pid) = getpid(); -# ifdef MAX_EXECUTION_TIMERS_DEBUG +# ifdef MAX_EXECUTION_TIMERS_DEBUG fprintf(stderr, "Timer %#jx created on thread %d\n", (uintmax_t) EG(max_execution_timer_timer), sev.sigev_notify_thread_id); -# endif +# endif sigaction(sev.sigev_signo, NULL, &EG(oldact)); } From 29cb81483603b461ac7de31b0b9957747855455b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 5 Jan 2024 19:45:18 +0100 Subject: [PATCH 06/51] [ci skip] NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 881c079f29a77..f218cc9a6df48 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.16 +- Core: + . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) From 3a237b96a06e26c474d19a6eb86948160e730036 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 5 Jan 2024 19:46:27 +0100 Subject: [PATCH 07/51] [ci skip] NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 5369b54b4a17e..acb5462c57d83 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.3.3 +- Core: + . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) From 379e913e1ac623a0007d6a32126c792f551deee9 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 6 Jan 2024 17:18:43 +0100 Subject: [PATCH 08/51] Fix run-tests.php differ calculateCommonSubsequence for EXPECTF calculateCommonSubsequence should not contain regexes. Fixes GH-13083 Closes GH-13084 --- run-tests.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-tests.php b/run-tests.php index 16b74e5804a66..71a8fdc80fe5f 100755 --- a/run-tests.php +++ b/run-tests.php @@ -4138,7 +4138,7 @@ public function calculateCommonSubsequence(array $from, array $to): array if ($cFrom === 1) { foreach ($to as $toV) { if (($this->isEqual)($from[0], $toV)) { - return [$from[0]]; + return [$toV]; } } From 10e8a0d17e4c1b2e9148560a843e18b891954c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 8 Jan 2024 16:16:45 +0100 Subject: [PATCH 09/51] Backport upgrading PHP-Parser to PHP-8.3 --- build/gen_stub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index a4818dd33c865..b3f3fcfba63db 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -4925,7 +4925,7 @@ function initPhpParser() { } $isInitialized = true; - $version = "5.0.0alpha3"; + $version = "5.0.0"; $phpParserDir = __DIR__ . "/PHP-Parser-$version"; if (!is_dir($phpParserDir)) { installPhpParser($version, $phpParserDir); From 6339938c7e289cb5a1c0bf8f37d96537301d5477 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 9 Jan 2024 20:05:51 +0300 Subject: [PATCH 10/51] Disable inlining and inter-procedure-analyses for zend_string_equal_val() function that may be overriden for valgrind (#13099) This is a more safely way to fix GH-9068 --- Zend/zend_string.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/Zend/zend_string.c b/Zend/zend_string.c index a7c42f26b88f2..50a27d48c0c95 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -364,6 +364,7 @@ ZEND_API void zend_interned_strings_switch_storage(bool request) } } +#if defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__))) /* Even if we don't build with valgrind support, include the symbol so that valgrind available * only at runtime will not result in false positives. */ #ifndef I_REPLACE_SONAME_FNNAME_ZU @@ -371,29 +372,20 @@ ZEND_API void zend_interned_strings_switch_storage(bool request) #endif /* See GH-9068 */ -#if defined(__GNUC__) && (__GNUC__ >= 11 || defined(__clang__)) && __has_attribute(no_caller_saved_registers) -# define NO_CALLER_SAVED_REGISTERS __attribute__((no_caller_saved_registers)) -# ifndef __clang__ -# pragma GCC push_options -# pragma GCC target ("general-regs-only") -# define POP_OPTIONS -# endif +#if __has_attribute(noipa) +# define NOIPA __attribute__((noipa)) #else -# define NO_CALLER_SAVED_REGISTERS +# define NOIPA #endif -ZEND_API bool ZEND_FASTCALL NO_CALLER_SAVED_REGISTERS I_REPLACE_SONAME_FNNAME_ZU(NONE,zend_string_equal_val)(const zend_string *s1, const zend_string *s2) +ZEND_API bool ZEND_FASTCALL I_REPLACE_SONAME_FNNAME_ZU(NONE,zend_string_equal_val)(const zend_string *s1, const zend_string *s2) { return !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)); } - -#ifdef POP_OPTIONS -# pragma GCC pop_options -# undef POP_OPTIONS #endif #if defined(__GNUC__) && defined(__i386__) -ZEND_API bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2) +ZEND_API zend_never_inline NOIPA bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2) { const char *ptr = ZSTR_VAL(s1); size_t delta = (const char*)s2 - (const char*)s1; @@ -431,7 +423,7 @@ ZEND_API bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const z } #elif defined(__GNUC__) && defined(__x86_64__) && !defined(__ILP32__) -ZEND_API bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2) +ZEND_API zend_never_inline NOIPA bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2) { const char *ptr = ZSTR_VAL(s1); size_t delta = (const char*)s2 - (const char*)s1; From 1d6f344bea49ccad82b9a95a80ed9fdc39e260a1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 9 Jan 2024 20:13:22 +0100 Subject: [PATCH 11/51] Fix GH-13094: range(9.9, '0') causes segmentation fault `start_type + end_type < 2*IS_STRING` is not right, in this test case the types are start_type==5 (IS_DOUBLE), end_type==7 (IS_ARRAY). The IS_ARRAY type is a sentinel to disambiguate single-byte strings. The path must be taken when one of the types is not a string nor a single-byte string. Therefore, use < IS_STRING with an OR condition. Closes GH-13105. --- NEWS | 4 +++ ext/standard/array.c | 4 +-- ext/standard/tests/array/range/gh13094.phpt | 29 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/array/range/gh13094.phpt diff --git a/NEWS b/NEWS index acb5462c57d83..07378d091d346 100644 --- a/NEWS +++ b/NEWS @@ -4,9 +4,13 @@ PHP NEWS - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) +- Standard: + . Fixed bug GH-13094 (range(9.9, '0') causes segmentation fault). (nielsdos) + 18 Jan 2024, PHP 8.3.2 - Core: diff --git a/ext/standard/array.c b/ext/standard/array.c index eee260f224319..76e33e9868aa8 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2924,8 +2924,8 @@ PHP_FUNCTION(range) /* If the range is given as strings, generate an array of characters. */ if (start_type >= IS_STRING || end_type >= IS_STRING) { - /* If one of the inputs is NOT a string */ - if (UNEXPECTED(start_type + end_type < 2*IS_STRING)) { + /* If one of the inputs is NOT a string nor single-byte string */ + if (UNEXPECTED(start_type < IS_STRING || end_type < IS_STRING)) { if (start_type < IS_STRING) { if (end_type != IS_ARRAY) { php_error_docref(NULL, E_WARNING, "Argument #1 ($start) must be a single byte string if" diff --git a/ext/standard/tests/array/range/gh13094.phpt b/ext/standard/tests/array/range/gh13094.phpt new file mode 100644 index 0000000000000..2e70adb65da72 --- /dev/null +++ b/ext/standard/tests/array/range/gh13094.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-13094 (range(9.9, '0') causes segmentation fault) +--FILE-- + +--EXPECT-- +array(10) { + [0]=> + float(9.9) + [1]=> + float(8.9) + [2]=> + float(7.9) + [3]=> + float(6.9) + [4]=> + float(5.9) + [5]=> + float(4.9) + [6]=> + float(3.9000000000000004) + [7]=> + float(2.9000000000000004) + [8]=> + float(1.9000000000000004) + [9]=> + float(0.9000000000000004) +} From 1e464e5b55f81b7fb9476a55f481fe1d2a25d6d9 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 9 Jan 2024 20:40:22 +0000 Subject: [PATCH 12/51] ext/gd: Fix GH-13082 Issue occur when compiling with recent clang releases (> 13) and with the '-Os' optimisation level, after using `imageloadfont` which returns a proper GdFont class leads to a subtle bug when attempting to use via the imagefont* function. --- NEWS | 4 ++++ ext/gd/gd.c | 8 ++++---- ext/gd/tests/gh13082.gdf | Bin 0 -> 53776 bytes ext/gd/tests/gh13082.phpt | 16 ++++++++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 ext/gd/tests/gh13082.gdf create mode 100644 ext/gd/tests/gh13082.phpt diff --git a/NEWS b/NEWS index f218cc9a6df48..b723d6e14d272 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,10 @@ PHP NEWS (Jakub Zelenka) . Fixed bug GH-12905 (FFI::new interacts badly with observers). (nielsdos) +- GD: + . Fixed GH-13082 undefined behavior with GdFont instances handling with + imageload* and imagechar*. (David Carlier) + - Intl: . Fixed GH-12943 (IntlDateFormatter::__construct accepts 'C' as valid locale). (David Carlier) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 1d8b3a0a1d46c..c86a663c5b7c1 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -2681,8 +2681,8 @@ static gdFontPtr php_find_gd_font(zend_object *font_obj, zend_long font_int) */ static void php_imagefontsize(INTERNAL_FUNCTION_PARAMETERS, int arg) { - zend_object *font_obj; - zend_long font_int; + zend_object *font_obj = NULL; + zend_long font_int = 0; gdFontPtr font; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -2750,8 +2750,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode) int ch = 0, col, x, y, i, l = 0; unsigned char *str = NULL; zend_object *font_obj; - zend_long font_int; - gdFontPtr font; + zend_long font_int = 0; + gdFontPtr font = NULL; ZEND_PARSE_PARAMETERS_START(6, 6) Z_PARAM_OBJECT_OF_CLASS(IM, gd_image_ce) diff --git a/ext/gd/tests/gh13082.gdf b/ext/gd/tests/gh13082.gdf new file mode 100644 index 0000000000000000000000000000000000000000..44669f3d12b92f2ef2144700e374b8f2d529c587 GIT binary patch literal 53776 zcmeHMU6wPst($qzV-}G8uPRH42oNGvF4?Ld+udKL&U6W)ND!dPlR5YP_piVH`cM1& zSNr>S`}^mq3H<%{cW`wb(M->nb$S={YHc_j)%%J|uXVmF*g1bTHkUcs z(EAehTW5B8G`>wv|M3j;&o{+;2O70q(=&3FI*Y#?q9qKoDz>Z0)btJ!tG}gxe>S0g zT80DW0U~Ho9AEYMs@{9O!m<*1j-$t`+HKA&UBC7G;2h$U&|^@cPp`aH zc6Iz|9lx)iU!LPnII({AJ>3e2-}eVR#mARz0_FxQHyO$ZQzJ`d=P-I&gY1(3wlhJu zk3hPExNz&QF+fALt+?mkg`=-JIIjNJkZ}^CnOerCx>qN~A|i}(q>P-sN{LnzXBNg} zRn0Zto#8TYPRAm)Ue@bB}dAc z%J}$3DUOA*8Xb~<5m)wEHjDj^u z(15st5)^TZHk?(A_ga8>A&wkulppJeL8OAH%wvPq>JlO&8#orJbhUjuuIMS)T?S9F ztzq@Py3!?BWEg5{=28~xh$|5$y2{Drk=6#FKYI%V%v2;Un)Un8)io!kh&}3`f7|uk5;@5 z^kiecLkK-l)ic~u@ko7ap5@ceHs`ua@k)*9X-7GO6>XVAo)}OfP~5?DmsfWTETPmK zq4a`N%pmn6a0d(+xVy)xbf|--8T-K1 zWeu0MVm!}74bD`0t{^dP`PV#FXYoX2#GZ2=SLIbibzm`}4MqryymKbiPjMzbiwCjp z+A(7|L^Hf1p*>_RT>Mv%G?yM}AnSUZ%9!u?D9?WW6^~=BPtdXMqx!2(Gm8EF*fls- z_j}g+bw8hl`o-E@adffJVjkb`ckGMVq5UX^Vbi-#qln6W5m1 zmltu$iwM6LuL~A(Ez);(6<4eyu5T>*V&wUz4&>uVwZ3Y8BPUfV??}#Bf7`k>J@Afs z&^u=X-;FT!w{6Gxh_#PR$Jj6rrCAfYD(4Z$`8^NB$WY%vV6Egr_3X=z7uV4_|^6D~6G<4R?rIWtc^axfi*XWmXAZ#$9CtEIy!|wZXOTM|X5(Rrk5V(()=t=f~Il8O0TKGyRr?z@MfNT< z-f7L2{YE>b;eGMvdP>1D1XfwUcs`4sfYQgt!i7Kcn;#Mbxz{w^}Q$c zuBj5Ejjj z-YZFn@#>wm3@8b^+*ImKND3RBH8+TRP&3Q6IJGgyas8g-Y`=CbuKu50=>@t4+toG* z8L`OIIY5)C9@yjR^N4!rEj7iF=DE{8ZR~1ku(L9 z<9+6EsT0RzZRH$|2dAnXtLODq?7`%C#_Ty?!hIs4xQ~BDy=4#S&*MDBJNpGz>xKmb zFd4&i>^Vbi->|Tk&*pzDZh9cDs=d+YaOhDt$EE9&h+3$JYACKnavQgE|KBG)dM|m5 zm~i}l@LNtM=}40*KP!lBlYj zn-KTMS2(02LA%G0qK=%snR}1E4u`@Jw>)3ry}M!9)0fDKFcv%jaC}Q zii&;;NlC2tVcG+qU+~**czs%H9-*JN!~(rBrE(`W7?X%_EZk?>10M#G66-2f?tImy zHZumo7^nZIO!n+KL9GU@zgK^_IIh3YG4-#p+-c8$rNM ztOgfXC;Z9yqD_?h{D5tkN4?|cCQ)`TM|fO=YZL9sm9Fq^tc@gJu|Xiga2CC+@MP=n zmNj4bgl9cJ51*eBZwU3cy=0o;Hi6#CAioEmJWoMUreG0EY=k*#HFCmAiPO@e+$U?J zQGP&e5Ys^~@2Bl#6-VB=Kk7jrgT>Zm9RX#L<4liO62GQf^&U*?-p!=JVtB1q{1Mo=^es*^r7%kJ^?*^{ay#uD^C}+SE42?f zDI}MsB2Z}_v3ne`sST($aMLZRq@Su)b{YESRc1|5wt(v6>@J*rRu|I~P%8HQ&PaO| z=D@6oU5i5lIVdgFX;W&{r$xpbq%c2WFN$bxR-^{8@*VHgMrM0ppNQMmZJRAMMJ)qy z0urVe1j$a}G_KsW^@tR>!wX__+xocNr<*lR@60m4PnE{yPyIrmncj!3{+&*)al5ux zIL_-2|3yW|8j$8ubBL2J&|r_f3s^7H5HL>&v564=8T?UMW@EF0-{t2A@^WnWZW@3HiiHWiOZR(u z4|%jHJoz|Eu#s;+8c(ucx_1~_RQ`GNM9v_gI!xt^R9?`r*IK%T4IcIiM$&?YTn5RQ zjV+rOq1Ik7RCF6Z0~|MC6=u@lPqzCrhF&Ucn2XS3s?yee9`*}4i<7yVKFfpA^tpvF)BMS~^|p46KC0JvGm_xJ zc+#R{8Ac4u$VKMD%ac!I(}0;nKAWHBgr73-qj-+`J(_=`cb{OB!ENfn2C+QQc^oX@ zpi!dZCtqt3gFl*`2ioNYbJY_OvtPr zp4^z-o-Qm(9AkTcXOmx*Yv{E8HTu_c*yx|>S!}nHW_Oo!M$)Via+1bMX(WrVyuf*> z&Q#)dnvdFISLrVhbDzIoQ2esv7*C&n-((1j#uuyo5%zbU1cS0VZX-E_L9yW>Lr}MW zhQAm%W4PxKz<%h-(+*=>PlQp_LcrQ!>v_bUGh#|0%`P7Jy|%h!3N-Nt9NG^c%E;HH_-Bv6HHm$RWXHf@3=DlLAaJaIL#9S{n~K4oD$cx zv}h>8qT7tsFt`1kJh31P%LC419kOS%X%Q?@8yiFzB+dchh&WHNAui3RAuDa50b4{k zGO;EmSMS_Q-wsMa{+g?!88g3|f}ZYi{UCVQc_Kv?4R(q*f@(Zy zGZhBS?HeWiOln@xx8HFY&_K|kX2wJ9xO&WR!nWXPxf_T`h7-4b*)p;XW1Fu#v7`lO z;il$0Pm|Ca&u~xp2kcH@HaCkKjCriFYC)Pj8(h)XNc|(z@vPEwCb;~?t%zs`#$hJ#w7v15 z#-KR1Yq7VJ`NqpED;ngH^+J#*d7crbMv2OZ+cBPq>)Gb)*Sf9)SnXTMK6I`jqi?7a zc@082*f5WbkcFp?-J@gA*~g3?dPjpSV6SA3MF)AFCl%eV1tD4aj%%w)KH_$a2U9X! z{UmW)I|y6b7)67v8_KYhF{jFm2!*yhqD*WM@KQl zhoLfaq?l103Fbzrv5uIvj5{XvV}8Yn4!xs67C5te8Toqp@ANyGu^lIkKn^`HAhTjn zX+B_Kq#*~#mD70=R9VlN)gtcsz-V&Ii;6%+n9}hrRA0#GRx`Z>q>aPzs7pg!Ohe8* zKT7Mc4@*oS%Xzj@k=mx7+>Vt_Ibx=>tz)r2<5B0x(NlHDkg3{-olc!1ZNxog7@^Vi z{K!--@p|pHZ&fa%Xr0Ma!3|2Z2MNm8d5Lvutu>x z2I<`P^_n^UzTa`W!>GqiH(#3dRqAN&QyF8oWBK#G#lDKH^FB19d0#6XW_3?|-q*yf zz#z)Jfiq${FrFa?8y$9^QmY*G>h;M)ZHG)DIa;DE7P4pLkunoeFkfzLL5pv#zy>bGA*Q!2l7@n|;^DyMHUgykpu zooU-K`lsCQ+}eSYac<-9ETm0InFt(f-Zd7R^^mT=LXV;dhG6!gJ;7=>C@GkHD7!xx$S+^uyXJ{ zXj9@MUp2&)q0d;Bh#Sx8C0 z7?I;v>Qn64ayrauYs@_t9Ln;|g08ov?CWXK-qB!vMUdZ9Hu0)$2l+(qhrGfh>JOE8BhUsxvA8HNJ?7SK3w3V1|*uc1|x(;)Uhh% z5m&3MWk3bk<)%`PpeW9K@^C|)>qJ&d2-f7rqBf5nt3Wx?H)~T)=3wWT$Lnu)7wK@p z>m)6c8c>pQVqy(O2#dV1Vl3o-b9wqq(_~=V2lE})36N~S|5Tp~wAyx4!n1;#Z zxVV>)iy4%So7Y_K(eV|JUh5tmzgD)%FvqU5U5eeyreSSyBGIc6D8`S=%1X$1>+OR#8_0bjwuFp#tByJXS076x9$zPz9ZkWC^_qRQrM8{# z!&zaEt1Q<0@LT-Gs8Y92jf3olUI0=2biXs5FYG-W&v>rI-*UfAyHri#gTHM+46)va z*Zry|9Prb$kJaE-cyM*(JUCfQ_EBrqGV9@;)nje!#L2aIuEm3QkGr}&M_zj$ V9%sf`&~f1h-#H^@h#__@^M3-gGN}Ln literal 0 HcmV?d00001 diff --git a/ext/gd/tests/gh13082.phpt b/ext/gd/tests/gh13082.phpt new file mode 100644 index 0000000000000..7434d699bee94 --- /dev/null +++ b/ext/gd/tests/gh13082.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-13082 - imagefontwidth/height unexpectedly throwing an exception on a valid GdFont object. +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +int(12) +int(20) From d57a7767a2e9778646c6fd5f1c96860a191751d3 Mon Sep 17 00:00:00 2001 From: Jan Palus Date: Wed, 10 Jan 2024 09:06:41 +0100 Subject: [PATCH 13/51] Set libtool tag per command instead of global one Global --tag=CC defined in configure.ac is not correct in all cases. For example linking objects that were compiled from C++ sources needs to be done with C++ compiler, however for link mode libtool will prefer compiler indicated with --tag. Fixes GH-12349 --- NEWS | 1 + build/Makefile.global | 4 ++-- build/php.m4 | 12 ++++++------ configure.ac | 5 ----- sapi/cgi/config9.m4 | 6 +++--- sapi/cli/config.m4 | 6 +++--- sapi/fpm/config.m4 | 4 ++-- sapi/fuzzer/Makefile.frag | 2 +- sapi/litespeed/config.m4 | 4 ++-- sapi/phpdbg/config.m4 | 4 ++-- 10 files changed, 22 insertions(+), 26 deletions(-) diff --git a/NEWS b/NEWS index b723d6e14d272..a75aaddfe6de2 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) + . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/build/Makefile.global b/build/Makefile.global index dee5fa5ecde73..b11ce20aae87a 100644 --- a/build/Makefile.global +++ b/build/Makefile.global @@ -16,8 +16,8 @@ build-modules: $(PHP_MODULES) $(PHP_ZEND_EX) build-binaries: $(PHP_BINARIES) libphp.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) - $(LIBTOOL) --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ - -@$(LIBTOOL) --silent --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1 + $(LIBTOOL) --tag=CC --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ + -@$(LIBTOOL) --silent --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1 libs/libphp.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp.so diff --git a/build/php.m4 b/build/php.m4 index 0599d0283fd9a..6ebc54b1b466d 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -786,10 +786,10 @@ dnl dnl PHP_BUILD_PROGRAM dnl AC_DEFUN([PHP_BUILD_PROGRAM],[ - php_c_pre='$(LIBTOOL) --mode=compile $(CC)' + php_c_pre='$(LIBTOOL) --tag=CC --mode=compile $(CC)' php_c_meta='$(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS)' php_c_post= - php_cxx_pre='$(LIBTOOL) --mode=compile $(CXX)' + php_cxx_pre='$(LIBTOOL) --tag=CXX --mode=compile $(CXX)' php_cxx_meta='$(COMMON_FLAGS) $(CXXFLAGS_CLEAN) $(EXTRA_CXXFLAGS)' php_cxx_post= php_lo=lo @@ -799,10 +799,10 @@ AC_DEFUN([PHP_BUILD_PROGRAM],[ no) pic_setting='-prefer-non-pic';; esac - shared_c_pre='$(LIBTOOL) --mode=compile $(CC)' + shared_c_pre='$(LIBTOOL) --tag=CC --mode=compile $(CC)' shared_c_meta='$(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) '$pic_setting shared_c_post= - shared_cxx_pre='$(LIBTOOL) --mode=compile $(CXX)' + shared_cxx_pre='$(LIBTOOL) --tag=CXX --mode=compile $(CXX)' shared_cxx_meta='$(COMMON_FLAGS) $(CXXFLAGS_CLEAN) $(EXTRA_CXXFLAGS) '$pic_setting shared_cxx_post= shared_lo=lo @@ -832,10 +832,10 @@ AC_DEFUN([PHP_SHARED_MODULE],[ PHP_SUBST($2) cat >>Makefile.objects<> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" else - BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" fi ;; *darwin*) BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; *) - BUILD_CGI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + BUILD_CGI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" ;; esac diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index d17d531683605..1b8e67f0b394e 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -33,16 +33,16 @@ if test "$PHP_CLI" != "no"; then case $host_alias in *aix*) if test "$php_sapi_module" = "shared"; then - BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" else - BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" fi ;; *darwin*) BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; *) - BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + BUILD_CLI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" ;; esac diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index da09511a0deb1..aa2a85d2ca632 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -745,13 +745,13 @@ if test "$PHP_FPM" != "no"; then case $host_alias in *aix*) - BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" + BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" ;; *darwin*) BUILD_FPM="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" ;; *) - BUILD_FPM="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" + BUILD_FPM="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" ;; esac diff --git a/sapi/fuzzer/Makefile.frag b/sapi/fuzzer/Makefile.frag index 8a456ca6c4f13..c4aefcd1af5d6 100644 --- a/sapi/fuzzer/Makefile.frag +++ b/sapi/fuzzer/Makefile.frag @@ -1,6 +1,6 @@ fuzzer: $(PHP_FUZZER_BINARIES) -FUZZER_BUILD = $(LIBTOOL) --mode=link $(FUZZING_CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(FUZZING_LIB) -rpath /ORIGIN/lib +FUZZER_BUILD = $(LIBTOOL) --tag=CC --mode=link $(FUZZING_CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(FUZZING_LIB) -rpath /ORIGIN/lib $(SAPI_FUZZER_PATH)/php-fuzz-parser: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_PARSER_OBJS) $(FUZZER_BUILD) $(PHP_FUZZER_PARSER_OBJS) -o $@ diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4 index 89074053852c3..f18697203cb2f 100644 --- a/sapi/litespeed/config.m4 +++ b/sapi/litespeed/config.m4 @@ -15,10 +15,10 @@ if test "$PHP_LITESPEED" != "no"; then ;; *cygwin*) SAPI_LITESPEED_PATH=sapi/litespeed/php.exe - BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" ;; *) - BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" ;; esac diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4 index ac95cf3c57f91..4bce37896d586 100644 --- a/sapi/phpdbg/config.m4 +++ b/sapi/phpdbg/config.m4 @@ -85,7 +85,7 @@ if test "$BUILD_PHPDBG" = "" && test "$PHP_PHPDBG" != "no"; then BUILD_BINARY="sapi/phpdbg/phpdbg" BUILD_SHARED="sapi/phpdbg/libphpdbg.la" - BUILD_PHPDBG="\$(LIBTOOL) --mode=link \ + BUILD_PHPDBG="\$(LIBTOOL) --tag=CC --mode=link \ \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \ \$(PHP_GLOBAL_OBJS:.lo=.o) \ \$(PHP_BINARY_OBJS:.lo=.o) \ @@ -96,7 +96,7 @@ if test "$BUILD_PHPDBG" = "" && test "$PHP_PHPDBG" != "no"; then \$(PHP_FRAMEWORKS) \ -o \$(BUILD_BINARY)" - BUILD_PHPDBG_SHARED="\$(LIBTOOL) --mode=link \ + BUILD_PHPDBG_SHARED="\$(LIBTOOL) --tag=CC --mode=link \ \$(CC) -shared -Wl,-soname,libphpdbg.so -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \ \$(PHP_GLOBAL_OBJS) \ \$(PHP_BINARY_OBJS) \ From b04b09ef563e46c1d594affeed71a4c35c91656b Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 4 Jan 2024 14:51:20 +0000 Subject: [PATCH 14/51] Fix GH-12996: Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path Closes GH-13072 --- NEWS | 4 ++ sapi/fpm/fpm/fpm_main.c | 2 +- ...v-pif-apache-pp-sn-strip-encoded-plus.phpt | 54 +++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 sapi/fpm/tests/fcgi-env-pif-apache-pp-sn-strip-encoded-plus.phpt diff --git a/NEWS b/NEWS index a75aaddfe6de2..bd3224b031d81 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) +- FPM: + . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when + plus in path). (Jakub Zelenka) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index b3ae2f69cc556..94a9ca6c7e604 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1165,7 +1165,7 @@ static void init_request_info(void) size_t decoded_path_info_len = 0; if (strchr(path_info, '%')) { decoded_path_info = estrdup(path_info); - decoded_path_info_len = php_url_decode(decoded_path_info, strlen(path_info)); + decoded_path_info_len = php_raw_url_decode(decoded_path_info, strlen(path_info)); } size_t snlen = strlen(env_script_name); size_t env_script_file_info_start = 0; diff --git a/sapi/fpm/tests/fcgi-env-pif-apache-pp-sn-strip-encoded-plus.phpt b/sapi/fpm/tests/fcgi-env-pif-apache-pp-sn-strip-encoded-plus.phpt new file mode 100644 index 0000000000000..4bef11ec668f0 --- /dev/null +++ b/sapi/fpm/tests/fcgi-env-pif-apache-pp-sn-strip-encoded-plus.phpt @@ -0,0 +1,54 @@ +--TEST-- +FPM: FastCGI env var path info fix for Apache ProxyPass SCRIPT_NAME encoded path and plush sign (GH-12996) +--SKIPIF-- + +--FILE-- +createSourceFileAndScriptName(); +$tester->start(); +$tester->expectLogStartNotices(); +$tester + ->request( + uri: $scriptName . '/1%202', + scriptFilename: "proxy:fcgi://" . $tester->getAddr() . $sourceFilePath . '/1%20+2', + scriptName: $scriptName . '/1 +2' + ) + ->expectBody([$scriptName, $scriptName . '/1 +2', $sourceFilePath, '/1%20+2', $scriptName . '/1%20+2']); +$tester->terminate(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + From 5a988d5764855aa25a60dc555357df1c35b44b55 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:32:11 +0100 Subject: [PATCH 15/51] Fix phar/tests/bug77432.phpt - For Windows we just have to set the right error_reporting value - Test cannot be used repeatedly on Opcache because the unlink will have no effect because of caching. Closes GH-13129. --- ext/phar/tests/bug77432.phpt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ext/phar/tests/bug77432.phpt b/ext/phar/tests/bug77432.phpt index 12480856b3952..b3b927a5439df 100644 --- a/ext/phar/tests/bug77432.phpt +++ b/ext/phar/tests/bug77432.phpt @@ -1,14 +1,10 @@ --TEST-- Bug #77432 (Segmentation fault on including phar file) ---SKIPIF-- - --EXTENSIONS-- phar --INI-- +opcache.enable=0 +error_reporting=-1 phar.readonly=0 --FILE-- Date: Sat, 13 Jan 2024 17:04:36 +0100 Subject: [PATCH 16/51] Follow-up fix for GH-13082 The font_obj should actually be NULL initialised, not the font gd pointer. Closes GH-13139. --- ext/gd/gd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index c86a663c5b7c1..509a5e4760626 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -2749,9 +2749,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode) gdImagePtr im; int ch = 0, col, x, y, i, l = 0; unsigned char *str = NULL; - zend_object *font_obj; + zend_object *font_obj = NULL; zend_long font_int = 0; - gdFontPtr font = NULL; ZEND_PARSE_PARAMETERS_START(6, 6) Z_PARAM_OBJECT_OF_CLASS(IM, gd_image_ce) @@ -2776,7 +2775,7 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode) y = Y; x = X; - font = php_find_gd_font(font_obj, font_int); + gdFontPtr font = php_find_gd_font(font_obj, font_int); switch (mode) { case 0: From 97c6da1dece1ff2b1b77708b106f5e46bc0c8c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sun, 14 Jan 2024 13:01:29 +0100 Subject: [PATCH 17/51] random/standard: Correctly handle broken engines in php_array_pick_keys (#13138) --- NEWS | 4 + .../03_randomizer/engine_unsafe_biased.phpt | 14 + .../engine_unsafe_empty_string.phpt | 14 + .../03_randomizer/engine_unsafe_nul.phpt | 322 ++++++++++++++++++ ext/standard/array.c | 30 +- 5 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 ext/random/tests/03_randomizer/engine_unsafe_nul.phpt diff --git a/NEWS b/NEWS index bd3224b031d81..ae34f72ec668e 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ PHP NEWS - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) +- Random: + . Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken + engines). (timwolla) + 18 Jan 2024, PHP 8.2.15 - Core: diff --git a/ext/random/tests/03_randomizer/engine_unsafe_biased.phpt b/ext/random/tests/03_randomizer/engine_unsafe_biased.phpt index 09fbd85b54eb0..9e911e826555b 100644 --- a/ext/random/tests/03_randomizer/engine_unsafe_biased.phpt +++ b/ext/random/tests/03_randomizer/engine_unsafe_biased.phpt @@ -43,6 +43,18 @@ try { echo $e->getMessage(), PHP_EOL; } +try { + var_dump(randomizer()->pickArrayKeys(range(1, 1234), 1)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->pickArrayKeys(range(1, 1234), 10)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + try { var_dump(randomizer()->shuffleBytes('foobar')); } catch (Random\BrokenRandomEngineError $e) { @@ -56,3 +68,5 @@ int(%d) string(2) "ff" Failed to generate an acceptable random number in 50 attempts Failed to generate an acceptable random number in 50 attempts +Failed to generate an acceptable random number in 50 attempts +Failed to generate an acceptable random number in 50 attempts diff --git a/ext/random/tests/03_randomizer/engine_unsafe_empty_string.phpt b/ext/random/tests/03_randomizer/engine_unsafe_empty_string.phpt index 01bd293bc0508..df9a5f8e267c0 100644 --- a/ext/random/tests/03_randomizer/engine_unsafe_empty_string.phpt +++ b/ext/random/tests/03_randomizer/engine_unsafe_empty_string.phpt @@ -43,6 +43,18 @@ try { echo $e->getMessage(), PHP_EOL; } +try { + var_dump(randomizer()->pickArrayKeys(range(1, 1234), 1)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->pickArrayKeys(range(1, 1234), 10)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + try { var_dump(randomizer()->shuffleBytes('foobar')); } catch (Random\BrokenRandomEngineError $e) { @@ -56,3 +68,5 @@ A random engine must return a non-empty string A random engine must return a non-empty string A random engine must return a non-empty string A random engine must return a non-empty string +A random engine must return a non-empty string +A random engine must return a non-empty string diff --git a/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt b/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt new file mode 100644 index 0000000000000..9320ae1af8f4a --- /dev/null +++ b/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt @@ -0,0 +1,322 @@ +--TEST-- +Random: Randomizer: Nul engines are correctly handled +--FILE-- +getInt(0, 1234)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->nextInt()); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(bin2hex(randomizer()->getBytes(1))); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->shuffleArray(range(1, 123))); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->pickArrayKeys(range(1, 123), 1)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->pickArrayKeys(range(1, 123), 10)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->shuffleBytes('foobar')); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +int(0) +int(0) +string(2) "00" +array(123) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) + [8]=> + int(10) + [9]=> + int(11) + [10]=> + int(12) + [11]=> + int(13) + [12]=> + int(14) + [13]=> + int(15) + [14]=> + int(16) + [15]=> + int(17) + [16]=> + int(18) + [17]=> + int(19) + [18]=> + int(20) + [19]=> + int(21) + [20]=> + int(22) + [21]=> + int(23) + [22]=> + int(24) + [23]=> + int(25) + [24]=> + int(26) + [25]=> + int(27) + [26]=> + int(28) + [27]=> + int(29) + [28]=> + int(30) + [29]=> + int(31) + [30]=> + int(32) + [31]=> + int(33) + [32]=> + int(34) + [33]=> + int(35) + [34]=> + int(36) + [35]=> + int(37) + [36]=> + int(38) + [37]=> + int(39) + [38]=> + int(40) + [39]=> + int(41) + [40]=> + int(42) + [41]=> + int(43) + [42]=> + int(44) + [43]=> + int(45) + [44]=> + int(46) + [45]=> + int(47) + [46]=> + int(48) + [47]=> + int(49) + [48]=> + int(50) + [49]=> + int(51) + [50]=> + int(52) + [51]=> + int(53) + [52]=> + int(54) + [53]=> + int(55) + [54]=> + int(56) + [55]=> + int(57) + [56]=> + int(58) + [57]=> + int(59) + [58]=> + int(60) + [59]=> + int(61) + [60]=> + int(62) + [61]=> + int(63) + [62]=> + int(64) + [63]=> + int(65) + [64]=> + int(66) + [65]=> + int(67) + [66]=> + int(68) + [67]=> + int(69) + [68]=> + int(70) + [69]=> + int(71) + [70]=> + int(72) + [71]=> + int(73) + [72]=> + int(74) + [73]=> + int(75) + [74]=> + int(76) + [75]=> + int(77) + [76]=> + int(78) + [77]=> + int(79) + [78]=> + int(80) + [79]=> + int(81) + [80]=> + int(82) + [81]=> + int(83) + [82]=> + int(84) + [83]=> + int(85) + [84]=> + int(86) + [85]=> + int(87) + [86]=> + int(88) + [87]=> + int(89) + [88]=> + int(90) + [89]=> + int(91) + [90]=> + int(92) + [91]=> + int(93) + [92]=> + int(94) + [93]=> + int(95) + [94]=> + int(96) + [95]=> + int(97) + [96]=> + int(98) + [97]=> + int(99) + [98]=> + int(100) + [99]=> + int(101) + [100]=> + int(102) + [101]=> + int(103) + [102]=> + int(104) + [103]=> + int(105) + [104]=> + int(106) + [105]=> + int(107) + [106]=> + int(108) + [107]=> + int(109) + [108]=> + int(110) + [109]=> + int(111) + [110]=> + int(112) + [111]=> + int(113) + [112]=> + int(114) + [113]=> + int(115) + [114]=> + int(116) + [115]=> + int(117) + [116]=> + int(118) + [117]=> + int(119) + [118]=> + int(120) + [119]=> + int(121) + [120]=> + int(122) + [121]=> + int(123) + [122]=> + int(1) +} +array(1) { + [0]=> + int(0) +} +Failed to generate an acceptable random number in 50 attempts +string(6) "oobarf" diff --git a/ext/standard/array.c b/ext/standard/array.c index 19b7dc1f8e8ab..361d83b10df41 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -5833,6 +5833,9 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * * specific offset using linear scan. */ i = 0; randval = algo->range(status, 0, num_avail - 1); + if (EG(exception)) { + return false; + } ZEND_HASH_FOREACH_KEY(ht, num_key, string_key) { if (i == randval) { if (string_key) { @@ -5853,6 +5856,9 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * if (HT_IS_PACKED(ht)) { do { randval = algo->range(status, 0, ht->nNumUsed - 1); + if (EG(exception)) { + return false; + } zv = &ht->arPacked[randval]; if (!Z_ISUNDEF_P(zv)) { ZVAL_LONG(retval, randval); @@ -5862,6 +5868,9 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * } else { do { randval = algo->range(status, 0, ht->nNumUsed - 1); + if (EG(exception)) { + return false; + } b = &ht->arData[randval]; if (!Z_ISUNDEF(b->val)) { if (b->key) { @@ -5894,11 +5903,25 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * zend_bitset_clear(bitset, bitset_len); i = num_req; + int failures = 0; while (i) { randval = algo->range(status, 0, num_avail - 1); - if (!zend_bitset_in(bitset, randval)) { + if (EG(exception)) { + goto fail; + } + if (zend_bitset_in(bitset, randval)) { + /* Use PHP_RANDOM_RANGE_ATTEMPTS instead of the hardcoded 50 for 8.3+. */ + if (++failures > 50) { + if (!silent) { + zend_throw_error(random_ce_Random_BrokenRandomEngineError, "Failed to generate an acceptable random number in %d attempts", 50); + } + + goto fail; + } + } else { zend_bitset_incl(bitset, randval); i--; + failures = 0; } } @@ -5922,6 +5945,11 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * free_alloca(bitset, use_heap); return true; + + fail: + free_alloca(bitset, use_heap); + + return false; } /* }}} */ From 00ea756c939e8f0b3d7f2cbd9059c0373481f73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sun, 14 Jan 2024 13:05:44 +0100 Subject: [PATCH 18/51] random/standard: Adjust #13138 for PHP 8.3 --- .../tests/03_randomizer/engine_unsafe_nul.phpt | 14 ++++++++++++++ ext/standard/array.c | 5 ++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt b/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt index 9320ae1af8f4a..ff53b83b207a6 100644 --- a/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt +++ b/ext/random/tests/03_randomizer/engine_unsafe_nul.phpt @@ -61,6 +61,18 @@ try { echo $e->getMessage(), PHP_EOL; } +try { + var_dump(randomizer()->getBytesFromString('123', 10)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + var_dump(randomizer()->getBytesFromString(str_repeat('a', 500), 10)); +} catch (Random\BrokenRandomEngineError $e) { + echo $e->getMessage(), PHP_EOL; +} + ?> --EXPECTF-- int(0) @@ -320,3 +332,5 @@ array(1) { } Failed to generate an acceptable random number in 50 attempts string(6) "oobarf" +string(10) "1111111111" +string(10) "aaaaaaaaaa" diff --git a/ext/standard/array.c b/ext/standard/array.c index 7a82b936f7d8e..388b15a0879bb 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6179,10 +6179,9 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status * goto fail; } if (zend_bitset_in(bitset, randval)) { - /* Use PHP_RANDOM_RANGE_ATTEMPTS instead of the hardcoded 50 for 8.3+. */ - if (++failures > 50) { + if (++failures > PHP_RANDOM_RANGE_ATTEMPTS) { if (!silent) { - zend_throw_error(random_ce_Random_BrokenRandomEngineError, "Failed to generate an acceptable random number in %d attempts", 50); + zend_throw_error(random_ce_Random_BrokenRandomEngineError, "Failed to generate an acceptable random number in %d attempts", PHP_RANDOM_RANGE_ATTEMPTS); } goto fail; From ed64949d1206b6a7134301ee9a930b0ac3bd9d19 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sun, 14 Jan 2024 18:10:05 +0100 Subject: [PATCH 19/51] strtok is not comptime() Fixes GH-13145 Closes GH-13148 --- NEWS | 3 +++ Zend/tests/gh13145.phpt | 16 ++++++++++++++++ ext/standard/basic_functions.stub.php | 1 - ext/standard/basic_functions_arginfo.h | 4 ++-- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/gh13145.phpt diff --git a/NEWS b/NEWS index 0cff1a696ff19..13634ed23a00f 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ PHP NEWS . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) +- Opcache: + . Fixed bug GH-13145 (strtok() is not comptime). (ilutov) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/Zend/tests/gh13145.phpt b/Zend/tests/gh13145.phpt new file mode 100644 index 0000000000000..801944d164890 --- /dev/null +++ b/Zend/tests/gh13145.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-13145: strtok() misoptimization +--FILE-- + +--EXPECT-- +string(4) "This" +string(2) "is" +string(2) "an" +string(7) "example" +string(6) "string" diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 66b458897adb4..be9b024258ee8 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2337,7 +2337,6 @@ function implode(string|array $separator, ?array $array = null): string {} function join(string|array $separator, ?array $array = null): string {} /** - * @compile-time-eval * @refcount 1 */ function strtok(string $string, ?string $token = null): string|false {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 39500b2b582dc..99e08feddf590 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 487cee0751d47b18bf0a8fbdb050313783f1b369 */ + * Stub hash: 7389d094a842a2289cd32cb37386e5e40ea7e031 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -3087,7 +3087,7 @@ static const zend_function_entry ext_functions[] = { ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(explode, arginfo_explode) ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(implode, arginfo_implode) ZEND_FALIAS(join, implode, arginfo_join) - ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(strtok, arginfo_strtok) + ZEND_FE(strtok, arginfo_strtok) ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(strtoupper, arginfo_strtoupper) ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(strtolower, arginfo_strtolower) ZEND_FE(str_increment, arginfo_str_increment) From 5e2a586c9ae7e6be77b130de443c0a18a2ff4a00 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 10 Dec 2023 03:37:13 +0000 Subject: [PATCH 20/51] ext/openssl: fix libressl build. Close GH-12919 --- NEWS | 4 ++++ ext/openssl/openssl.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ae34f72ec668e..25e241987d678 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) +- OpenSSL: + . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. + (David Carlier). + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 59d938d77e8ca..f6ed67b805b67 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -61,7 +61,7 @@ #include #endif -#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_NO_ENGINE) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)) && !defined(OPENSSL_NO_ENGINE) #include #endif From cd483f136c76eb1b7b8a6a8ad4a66106d8bff066 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:15:04 +0100 Subject: [PATCH 21/51] Use getenv to prevent undefined key warning --- sapi/phpdbg/tests/gh12962.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/phpdbg/tests/gh12962.phpt b/sapi/phpdbg/tests/gh12962.phpt index c5cf9425d7c47..f307547397b95 100644 --- a/sapi/phpdbg/tests/gh12962.phpt +++ b/sapi/phpdbg/tests/gh12962.phpt @@ -7,7 +7,7 @@ if (!getenv('TEST_PHPDBG_EXECUTABLE')) die("SKIP: No TEST_PHPDBG_EXECUTABLE spec --FILE-- --EXPECT-- Executed .phpdbginit From fa751c7dd62406c44f739c0277796561010915b5 Mon Sep 17 00:00:00 2001 From: SakiTakamachi Date: Sun, 14 Jan 2024 00:30:21 +0900 Subject: [PATCH 22/51] Fix GH-13119 (#13125) Fixed an issue where pdo_firebird float and double type values were wrong. Changed from using `%F` format with `zend_strpprintf` to using `%H` format with `zend_strpprintf_unchecked`. Fixes GH-13119 Closes GH-13125 --- NEWS | 4 ++ ext/pdo_firebird/firebird_statement.c | 9 +++- ext/pdo_firebird/tests/gh10908.phpt | 12 ++--- ext/pdo_firebird/tests/gh13119.phpt | 77 +++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 ext/pdo_firebird/tests/gh13119.phpt diff --git a/NEWS b/NEWS index 25e241987d678..e5014b67ebe15 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. (David Carlier). +- PDO_Firebird: + . Fix GH-13119 (Changed to convert float and double values ​​into strings using + `H` format). (SakiTakamachi) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 4ad51ab483d96..1fe894cd631df 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -51,6 +51,11 @@ static zend_always_inline double get_double_from_sqldata(const ISC_SCHAR *sqldat READ_AND_RETURN_USING_MEMCPY(double, sqldata); } +static zend_always_inline float get_float_from_sqldata(const ISC_SCHAR *sqldata) +{ + READ_AND_RETURN_USING_MEMCPY(float, sqldata); +} + static zend_always_inline ISC_TIMESTAMP get_isc_timestamp_from_sqldata(const ISC_SCHAR *sqldata) { READ_AND_RETURN_USING_MEMCPY(ISC_TIMESTAMP, sqldata); @@ -459,11 +464,11 @@ static int firebird_stmt_get_col( break; case SQL_FLOAT: /* TODO: Why is this not returned as the native type? */ - ZVAL_STR(result, zend_strpprintf(0, "%F", *(float*)var->sqldata)); + ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.8H", get_float_from_sqldata(var->sqldata))); break; case SQL_DOUBLE: /* TODO: Why is this not returned as the native type? */ - ZVAL_STR(result, zend_strpprintf(0, "%F", get_double_from_sqldata(var->sqldata))); + ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.16H", get_double_from_sqldata(var->sqldata))); break; #ifdef SQL_BOOLEAN case SQL_BOOLEAN: diff --git a/ext/pdo_firebird/tests/gh10908.phpt b/ext/pdo_firebird/tests/gh10908.phpt index a1e8271ffd19b..bcd3bb1e20024 100644 --- a/ext/pdo_firebird/tests/gh10908.phpt +++ b/ext/pdo_firebird/tests/gh10908.phpt @@ -79,8 +79,8 @@ Array Array ( - [DBL] => 1.000000 - [0] => 1.000000 + [DBL] => 1 + [0] => 1 ) Array @@ -103,10 +103,10 @@ Array [1] => ABC [NUM] => 12.340 [2] => 12.340 - [DBL] => 1.000000 - [3] => 1.000000 - [FLT] => 2.000000 - [4] => 2.000000 + [DBL] => 1 + [3] => 1 + [FLT] => 2 + [4] => 2 [TS] => 2023-03-24 17:39:00 [5] => 2023-03-24 17:39:00 [MYDATE] => 2023-03-24 diff --git a/ext/pdo_firebird/tests/gh13119.phpt b/ext/pdo_firebird/tests/gh13119.phpt new file mode 100644 index 0000000000000..29524e3d3bf95 --- /dev/null +++ b/ext/pdo_firebird/tests/gh13119.phpt @@ -0,0 +1,77 @@ +--TEST-- +GH-13119 (float, double value is incorrect) +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +exec('CREATE TABLE gh13119 (f_val FLOAT, d_val DOUBLE PRECISION)'); + +$dbh->exec('INSERT INTO gh13119 VALUES (0.1, 0.1)'); +$dbh->exec('INSERT INTO gh13119 VALUES (0.0000000000000001, 0.0000000000000001)'); +$dbh->exec('INSERT INTO gh13119 VALUES (12.000000, 12.00000000000000)'); +$dbh->exec('INSERT INTO gh13119 VALUES (12.000001, 12.00000000000001)'); +$dbh->exec('INSERT INTO gh13119 VALUES (12.345678, 12.34567890123456)'); +$dbh->exec('INSERT INTO gh13119 VALUES (0.0000000000000000012345678, 0.000000000000000001234567890123456)'); + +$stmt = $dbh->query('select * from gh13119'); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +?> +--CLEAN-- +exec('DROP TABLE gh13119'); +unset($dbh); +?> +--EXPECT-- +array(6) { + [0]=> + array(2) { + ["F_VAL"]=> + string(3) "0.1" + ["D_VAL"]=> + string(3) "0.1" + } + [1]=> + array(2) { + ["F_VAL"]=> + string(7) "1.0E-16" + ["D_VAL"]=> + string(7) "1.0E-16" + } + [2]=> + array(2) { + ["F_VAL"]=> + string(2) "12" + ["D_VAL"]=> + string(2) "12" + } + [3]=> + array(2) { + ["F_VAL"]=> + string(9) "12.000001" + ["D_VAL"]=> + string(17) "12.00000000000001" + } + [4]=> + array(2) { + ["F_VAL"]=> + string(9) "12.345678" + ["D_VAL"]=> + string(17) "12.34567890123456" + } + [5]=> + array(2) { + ["F_VAL"]=> + string(13) "1.2345678E-18" + ["D_VAL"]=> + string(21) "1.234567890123456E-18" + } +} From 9814d4a1912b9eab6bbf3a98524315e290572510 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Mon, 15 Jan 2024 22:11:47 +0100 Subject: [PATCH 23/51] Fix missing error check in curl_multi_init() Closes GH-13157. --- NEWS | 3 +++ ext/curl/multi.c | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index e5014b67ebe15..c826604c07f80 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,9 @@ PHP NEWS . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) +- Curl: + . Fix missing error check in curl_multi_init(). (divinity76) + - FPM: . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 3d6f789e317ec..e8c32301d2e4d 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -60,12 +60,17 @@ static inline php_curlm *curl_multi_from_obj(zend_object *obj) { PHP_FUNCTION(curl_multi_init) { php_curlm *mh; + CURLM *multi; ZEND_PARSE_PARAMETERS_NONE(); - + multi = curl_multi_init(); + if (UNEXPECTED(multi == NULL)) { + zend_throw_error(NULL, "%s(): Could not initialize a new cURL multi handle", get_active_function_name()); + RETURN_THROWS(); + } object_init_ex(return_value, curl_multi_ce); mh = Z_CURL_MULTI_P(return_value); - mh->multi = curl_multi_init(); + mh->multi = multi; zend_llist_init(&mh->easyh, sizeof(zval), _php_curl_multi_cleanup_list, 0); } From 2cde4b2ea46129f7a11ac6c6234dd4691e05a8f3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:21:30 +0100 Subject: [PATCH 24/51] Fix GH-13097: Anonymous class reference in trigger_error / thrown Exception Closes GH-13153. --- NEWS | 2 ++ Zend/tests/gh13097_a.phpt | 15 +++++++++++++++ Zend/tests/gh13097_b.phpt | 18 ++++++++++++++++++ Zend/zend_builtin_functions.c | 7 +++---- Zend/zend_exceptions.c | 3 ++- main/main.c | 12 +++++++++--- 6 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 Zend/tests/gh13097_a.phpt create mode 100644 Zend/tests/gh13097_b.phpt diff --git a/NEWS b/NEWS index c826604c07f80..5509955c51ccc 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) + . Fixed bug GH-13097 (Anonymous class reference in trigger_error / thrown + Exception). (nielsdos) - Curl: . Fix missing error check in curl_multi_init(). (divinity76) diff --git a/Zend/tests/gh13097_a.phpt b/Zend/tests/gh13097_a.phpt new file mode 100644 index 0000000000000..b9ad729f66e4d --- /dev/null +++ b/Zend/tests/gh13097_a.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-13097 (Anonymous class reference in trigger_error / thrown Exception) +--FILE-- + +--EXPECTF-- +Fatal error: class@anonymous%s ...now you don't! in %s on line %d diff --git a/Zend/tests/gh13097_b.phpt b/Zend/tests/gh13097_b.phpt new file mode 100644 index 0000000000000..7473c99d9f499 --- /dev/null +++ b/Zend/tests/gh13097_b.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-13097 (Anonymous class reference in trigger_error / thrown Exception) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception: class@anonymous%s ...now you don't! in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 9c4b836caface..72cb07decbd38 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1108,10 +1108,9 @@ ZEND_FUNCTION(get_included_files) ZEND_FUNCTION(trigger_error) { zend_long error_type = E_USER_NOTICE; - char *message; - size_t message_len; + zend_string *message; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &message, &message_len, &error_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &message, &error_type) == FAILURE) { RETURN_THROWS(); } @@ -1128,7 +1127,7 @@ ZEND_FUNCTION(trigger_error) break; } - zend_error((int)error_type, "%s", message); + zend_error_zstr_at(error_type, zend_get_executed_filename_ex(), zend_get_executed_lineno(), message); // TODO Change to void RETURN_TRUE; } diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 2b2f6dfb4b38a..8ad603e51e71c 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -950,9 +950,10 @@ ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *ex, int severit file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE)); line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE)); + ZVAL_STR(&tmp, str); zend_error_va(severity | E_DONT_BAIL, (file && ZSTR_LEN(file) > 0) ? file : NULL, line, - "Uncaught %s\n thrown", ZSTR_VAL(str)); + "Uncaught %Z\n thrown", &tmp); zend_string_release_ex(str, 0); zend_string_release_ex(file, 0); diff --git a/main/main.c b/main/main.c index b2d03b4af8af4..83f8829890e40 100644 --- a/main/main.c +++ b/main/main.c @@ -1350,19 +1350,25 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c php_printf("%s
\n%s: %s in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(buf), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); zend_string_free(buf); } else { - php_printf("%s
\n%s: %s in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); + zval tmp; + ZVAL_STR(&tmp, message); + php_printf_unchecked("%s
\n%s: %Z in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, &tmp, ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); } } else { /* Write CLI/CGI errors to stderr if display_errors = "stderr" */ if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg")) && PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR ) { - fprintf(stderr, "%s: %s in %s on line %" PRIu32 "\n", error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno); + fprintf(stderr, "%s: ", error_type_str); + fwrite(ZSTR_VAL(message), sizeof(char), ZSTR_LEN(message), stderr); + fprintf(stderr, " in %s on line %" PRIu32 "\n", ZSTR_VAL(error_filename), error_lineno); #ifdef PHP_WIN32 fflush(stderr); #endif } else { - php_printf("%s\n%s: %s in %s on line %" PRIu32 "\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); + zval tmp; + ZVAL_STR(&tmp, message); + php_printf_unchecked("%s\n%s: %Z in %s on line %" PRIu32 "\n%s", STR_PRINT(prepend_string), error_type_str, &tmp, ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); } } } From b33e3eb8c2d0b10856072c93ed70c599cc8da4d1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Jan 2024 00:19:43 +0300 Subject: [PATCH 25/51] Fix zend_may_throw() for FETCH_DIM_IS and ISSET_ISEMPTY_DIM_OBJ Recentlty this insructions were updated to emit warning on inability to convert double index to long. This may lead to exception. This fixes memory leak on wordpress test suite (nightly workflow) --- Zend/Optimizer/zend_inference.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 9d6517bdedb09..681173f094d40 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5127,9 +5127,9 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_FETCH_IS: return (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); case ZEND_ISSET_ISEMPTY_DIM_OBJ: - return (t1 & MAY_BE_OBJECT) || (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); + return (t1 & MAY_BE_OBJECT) || (t2 & (MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT)); case ZEND_FETCH_DIM_IS: - return (t1 & MAY_BE_OBJECT) || (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); + return (t1 & MAY_BE_OBJECT) || (t2 & (MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); case ZEND_CAST: switch (opline->extended_value) { case IS_LONG: From 5e9e9c9d511866af8b6c6d336222a570e6ba5f62 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 13 Jan 2024 00:28:57 +0100 Subject: [PATCH 26/51] Fix GH-13071: Copying large files using mmap-able source streams may exhaust available memory and fail Commit 5cbe5a538c disabled chunking for all writes to streams. However, user streams have a callback where code is executed on data that is subject to the memory limit. Therefore, when using large writes or stream_copy_to_stream/copy the memory limit can easily be hit with large enough data. To solve this, we reintroduce chunking for userspace streams. Users have control over the chunk size, which is neat because they can improve the performance by setting the chunk size if that turns out to be a bottleneck. In an ideal world, we add an option so we can "ask" the stream whether it "prefers" chunked writes, similar to how we have php_stream_mmap_supported & friends. However, that cannot be done on stable branches. Closes GH-13136. --- NEWS | 4 ++ ext/standard/tests/file/gh13136.phpt | 55 +++++++++++++++++++ ext/standard/tests/file/userstreams_006.phpt | 3 +- .../tests/streams/set_file_buffer.phpt | 1 + .../tests/streams/stream_set_chunk_size.phpt | 16 ++++-- main/streams/streams.c | 9 ++- 6 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 ext/standard/tests/file/gh13136.phpt diff --git a/NEWS b/NEWS index 5509955c51ccc..e06ad13ca2f4c 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,10 @@ PHP NEWS . Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken engines). (timwolla) +- Streams: + . Fixed bug GH-13071 (Copying large files using mmap-able source streams may + exhaust available memory and fail). (nielsdos) + 18 Jan 2024, PHP 8.2.15 - Core: diff --git a/ext/standard/tests/file/gh13136.phpt b/ext/standard/tests/file/gh13136.phpt new file mode 100644 index 0000000000000..a90c07c91c280 --- /dev/null +++ b/ext/standard/tests/file/gh13136.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-13071 (Copying large files using mmap-able source streams may exhaust available memory and fail) +--FILE-- +trim_path($path); + $this->file = fopen($path, $mode); + return true; + } + + public function stream_close() { + fclose($this->file); + return true; + } + + public function stream_write($data) { + self::$writes++; + return fwrite($this->file, $data); + } + + public function url_stat($path, $flags) { + return false; + } + + private function trim_path(string $path): string { + return substr($path, strlen("up://")); + } +} + +file_put_contents(__DIR__ . "/gh13071.tmp", str_repeat("a", 1024 * 1024 * 8)); + +stream_wrapper_register("up", CustomStream::class, STREAM_IS_URL); + +$old_limit = ini_get("memory_limit"); +ini_set("memory_limit", memory_get_usage(true) + 5 * 1024 * 1024); +copy(__DIR__ . "/gh13071.tmp", "up://" . __DIR__ . "/gh13071.out.tmp"); +ini_set("memory_limit", $old_limit); + +echo "Done ", CustomStream::$writes, " writes\n"; + +?> +--CLEAN-- + +--EXPECT-- +Done 1024 writes diff --git a/ext/standard/tests/file/userstreams_006.phpt b/ext/standard/tests/file/userstreams_006.phpt index a432937dac29f..e5d341379f6d1 100644 --- a/ext/standard/tests/file/userstreams_006.phpt +++ b/ext/standard/tests/file/userstreams_006.phpt @@ -34,5 +34,6 @@ bool(true) option: 3, 2, 50 int(-1) int(8192) -size: 70 +size: 42 +size: 28 int(70) diff --git a/ext/standard/tests/streams/set_file_buffer.phpt b/ext/standard/tests/streams/set_file_buffer.phpt index ef808a24fd002..c39ba56cf6cfb 100644 --- a/ext/standard/tests/streams/set_file_buffer.phpt +++ b/ext/standard/tests/streams/set_file_buffer.phpt @@ -39,4 +39,5 @@ option: %d, %d, %d int(%i) int(%d) size: %d +size: 28 int(%d) diff --git a/ext/standard/tests/streams/stream_set_chunk_size.phpt b/ext/standard/tests/streams/stream_set_chunk_size.phpt index 77d9bac00ea4f..8bb5b46b7f94a 100644 --- a/ext/standard/tests/streams/stream_set_chunk_size.phpt +++ b/ext/standard/tests/streams/stream_set_chunk_size.phpt @@ -35,7 +35,7 @@ echo "should return previous chunk size (8192)\n"; var_dump(stream_set_chunk_size($f, 1)); echo "should be read without buffer (\$count == 10000)\n"; var_dump(strlen(fread($f, 10000))); -echo "should have no effect on writes\n"; +echo "should elicit 3 writes\n"; var_dump(fwrite($f, str_repeat('b', 3))); echo "should return previous chunk size (1)\n"; @@ -46,7 +46,7 @@ echo "should elicit one read of size 100 (chunk size)\n"; var_dump(strlen(fread($f, 50))); echo "should elicit no read because there is sufficient cached data\n"; var_dump(strlen(fread($f, 50))); -echo "should have no effect on writes\n"; +echo "should elicit 3 writes\n"; var_dump(strlen(fwrite($f, str_repeat('b', 250)))); echo "\nerror conditions\n"; @@ -68,8 +68,10 @@ int(8192) should be read without buffer ($count == 10000) read with size: 10000 int(10000) -should have no effect on writes -write with size: 3 +should elicit 3 writes +write with size: 1 +write with size: 1 +write with size: 1 int(3) should return previous chunk size (1) int(1) @@ -81,8 +83,10 @@ read with size: 100 int(50) should elicit no read because there is sufficient cached data int(50) -should have no effect on writes -write with size: 250 +should elicit 3 writes +write with size: 100 +write with size: 100 +write with size: 50 int(3) error conditions diff --git a/main/streams/streams.c b/main/streams/streams.c index e1399927b2783..d45a9bfab85f8 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1133,8 +1133,15 @@ static ssize_t _php_stream_write_buffer(php_stream *stream, const char *buf, siz stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position); } + /* See GH-13071: userspace stream is subject to the memory limit. */ + size_t chunk_size = count; + if (php_stream_is(stream, PHP_STREAM_IS_USERSPACE)) { + /* If the stream is unbuffered, we can only write one byte at a time. */ + chunk_size = stream->chunk_size; + } + while (count > 0) { - ssize_t justwrote = stream->ops->write(stream, buf, count); + ssize_t justwrote = stream->ops->write(stream, buf, MIN(chunk_size, count)); if (justwrote <= 0) { /* If we already successfully wrote some bytes and a write error occurred * later, report the successfully written bytes. */ From 42cbace1ad4ba20c4a17ea4d4cad3f78f633f161 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 16 Jan 2024 19:54:18 +0100 Subject: [PATCH 27/51] Fix range inference since "proper-range-semantics" RFC * Arrays returned from range are never empty * When step is a double value representable by a long, it is coerced implicitly. As such, passing a double step no longer guarantees that the result is a non-int array. Closes GH-13166 --- NEWS | 1 + Zend/Optimizer/zend_func_info.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 3a97a1c29a73c..9eb7441c917af 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ PHP NEWS - Opcache: . Fixed bug GH-13145 (strtok() is not comptime). (ilutov) + . Fixed type inference of range(). (ilutov) - OpenSSL: . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index e2c746bbf539c..69238c1458bb2 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -61,7 +61,7 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline, &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes]); uint32_t t3 = 0; - uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY | MAY_BE_ARRAY_EMPTY; + uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY; if (call_info->num_args == 3) { t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline, @@ -77,9 +77,7 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa } if ((t1 & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_DOUBLE)) && (t2 & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_DOUBLE))) { - if ((t3 & MAY_BE_ANY) != MAY_BE_DOUBLE) { - tmp |= MAY_BE_ARRAY_OF_LONG; - } + tmp |= MAY_BE_ARRAY_OF_LONG; } if (tmp & MAY_BE_ARRAY_OF_ANY) { tmp |= MAY_BE_ARRAY_PACKED; From 120bd364aaa8093bb592dcab4badba61d3103158 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:24:34 +0100 Subject: [PATCH 28/51] Fix crashes with entity references and predefined entities Closes GH-13004. --- NEWS | 3 ++ .../DOMEntityReference_predefined_free.phpt | 46 +++++++++++++++++++ .../delayed_freeing/entity_declaration.phpt | 20 ++++++-- ext/libxml/libxml.c | 43 +++++++++++++++-- 4 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 ext/dom/tests/DOMEntityReference_predefined_free.phpt diff --git a/NEWS b/NEWS index 9eb7441c917af..be15ce25d7401 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ PHP NEWS . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) +- LibXML: + . Fix crashes with entity references and predefined entities. (nielsdos) + - Opcache: . Fixed bug GH-13145 (strtok() is not comptime). (ilutov) . Fixed type inference of range(). (ilutov) diff --git a/ext/dom/tests/DOMEntityReference_predefined_free.phpt b/ext/dom/tests/DOMEntityReference_predefined_free.phpt new file mode 100644 index 0000000000000..4b971d83703ed --- /dev/null +++ b/ext/dom/tests/DOMEntityReference_predefined_free.phpt @@ -0,0 +1,46 @@ +--TEST-- +Freeing of a predefined DOMEntityReference +--EXTENSIONS-- +dom +--FILE-- + +--EXPECT-- +object(DOMEntityReference)#1 (17) { + ["nodeName"]=> + string(3) "amp" + ["nodeValue"]=> + NULL + ["nodeType"]=> + int(5) + ["parentNode"]=> + NULL + ["parentElement"]=> + NULL + ["childNodes"]=> + string(22) "(object value omitted)" + ["firstChild"]=> + string(22) "(object value omitted)" + ["lastChild"]=> + string(22) "(object value omitted)" + ["previousSibling"]=> + NULL + ["nextSibling"]=> + NULL + ["attributes"]=> + NULL + ["isConnected"]=> + bool(false) + ["namespaceURI"]=> + NULL + ["prefix"]=> + string(0) "" + ["localName"]=> + NULL + ["baseURI"]=> + NULL + ["textContent"]=> + string(0) "" +} diff --git a/ext/dom/tests/delayed_freeing/entity_declaration.phpt b/ext/dom/tests/delayed_freeing/entity_declaration.phpt index 3e082611c3583..c049be675be38 100644 --- a/ext/dom/tests/delayed_freeing/entity_declaration.phpt +++ b/ext/dom/tests/delayed_freeing/entity_declaration.phpt @@ -9,16 +9,30 @@ $doc->loadXML(<<<'XML' + ]> XML); -$entity = $doc->doctype->entities[0]; -var_dump($entity->nodeName, $entity->parentNode->nodeName); +$ref1 = $doc->createEntityReference("test"); +$ref2 = $doc->createEntityReference("myimage"); +$entity1 = $doc->doctype->entities[0]; +$entity2 = $doc->doctype->entities[1]; +if (strcmp($entity1->nodeName, $entity2->nodeName) < 0) { + // Entity ordering depends on the addresses + [$entity1, $entity2] = [$entity2, $entity1]; +} +var_dump($entity1->nodeName, $entity1->parentNode->nodeName); +var_dump($entity2->nodeName, $entity2->parentNode->nodeName); $doc->removeChild($doc->doctype); -var_dump($entity->nodeName, $entity->parentNode); +var_dump($entity1->nodeName, $entity1->parentNode); +var_dump($entity2->nodeName, $entity2->parentNode); ?> --EXPECT-- string(4) "test" string(5) "books" +string(7) "myimage" +string(5) "books" string(4) "test" NULL +string(7) "myimage" +NULL diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index e8654abeed700..299dd1e11de5f 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -207,12 +207,36 @@ static void php_libxml_node_free(xmlNodePtr node) * dtd is attached to the document. This works around the issue by inspecting the parent directly. */ case XML_ENTITY_DECL: { xmlEntityPtr entity = (xmlEntityPtr) node; - php_libxml_unlink_entity_decl(entity); - if (entity->orig != NULL) { - xmlFree((char *) entity->orig); - entity->orig = NULL; + if (entity->etype != XML_INTERNAL_PREDEFINED_ENTITY) { + php_libxml_unlink_entity_decl(entity); +#if LIBXML_VERSION >= 21200 + xmlFreeEntity(entity); +#else + if (entity->children != NULL && entity->owner && entity == (xmlEntityPtr) entity->children->parent) { + xmlFreeNodeList(entity->children); + } + xmlDictPtr dict = entity->doc != NULL ? entity->doc->dict : NULL; + if (dict == NULL || !xmlDictOwns(dict, entity->name)) { + xmlFree((xmlChar *) entity->name); + } + if (dict == NULL || !xmlDictOwns(dict, entity->ExternalID)) { + xmlFree((xmlChar *) entity->ExternalID); + } + if (dict == NULL || !xmlDictOwns(dict, entity->SystemID)) { + xmlFree((xmlChar *) entity->SystemID); + } + if (dict == NULL || !xmlDictOwns(dict, entity->URI)) { + xmlFree((xmlChar *) entity->URI); + } + if (dict == NULL || !xmlDictOwns(dict, entity->content)) { + xmlFree(entity->content); + } + if (dict == NULL || !xmlDictOwns(dict, entity->orig)) { + xmlFree(entity->orig); + } + xmlFree(entity); +#endif } - xmlFreeNode(node); break; } case XML_NOTATION_NODE: { @@ -1386,6 +1410,15 @@ PHP_LIBXML_API void php_libxml_node_free_resource(xmlNodePtr node) case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: break; + case XML_ENTITY_REF_NODE: + /* Entity reference nodes are special: their children point to entity declarations, + * but they don't own the declarations and therefore shouldn't free the children. + * Moreover, there can be more than one reference node for a single entity declarations. */ + php_libxml_unregister_node(node); + if (node->parent == NULL) { + php_libxml_node_free(node); + } + break; default: if (node->parent == NULL || node->type == XML_NAMESPACE_DECL) { php_libxml_node_free_list((xmlNodePtr) node->children); From 0d21a8dcb53367e3c060e68ed93527ce3413f8c6 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 24 Nov 2023 14:47:34 +0100 Subject: [PATCH 29/51] Fix GH-12107: When running a stored procedure (that returns a result set) twice, PHP crashes Closes GH-12771. --- NEWS | 4 +++ ext/mysqli/tests/gh12107.phpt | 59 +++++++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_ps.c | 5 ++- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 ext/mysqli/tests/gh12107.phpt diff --git a/NEWS b/NEWS index e06ad13ca2f4c..62702d878537b 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ PHP NEWS . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) +- MySQLnd: + . Fixed bug GH-12107 (When running a stored procedure (that returns a result + set) twice, PHP crashes). (nielsdos) + - OpenSSL: . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. (David Carlier). diff --git a/ext/mysqli/tests/gh12107.phpt b/ext/mysqli/tests/gh12107.phpt new file mode 100644 index 0000000000000..ca5dd4ba8f142 --- /dev/null +++ b/ext/mysqli/tests/gh12107.phpt @@ -0,0 +1,59 @@ +--TEST-- +GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query($sql); + +echo "Start or run 1\n"; +$stmt = $mysqli->prepare("call `gh12107`()"); +$stmt->execute(); +$stmt->bind_result($output); +var_dump($stmt->fetch()); +var_dump($output); +unset($output); +echo "End of run 1\n"; + +echo "Start or run 2\n"; +$stmt->execute(); +$stmt->bind_result($output); +var_dump($stmt->fetch()); +var_dump($output); +echo "End of run 2\n"; + +?> +--CLEAN-- + +--EXPECT-- +Start or run 1 +bool(true) +string(11) "hello world" +End of run 1 +Start or run 2 +bool(true) +string(11) "hello world" +End of run 2 diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 15ccec4522beb..c564fca3097e5 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -652,8 +652,11 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, const enum_my Executed, but the user hasn't started to fetch This will clean also the metadata, but after the EXECUTE call we will have it again. + stmt->result may be freed and nullified by free_stmt_result, transitively called from flush. */ - stmt->result->m.free_result_buffers(stmt->result); + if (stmt->result) { + stmt->result->m.free_result_buffers(stmt->result); + } stmt->state = MYSQLND_STMT_PREPARED; } else if (stmt->state < MYSQLND_STMT_PREPARED) { From c2c1710ed7153c8cfd9572ad6d933c0e9e5c8878 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 17 Jan 2024 17:13:35 +0100 Subject: [PATCH 30/51] Fix GH-13177: PHP 8.3.2: final private constructor not allowed when used in trait zend_compile has an exception to this rule for constructors using `zend_is_constructor`, which compares the function name to `__construct`. Sadly, `zend_is_constructor` is not a public API, but we can just do the string compare ourselves. Closes GH-13179. --- NEWS | 2 + Zend/tests/traits/bugs/gh13177.phpt | 63 +++++++++++++++++++++++++++++ Zend/zend_inheritance.c | 19 +++++++-- 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/traits/bugs/gh13177.phpt diff --git a/NEWS b/NEWS index 28206e9c5e297..1bdf3c5f3467a 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) . Fixed bug GH-13097 (Anonymous class reference in trigger_error / thrown Exception). (nielsdos) + . Fixed bug GH-13177 (PHP 8.3.2: final private constructor not allowed + when used in trait). (nielsdos) - Curl: . Fix missing error check in curl_multi_init(). (divinity76) diff --git a/Zend/tests/traits/bugs/gh13177.phpt b/Zend/tests/traits/bugs/gh13177.phpt new file mode 100644 index 0000000000000..42ef0ae9d60d7 --- /dev/null +++ b/Zend/tests/traits/bugs/gh13177.phpt @@ -0,0 +1,63 @@ +--TEST-- +GH-13177 (PHP 8.3.2: final private constructor not allowed when used in trait) +--FILE-- +getMethod("__construct"), "\n"; +} + +class Foo5 extends Foo3 { + private function __construct() {} +} + +?> +--EXPECTF-- +Warning: Private methods cannot be final as they are never overridden by other classes in %s on line %d +Method [ final private method __construct ] { + @@ %sgh13177.php 4 - 4 +} + +Method [ final private method __construct ] { + @@ %sgh13177.php 4 - 4 +} + +Method [ final private method __construct ] { + @@ %sgh13177.php 4 - 4 +} + +Method [ final private method __construct ] { + @@ %sgh13177.php 24 - 24 +} + + +Fatal error: Cannot override final method Foo3::__construct() in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 6362090ada908..ea8cc219a23a3 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1949,10 +1949,6 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_ zend_function *new_fn; bool check_inheritance = false; - if ((fn->common.fn_flags & (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) == (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) { - zend_error(E_COMPILE_WARNING, "Private methods cannot be final as they are never overridden by other classes"); - } - if ((existing_fn = zend_hash_find_ptr(&ce->function_table, key)) != NULL) { /* if it is the same function with the same visibility and has not been assigned a class scope yet, regardless * of where it is coming from there is no conflict and we do not need to add it again */ @@ -2033,6 +2029,17 @@ static void zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce) /* } /* }}} */ +static void zend_traits_check_private_final_inheritance(uint32_t original_fn_flags, zend_function *fn_copy, zend_string *name) +{ + /* If the function was originally already private+final, then it will have already been warned about. + * If the function became private+final only after applying modifiers, we need to emit the same warning. */ + if ((original_fn_flags & (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) != (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL) + && (fn_copy->common.fn_flags & (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)) == (ZEND_ACC_PRIVATE | ZEND_ACC_FINAL) + && !zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME)) { + zend_error(E_COMPILE_WARNING, "Private methods cannot be final as they are never overridden by other classes"); + } +} + static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, zend_class_entry *ce, HashTable *exclude_table, zend_class_entry **aliases) /* {{{ */ { zend_trait_alias *alias, **alias_ptr; @@ -2058,6 +2065,8 @@ static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, z fn_copy.common.fn_flags = alias->modifiers | fn->common.fn_flags; } + zend_traits_check_private_final_inheritance(fn->common.fn_flags, &fn_copy, alias->alias); + lcname = zend_string_tolower(alias->alias); zend_add_trait_method(ce, alias->alias, lcname, &fn_copy); zend_string_release_ex(lcname, 0); @@ -2095,6 +2104,8 @@ static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, z } } + zend_traits_check_private_final_inheritance(fn->common.fn_flags, &fn_copy, fnname); + zend_add_trait_method(ce, fn->common.function_name, fnname, &fn_copy); } } From 8d4e177d821a6e31c313f7f87f83d4391ed542e7 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 20 Jan 2024 23:48:50 +0000 Subject: [PATCH 31/51] ext/gd disable gh13082 test for travis. The sample file is for little endian architectures. Close GH-13208 --- ext/gd/tests/gh13082.phpt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/gd/tests/gh13082.phpt b/ext/gd/tests/gh13082.phpt index 7434d699bee94..edfca9d850fdc 100644 --- a/ext/gd/tests/gh13082.phpt +++ b/ext/gd/tests/gh13082.phpt @@ -2,6 +2,8 @@ GH-13082 - imagefontwidth/height unexpectedly throwing an exception on a valid GdFont object. --EXTENSIONS-- gd +--SKIPIF-- + --FILE-- Date: Sun, 14 Jan 2024 19:41:27 +0200 Subject: [PATCH 32/51] Do not allow zend.script_encoding to be set to 'pass' When investigating another bug reported by GitHub user 'tstangner', I discovered that PHP segfaults when the INI parameter zend.script_encoding is set to "pass". This bug dates back to December 2022 (caused by yours truly in 953864661a). If any PHP users in the wild were actually setting zend.script_encoding to "pass" (which would be an utterly useless thing to do), I expect that someone would have filed a bug report by now. The absence of such bug reports is evidence that nobody is doing this. Hence, it seems that the best fix is simply to disallow "pass" as a choice for zend.script_encoding. The internal function 'php_mb_zend_encoding_list_parser' which I am modifying to accomplish this has no other in-tree callers, aside from the 'exif' extension. Further, exif only calls the function with a few hard-coded values, and none of them are the string "pass", so this change will not have any impact on exif. --- Zend/tests/multibyte/multibyte_encoding_007.phpt | 15 +++++++++++++++ ext/mbstring/mbstring.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/multibyte/multibyte_encoding_007.phpt diff --git a/Zend/tests/multibyte/multibyte_encoding_007.phpt b/Zend/tests/multibyte/multibyte_encoding_007.phpt new file mode 100644 index 0000000000000..5e3323403d692 --- /dev/null +++ b/Zend/tests/multibyte/multibyte_encoding_007.phpt @@ -0,0 +1,15 @@ +--TEST-- +Don't segfault when zend.script_encoding=pass +--EXTENSIONS-- +mbstring +--INI-- +zend.multibyte=1 +zend.script_encoding=pass +internal_encoding=UTF-8 +--FILE-- + +--EXPECT-- +Warning: PHP Startup: INI setting contains invalid encoding "pass" in Unknown on line 0 +Done! diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index ad15dd6768e03..9cbf539431e56 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -474,7 +474,7 @@ static zend_result php_mb_zend_encoding_list_parser(const char *encoding_list, s return php_mb_parse_encoding_list( encoding_list, encoding_list_len, (const mbfl_encoding ***)return_list, return_size, - persistent, /* arg_num */ 0, /* allow_pass_encoding */ 1); + persistent, /* arg_num */ 0, /* allow_pass_encoding */ 0); } static const zend_encoding *php_mb_zend_internal_encoding_getter(void) From b45e7a613f42290b06c95c2c04c6401a2636606e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 22 Jan 2024 10:32:04 +0300 Subject: [PATCH 33/51] Wrap cleanup function call with zend_try. Fizes oss-fuzz #65911 --- sapi/fuzzer/fuzzer-sapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index 3a79e273106fa..e55099a5d0583 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -280,7 +280,9 @@ int fuzzer_do_request_from_buffer( CG(compiled_filename) = NULL; /* ??? */ if (before_shutdown) { - before_shutdown(); + zend_try { + before_shutdown(); + } zend_end_try(); } fuzzer_request_shutdown(); From 72526609413e8a8cd768ed4966c17b1a9db6c12c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 22 Jan 2024 10:01:25 +0100 Subject: [PATCH 34/51] Fix GH-13215 GCC 14 build --- Zend/zend_atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 617cde0ec5640..8aab3f11ada00 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -23,7 +23,7 @@ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || (__GNUC__ > (x))) /* Builtins are used to avoid library linkage */ -#if __has_feature(c_atomic) +#if __has_feature(c_atomic) && defined(__clang__) #define HAVE_C11_ATOMICS 1 #elif ZEND_GCC_PREREQ(4, 7) #define HAVE_GNUC_ATOMICS 1 From 242f89283e2c423a6a3a307713b13135dfd0074a Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 22 Jan 2024 10:59:00 +0100 Subject: [PATCH 35/51] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 62702d878537b..425455c5bcce4 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) . Fixed bug GH-13097 (Anonymous class reference in trigger_error / thrown Exception). (nielsdos) + . Fixed bug GH-13215 (GCC 14 build failure). (Remi) - Curl: . Fix missing error check in curl_multi_init(). (divinity76) From fae27cd8c43f8581c3c0cdbca9e0eda1ae6cb5d7 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 22 Jan 2024 10:59:34 +0100 Subject: [PATCH 36/51] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 1bdf3c5f3467a..743dc955568e7 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS Exception). (nielsdos) . Fixed bug GH-13177 (PHP 8.3.2: final private constructor not allowed when used in trait). (nielsdos) + . Fixed bug GH-13215 (GCC 14 build failure). (Remi) - Curl: . Fix missing error check in curl_multi_init(). (divinity76) From f120ac93a12c10abfddc6b7cff38b1235363c85a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 22 Jan 2024 15:56:12 +0300 Subject: [PATCH 37/51] Fix GH-12481: PHP crash with JIT enabled --- ext/opcache/jit/zend_jit_x86.dasc | 22 ++++++++++++++++++---- ext/opcache/tests/jit/gh12481.phpt | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/jit/gh12481.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index b0353c0d3d761..6d92a32d570e6 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4426,8 +4426,14 @@ static int zend_jit_math_long_long(dasm_State **Dst, } else { zend_reg tmp_reg; - if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { - tmp_reg = ZREG_R1; + if (Z_MODE(res_addr) == IS_MEM_ZVAL) { + if (Z_REG(res_addr) != ZREG_R0 && result_reg != ZREG_R0) { + tmp_reg = ZREG_R0; + } else if (Z_REG(res_addr) != ZREG_R1 && result_reg != ZREG_R1) { + tmp_reg = ZREG_R1; + } else { + tmp_reg = ZREG_R2; + } } else if (result_reg != ZREG_R0) { tmp_reg = ZREG_R0; } else { @@ -5295,8 +5301,16 @@ static int zend_jit_long_math_helper(dasm_State **Dst, } else { zend_reg tmp_reg; - if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { - tmp_reg = ZREG_R1; + if (Z_MODE(res_addr) == IS_MEM_ZVAL) { + if (Z_REG(res_addr) != ZREG_R0 && result_reg != ZREG_R0) { + tmp_reg = ZREG_R0; + } else if (Z_REG(res_addr) != ZREG_R1 && result_reg != ZREG_R1) { + tmp_reg = ZREG_R1; + } else { + tmp_reg = ZREG_R2; + } + } else if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R1) { + tmp_reg = ZREG_R0; } else if (result_reg != ZREG_R0) { tmp_reg = ZREG_R0; } else { diff --git a/ext/opcache/tests/jit/gh12481.phpt b/ext/opcache/tests/jit/gh12481.phpt new file mode 100644 index 0000000000000..0ee78b8767351 --- /dev/null +++ b/ext/opcache/tests/jit/gh12481.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-12481: PHP crash on Windows 64-bit with JIT enabled +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + +DONE +--EXPECTF-- +DONE From 7f7031eb72c02774c38929733bda9c036c54ea6c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:04:33 +0100 Subject: [PATCH 38/51] Fix GH-12504: Corrupted session written when there's a fatal error in autoloader For details and reasoning, see [1] and following. [1] https://github.com/php/php-src/issues/12504#issuecomment-1790870399 Closes GH-13207. --- NEWS | 4 +++ ext/session/session.c | 22 ++++++++---- ext/session/tests/gh12504.phpt | 62 ++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 ext/session/tests/gh12504.phpt diff --git a/NEWS b/NEWS index 425455c5bcce4..55875b8dd3b50 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,10 @@ PHP NEWS . Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken engines). (timwolla) +- Session: + . Fixed bug GH-12504 (Corrupted session written when there's a fatal error + in autoloader). (nielsdos) + - Streams: . Fixed bug GH-13071 (Copying large files using mmap-able source streams may exhaust available memory and fail). (nielsdos) diff --git a/ext/session/session.c b/ext/session/session.c index 6998432147f9c..6b63999297205 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -246,18 +246,28 @@ static zend_string *php_session_encode(void) /* {{{ */ } /* }}} */ +static ZEND_COLD void php_session_cancel_decode(void) +{ + php_session_destroy(); + php_session_track_init(); + php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed"); +} + static zend_result php_session_decode(zend_string *data) /* {{{ */ { if (!PS(serializer)) { php_error_docref(NULL, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object"); return FAILURE; } - if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) { - php_session_destroy(); - php_session_track_init(); - php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed"); - return FAILURE; - } + zend_try { + if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) { + php_session_cancel_decode(); + return FAILURE; + } + } zend_catch { + php_session_cancel_decode(); + zend_bailout(); + } zend_end_try(); return SUCCESS; } /* }}} */ diff --git a/ext/session/tests/gh12504.phpt b/ext/session/tests/gh12504.phpt new file mode 100644 index 0000000000000..eb19424eb5005 --- /dev/null +++ b/ext/session/tests/gh12504.phpt @@ -0,0 +1,62 @@ +--TEST-- +GH-12504 (Corrupted session written when there's a fatal error in autoloader) +--EXTENSIONS-- +session +--FILE-- + +--EXPECTF-- +Fatal error: Default value for property of type int may not be null. Use the nullable type ?int to allow null default value in %s on line %d + +Warning: Unknown: Failed to decode session object. Session has been destroyed in Unknown on line 0 +In shutdown function +array(0) { +} From f18710e362f1f083310dda733f01686f95463345 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 22 Jan 2024 22:37:18 +0100 Subject: [PATCH 39/51] Fix dumping of zend_string.val in gdb char val[1] is now interpreted as a single-character string by gdb, rather than char*. Closes GH-13222 --- .gdbinit | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.gdbinit b/.gdbinit index 6117922621068..0f1401ef564f1 100644 --- a/.gdbinit +++ b/.gdbinit @@ -66,18 +66,18 @@ define dump_bt if $func if $ex->This->value.obj if $func->common.scope - printf "%s->", $func->common.scope->name->val + printf "%s->", (char*)$func->common.scope->name->val else - printf "%s->", $ex->This->value.obj->ce.name->val + printf "%s->", (char*)$ex->This->value.obj->ce.name->val end else if $func->common.scope - printf "%s::", $func->common.scope->name->val + printf "%s::", (char*)$func->common.scope->name->val end end if $func->common.function_name - printf "%s(", $func->common.function_name->val + printf "%s(", (char*)$func->common.function_name->val else printf "(main" end @@ -109,7 +109,7 @@ define dump_bt printf "%f", $zvalue->value.dval end if $type == 6 - ____print_str $zvalue->value.str->val $zvalue->value.str->len + ____print_str (char*)$zvalue->value.str->val $zvalue->value.str->len end if $type == 7 printf "array(%d)[%p]", $zvalue->value.arr->nNumOfElements, $zvalue @@ -135,7 +135,7 @@ define dump_bt end if $func != 0 if $func->type == 2 - printf "%s:%d ", $func->op_array.filename->val, $ex->opline->lineno + printf "%s:%d ", (char*)$func->op_array.filename->val, $ex->opline->lineno else printf "[internal function]" end @@ -186,7 +186,7 @@ define ____printzv_contents printf "double: %f", $zvalue->value.dval end if $type == 6 - printf "string: %s", $zvalue->value.str->val + printf "string: %s", (char*)$zvalue->value.str->val end if $type == 7 printf "array: " @@ -208,7 +208,7 @@ define ____printzv_contents set $handle = $zvalue->value.obj.handle set $handlers = $zvalue->value.obj.handlers set $zobj = $zvalue->value.obj - set $cname = $zobj->ce->name->val + set $cname = (char*)$zobj->ce->name->val printf "(%s) #%d", $cname, $handle if ! $arg1 if $handlers->get_properties == &zend_std_get_properties @@ -233,7 +233,7 @@ define ____printzv_contents set $name = $p->key set $prop = (zend_property_info*)$p->val.value.ptr set $val = (zval*)((char*)$zobj + $prop->offset) - printf "%s => ", $name->val + printf "%s => ", (char*)$name->val printzv $val set $k = $k + 1 end @@ -348,7 +348,7 @@ define ____print_ht end printf "[%d] ", $i if $key - ____print_str $key->val $key->len + ____print_str (char*)$key->val $key->len printf " => " else printf "%d => ", $h @@ -365,7 +365,7 @@ define ____print_ht end if $arg1 == 3 set $func = (zend_function*)$val->value.ptr - printf "\"%s\"\n", $func->common.function_name->val + printf "\"%s\"\n", (char*)$func->common.function_name->val end if $arg1 == 4 set $const = (zend_constant *)$val->value.ptr @@ -423,15 +423,15 @@ define ____print_inh_class printf "final " end end - printf "class %s", $ce->name->val + printf "class %s", (char*)$ce->name->val if $ce->parent != 0 - printf " extends %s", $ce->parent->name->val + printf " extends %s", (char*)$ce->parent->name->val end if $ce->num_interfaces != 0 printf " implements" set $tmp = 0 while $tmp < $ce->num_interfaces - printf " %s", $ce->interfaces[$tmp]->name->val + printf " %s", (char*)$ce->interfaces[$tmp]->name->val set $tmp = $tmp + 1 if $tmp < $ce->num_interfaces printf "," @@ -443,10 +443,10 @@ end define ____print_inh_iface set $ce = $arg0 - printf "interface %s", $ce->name->val + printf "interface %s", (char*)$ce->name->val if $ce->num_interfaces != 0 set $ce = $ce->interfaces[0] - printf " extends %s", $ce->name->val + printf " extends %s", (char*)$ce->name->val else set $ce = 0 end @@ -486,7 +486,7 @@ define print_pi set $ptr_to_val = (zval*)((char*)$pi->ce->default_properties_table + $pi->offset - $initial_offset) printf "[%p] {\n", $pi printf " offset = %p\n", $pi->offset - printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val + printf " ce = [%p] %s\n", $pi->ce, (char*)$pi->ce->name->val printf " flags = 0x%x (", $pi->flags if $pi->flags & 0x100 printf "ZEND_ACC_PUBLIC" @@ -608,7 +608,7 @@ define print_zstr set $maxlen = $zstr->len end printf "string(%d) ", $zstr->len - ____print_str $zstr->val $zstr->len $maxlen + ____print_str (char*)$zstr->val $zstr->len $maxlen printf "\n" end From 1c1d785c4fba21a3f4e51dfd3025d20ca84508bb Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 23 Jan 2024 17:32:59 +0100 Subject: [PATCH 40/51] [skip ci] Fix 64-bit only test --- ext/opcache/tests/jit/gh12481.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/opcache/tests/jit/gh12481.phpt b/ext/opcache/tests/jit/gh12481.phpt index 0ee78b8767351..7c13db6f1210e 100644 --- a/ext/opcache/tests/jit/gh12481.phpt +++ b/ext/opcache/tests/jit/gh12481.phpt @@ -3,6 +3,10 @@ GH-12481: PHP crash on Windows 64-bit with JIT enabled --INI-- opcache.enable=1 opcache.enable_cli=1 +--SKIPIF-- + --FILE-- Date: Thu, 11 Jan 2024 22:09:42 +0200 Subject: [PATCH 41/51] Fix segfault caused by use of 'pass' encoding when mbstring converts multipart form POST data When mbstring.encoding_translation=1, and PHP receives an (RFC1867) form-based file upload, and the Content-Disposition HTTP header contains a filename for the uploaded file, PHP will internally invoke mbstring code to 1) try to auto-detect the text encoding of the filename, and if that succeeds, 2) convert the filename to internal text encoding. In such cases, the candidate text encodings which are considered during "auto-detection" are those listed in the INI parameter mbstring.http_input. Further, mbstring.http_input is one of the few contexts where mbstring allows the magic string "pass" to appear in place of an actual text encoding name. Before mbstring's encoding auto-detection function was reimplemented, the old implementation would never return "pass", even if "pass" was the only candidate it was given to choose from. It is not clear if this was intended by the original developers or not. This behavior was the result of some rather subtle details of the implementation. After mbstring's auto-detection function was reimplemented, if the new implementation was given only one candidate to choose, and it was not running in 'strict' mode, it would always return that candidate, even if the candidate was the non-encoding "pass". The upshot of all of this: Previously, if mbstring.encoding_translation=1 and mbstring.http_input=pass, encoding conversion of RFC1867 filenames would never be attempted. But after the reimplementation, encoding 'conversion' would occur (uselessly). Further, in December 2022, I reimplemented the relevant bit of encoding conversion code. When doing this, I never bothered to implement encoding/decoding routines for the non-encoding "pass", because I thought that they would never be used. Well, in the one case described above, those routines *would* have been used, had they actually existed. Because they didn't exist, we get a nice NULL pointer dereference and ensuing segfault instead. Instead of 'fixing' this by adding encoding/decoding routines for the non-encoding "pass", I have modified the function which the RFC1867 form-handling code invokes to auto-detect input encoding. This function will never return "pass" now, just like the previous implementation. Thanks to the GitHub user 'tstangner' for reporting this bug. --- ext/mbstring/mbstring.c | 32 +++++++++++++++++++------------- ext/mbstring/tests/gh13123.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 ext/mbstring/tests/gh13123.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 9cbf539431e56..cf4c1c32c5915 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -291,8 +291,7 @@ static size_t count_commas(const char *p, const char *end) { * Emits a ValueError in function context and a warning in INI context, in INI context arg_num must be 0. */ static zend_result php_mb_parse_encoding_list(const char *value, size_t value_length, - const mbfl_encoding ***return_list, size_t *return_size, bool persistent, uint32_t arg_num, - bool allow_pass_encoding) + const mbfl_encoding ***return_list, size_t *return_size, bool persistent, uint32_t arg_num) { if (value == NULL || value_length == 0) { *return_list = NULL; @@ -345,8 +344,7 @@ static zend_result php_mb_parse_encoding_list(const char *value, size_t value_le } } } else { - const mbfl_encoding *encoding = - allow_pass_encoding ? php_mb_get_encoding_or_pass(p1) : mbfl_name2encoding(p1); + const mbfl_encoding *encoding = mbfl_name2encoding(p1); if (!encoding) { /* Called from an INI setting modification */ if (arg_num == 0) { @@ -452,8 +450,12 @@ static const zend_encoding *php_mb_zend_encoding_detector(const unsigned char *a list = (const zend_encoding**)MBSTRG(current_detect_order_list); list_size = MBSTRG(current_detect_order_list_size); } - - return (const zend_encoding*)mb_guess_encoding((unsigned char*)arg_string, arg_length, (const mbfl_encoding **)list, list_size, false, false); + if (list_size == 1 && ((mbfl_encoding*)*list) == &mbfl_encoding_pass) { + /* Emulate behavior of previous implementation; it would never return "pass" + * from an encoding auto-detection operation */ + return NULL; + } + return (const zend_encoding*)mb_guess_encoding((unsigned char*)arg_string, arg_length, (const mbfl_encoding**)list, list_size, false, false); } static size_t php_mb_zend_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const zend_encoding *encoding_to, const zend_encoding *encoding_from) @@ -474,7 +476,7 @@ static zend_result php_mb_zend_encoding_list_parser(const char *encoding_list, s return php_mb_parse_encoding_list( encoding_list, encoding_list_len, (const mbfl_encoding ***)return_list, return_size, - persistent, /* arg_num */ 0, /* allow_pass_encoding */ 0); + persistent, /* arg_num */ 0); } static const zend_encoding *php_mb_zend_internal_encoding_getter(void) @@ -712,7 +714,7 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) return SUCCESS; } - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, /* persistent */ 1, /* arg_num */ 0, /* allow_pass_encoding */ 0) || size == 0) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, /* persistent */ 1, /* arg_num */ 0) || size == 0) { return FAILURE; } @@ -728,7 +730,11 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) static int _php_mb_ini_mbstring_http_input_set(const char *new_value, size_t new_value_length) { const mbfl_encoding **list; size_t size; - if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, /* persistent */ 1, /* arg_num */ 0, /* allow_pass_encoding */ 1) || size == 0) { + if (new_value_length == 4 && strncmp(new_value, "pass", 4) == 0) { + list = (const mbfl_encoding**)pecalloc(1, sizeof(mbfl_encoding*), 1); + *list = &mbfl_encoding_pass; + size = 1; + } else if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, /* persistent */ 1, /* arg_num */ 0) || size == 0) { return FAILURE; } if (MBSTRG(http_input_list)) { @@ -1383,7 +1389,7 @@ PHP_FUNCTION(mb_detect_order) RETURN_THROWS(); } } else { - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(order_str), ZSTR_LEN(order_str), &list, &size, /* persistent */ 0, /* arg_num */ 1, /* allow_pass_encoding */ 0)) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(order_str), ZSTR_LEN(order_str), &list, &size, /* persistent */ 0, /* arg_num */ 1)) { RETURN_THROWS(); } } @@ -2799,7 +2805,7 @@ PHP_FUNCTION(mb_convert_encoding) } else if (from_encodings_str) { if (php_mb_parse_encoding_list(ZSTR_VAL(from_encodings_str), ZSTR_LEN(from_encodings_str), &from_encodings, &num_from_encodings, - /* persistent */ 0, /* arg_num */ 3, /* allow_pass_encoding */ 0) == FAILURE) { + /* persistent */ 0, /* arg_num */ 3) == FAILURE) { RETURN_THROWS(); } free_from_encodings = true; @@ -3163,7 +3169,7 @@ PHP_FUNCTION(mb_detect_encoding) RETURN_THROWS(); } } else if (encoding_str) { - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, /* persistent */ 0, /* arg_num */ 2, /* allow_pass_encoding */ 0)) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, /* persistent */ 0, /* arg_num */ 2)) { RETURN_THROWS(); } } else { @@ -3564,7 +3570,7 @@ PHP_FUNCTION(mb_convert_variables) RETURN_THROWS(); } } else { - if (php_mb_parse_encoding_list(ZSTR_VAL(from_enc_str), ZSTR_LEN(from_enc_str), &elist, &elistsz, /* persistent */ 0, /* arg_num */ 2, /* allow_pass_encoding */ 0) == FAILURE) { + if (php_mb_parse_encoding_list(ZSTR_VAL(from_enc_str), ZSTR_LEN(from_enc_str), &elist, &elistsz, /* persistent */ 0, /* arg_num */ 2) == FAILURE) { RETURN_THROWS(); } } diff --git a/ext/mbstring/tests/gh13123.phpt b/ext/mbstring/tests/gh13123.phpt new file mode 100644 index 0000000000000..3944751d2dea4 --- /dev/null +++ b/ext/mbstring/tests/gh13123.phpt @@ -0,0 +1,24 @@ +--TEST-- +Segfault in mb_fast_convert() when mbstring.encoding_translation is enabled (GH-13123) +--EXTENSIONS-- +mbstring +--POST_RAW-- +Content-Type: multipart/form-data, boundary=Blah + +--Blah +Content-Disposition: form-data; name="file"; filename="file.txt" +Content-Type: text/plain + +foo +--Blah + +--INI-- +error_reporting=E_ALL&~E_DEPRECATED +mbstring.encoding_translation=On +mbstring.http_input=pass +--FILE-- + +--EXPECT-- +Done! From d417072ebe2049a018fa1b457bebf9b57b3b168a Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:59:40 +0100 Subject: [PATCH 42/51] Fix GH-13232: Segmentation fault will be reported when JIT is off but JIT_debug is still on Closes GH-13234. --- NEWS | 4 ++++ ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/tests/jit/gh13232.phpt | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/gh13232.phpt diff --git a/NEWS b/NEWS index 55875b8dd3b50..423fbe94df3c0 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,10 @@ PHP NEWS . Fixed bug GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes). (nielsdos) +- Opcache: + . Fixed bug GH-13232 (Segmentation fault will be reported when JIT is off but + JIT_debug is still on). (nielsdos) + - OpenSSL: . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. (David Carlier). diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index df965a4dbc76f..c4f169f811643 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -5040,7 +5040,7 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, bool reattached) ZEND_EXT_API void zend_jit_shutdown(void) { - if (JIT_G(debug) & ZEND_JIT_DEBUG_SIZE) { + if (JIT_G(debug) & ZEND_JIT_DEBUG_SIZE && dasm_ptr != NULL) { fprintf(stderr, "\nJIT memory usage: %td\n", (ptrdiff_t)((char*)*dasm_ptr - (char*)dasm_buf)); } diff --git a/ext/opcache/tests/jit/gh13232.phpt b/ext/opcache/tests/jit/gh13232.phpt new file mode 100644 index 0000000000000..aad5a7913f8a6 --- /dev/null +++ b/ext/opcache/tests/jit/gh13232.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-13232 (Segmentation fault will be reported when JIT is off but JIT_debug is still on) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=disable +opcache.jit_debug=0xfffff +--FILE-- + +--EXPECT-- +Done From ba80372a58351a45913d66576d9730d3065faa31 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 28 Dec 2023 22:41:32 +0100 Subject: [PATCH 43/51] Fix GH-13037: PharData incorrectly extracts zip file The code currently assumes that the extra field length of the central directory entry and the local entry are the same, but that's not the case. For example, the "Extended Timestamp extra field" differs in size for local vs central directory entries. This causes the file contents offset to be incorrect because it is based on the central directory length instead of the local entry length. Fix it by reading the local entry and getting the size from there as well as checking consistency for the file name length. Closes GH-13045. --- NEWS | 1 + ext/phar/tests/zip/files/gh13037.zip | Bin 0 -> 164 bytes ext/phar/tests/zip/gh13037.phpt | 17 ++++++++ ext/phar/zip.c | 59 +++++++++++++++++++-------- 4 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 ext/phar/tests/zip/files/gh13037.zip create mode 100644 ext/phar/tests/zip/gh13037.phpt diff --git a/NEWS b/NEWS index 423fbe94df3c0..34b6a0de4439d 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,7 @@ PHP NEWS - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) + . Fixed bug GH-13037 (PharData incorrectly extracts zip file). (nielsdos) - Random: . Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken diff --git a/ext/phar/tests/zip/files/gh13037.zip b/ext/phar/tests/zip/files/gh13037.zip new file mode 100644 index 0000000000000000000000000000000000000000..d039461237f435f763f8e67a39cbe18be6a22164 GIT binary patch literal 164 zcmWIWW@h1H0D*#)bHWu2tjySeY!GH)kYOlEEiMTS;bdSgxz?Ln1;nKl+zgB?FPMSS zAR;3*CnujPz?+dtjv1FJ5+K7F7=d_6BZvhtlNDknnt1`x)fV2yU!vFwN CjU6fg literal 0 HcmV?d00001 diff --git a/ext/phar/tests/zip/gh13037.phpt b/ext/phar/tests/zip/gh13037.phpt new file mode 100644 index 0000000000000..5e13bd37907d6 --- /dev/null +++ b/ext/phar/tests/zip/gh13037.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-13037 (PharData incorrectly extracts zip file) +--EXTENSIONS-- +phar +--FILE-- +extractTo(__DIR__ . '/out_gh13037/'); +echo file_get_contents(__DIR__ . '/out_gh13037/test'); +?> +--CLEAN-- + +--EXPECT-- +hello diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 1804d926b4ae2..1472906c8b9da 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -386,8 +386,6 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia entry.timestamp = phar_zip_d2u_time(zipentry.timestamp, zipentry.datestamp); entry.flags = PHAR_ENT_PERM_DEF_FILE; entry.header_offset = PHAR_GET_32(zipentry.offset); - entry.offset = entry.offset_abs = PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + PHAR_GET_16(zipentry.filename_len) + - PHAR_GET_16(zipentry.extra_len); if (PHAR_GET_16(zipentry.flags) & PHAR_ZIP_FLAG_ENCRYPTED) { PHAR_ZIP_FAIL("Cannot process encrypted zip files"); @@ -417,6 +415,42 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia entry.is_dir = 0; } + phar_zip_file_header local; /* Warning: only filled in when the entry is not a directory! */ + if (!entry.is_dir) { + /* A file has a central directory entry, and a local file header. Both of these contain the filename + * and the extra field data. However, at least the extra field data does not have to match between the two! + * This happens for example for the "Extended Timestamp extra field" where the local header has 2 extra fields + * in comparison to the central header. So we have to use the local header to find the right offset to the file + * contents, otherwise we're reading some garbage bytes before reading the actual file contents. */ + zend_off_t current_central_dir_pos = php_stream_tell(fp); + + php_stream_seek(fp, entry.header_offset, SEEK_SET); + if (sizeof(local) != php_stream_read(fp, (char *) &local, sizeof(local))) { + pefree(entry.filename, entry.is_persistent); + PHAR_ZIP_FAIL("phar error: internal corruption (cannot read local file header)"); + } + php_stream_seek(fp, current_central_dir_pos, SEEK_SET); + + /* verify local header + * Note: normally I'd check the crc32, and file sizes too here, but that breaks tests zip/bug48791.phpt & zip/odt.phpt, + * suggesting that something may be wrong with those files or the assumption doesn't hold. Anyway, the other checks + * _are_ performed for the alias file as was done in the past too. */ + if (entry.filename_len != PHAR_GET_16(local.filename_len)) { + pefree(entry.filename, entry.is_persistent); + PHAR_ZIP_FAIL("phar error: internal corruption (local file header does not match central directory)"); + } + + entry.offset = entry.offset_abs = entry.header_offset + + sizeof(phar_zip_file_header) + + entry.filename_len + + PHAR_GET_16(local.extra_len); + } else { + entry.offset = entry.offset_abs = entry.header_offset + + sizeof(phar_zip_file_header) + + entry.filename_len + + PHAR_GET_16(zipentry.extra_len); + } + if (entry.filename_len == sizeof(".phar/signature.bin")-1 && !strncmp(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { size_t read; php_stream *sigfile; @@ -445,7 +479,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia if (metadata) { php_stream_write(sigfile, metadata, PHAR_GET_16(locator.comment_len)); } - php_stream_seek(fp, sizeof(phar_zip_file_header) + entry.header_offset + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET); + php_stream_seek(fp, entry.offset, SEEK_SET); sig = (char *) emalloc(entry.uncompressed_filesize); read = php_stream_read(fp, sig, entry.uncompressed_filesize); if (read != entry.uncompressed_filesize || read <= 8) { @@ -563,28 +597,17 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { php_stream_filter *filter; - zend_off_t saveloc; - /* verify local file header */ - phar_zip_file_header local; /* archive alias found */ - saveloc = php_stream_tell(fp); - php_stream_seek(fp, PHAR_GET_32(zipentry.offset), SEEK_SET); - - if (sizeof(local) != php_stream_read(fp, (char *) &local, sizeof(local))) { - pefree(entry.filename, entry.is_persistent); - PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (cannot read local file header for alias)"); - } /* verify local header */ - if (entry.filename_len != PHAR_GET_16(local.filename_len) || entry.crc32 != PHAR_GET_32(local.crc32) || entry.uncompressed_filesize != PHAR_GET_32(local.uncompsize) || entry.compressed_filesize != PHAR_GET_32(local.compsize)) { + ZEND_ASSERT(!entry.is_dir); + if (entry.crc32 != PHAR_GET_32(local.crc32) || entry.uncompressed_filesize != PHAR_GET_32(local.uncompsize) || entry.compressed_filesize != PHAR_GET_32(local.compsize)) { pefree(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (local header of alias does not match central directory)"); } - /* construct actual offset to file start - local extra_len can be different from central extra_len */ - entry.offset = entry.offset_abs = - sizeof(local) + entry.header_offset + PHAR_GET_16(local.filename_len) + PHAR_GET_16(local.extra_len); + zend_off_t restore_pos = php_stream_tell(fp); php_stream_seek(fp, entry.offset, SEEK_SET); /* these next lines should be for php < 5.2.6 after 5.3 filters are fixed */ fp->writepos = 0; @@ -680,7 +703,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia } /* return to central directory parsing */ - php_stream_seek(fp, saveloc, SEEK_SET); + php_stream_seek(fp, restore_pos, SEEK_SET); } phar_set_inode(&entry); From 4a487294383009d71d9b9ba56f6b589335e70dca Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 24 Jan 2024 22:12:49 +0100 Subject: [PATCH 44/51] Fix GH-10344: imagettfbbox(): Could not find/open font UNC path libgd uses an incorrect absolute path check in gdft.c. It checks if either the path starts with a '/' (only valid on Posix btw), or whether it contains something of the form C:\ or C:/. However, this overlooks the possibility of using UNC paths on Windows. As we already do PHP-specific stuff with VCWD_ macros, use IS_ABSOLUTE_PATH to check for an absolute path which will take into account UNC paths as well. Closes GH-13241. --- NEWS | 4 ++++ ext/gd/libgd/gdft.c | 12 +++++++++++- ext/gd/tests/gh10344.phpt | 28 ++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 ext/gd/tests/gh10344.phpt diff --git a/NEWS b/NEWS index 34b6a0de4439d..174233753b0a3 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ PHP NEWS . Fixed bug GH-12996 (Incorrect SCRIPT_NAME with Apache ProxyPassMatch when plus in path). (Jakub Zelenka) +- GD: + . Fixed bug GH-10344 (imagettfbbox(): Could not find/open font UNC path). + (nielsdos) + - MySQLnd: . Fixed bug GH-12107 (When running a stored procedure (that returns a result set) twice, PHP crashes). (nielsdos) diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 554a656e625c9..6876ca6f6b428 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -401,7 +401,17 @@ static void *fontFetch (char **error, void *key) #ifdef NETWARE if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) { #else - if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) { + /* Actual length doesn't matter, just the minimum does up to length 2. */ + unsigned int min_length = 0; + if (name[0] != '\0') { + if (name[1] != '\0') { + min_length = 2; + } else { + min_length = 1; + } + } + ZEND_IGNORE_VALUE(min_length); /* On Posix systems this may be unused */ + if (IS_ABSOLUTE_PATH(name, min_length)) { #endif snprintf(fullname, sizeof(fullname) - 1, "%s", name); if (access(fullname, R_OK) == 0) { diff --git a/ext/gd/tests/gh10344.phpt b/ext/gd/tests/gh10344.phpt new file mode 100644 index 0000000000000..829f8f9c35cde --- /dev/null +++ b/ext/gd/tests/gh10344.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-10344 (imagettfbbox(): Could not find/open font UNC path) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(8) From f26dd1354b9ceafd4aeaa3318112000e463f7f85 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:30:23 +0100 Subject: [PATCH 45/51] Fix GH-10614: imagerotate will turn the picture all black, when rotated 90 This is a backport of the upstream libgd PR that was recently committed [1]. [1] https://github.com/libgd/libgd/pull/862 Closes GH-13246. --- NEWS | 2 + ext/gd/libgd/gd_rotate.c | 6 +-- ext/gd/tests/gh10614.phpt | 93 ++++++++++++++++++++++++++++++++++++++ ext/gd/tests/gh10614.png | Bin 0 -> 98 bytes 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 ext/gd/tests/gh10614.phpt create mode 100644 ext/gd/tests/gh10614.png diff --git a/NEWS b/NEWS index 174233753b0a3..8bc955af3d227 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ PHP NEWS - GD: . Fixed bug GH-10344 (imagettfbbox(): Could not find/open font UNC path). (nielsdos) + . Fixed bug GH-10614 (imagerotate will turn the picture all black, when + rotated 90). (nielsdos) - MySQLnd: . Fixed bug GH-12107 (When running a stored procedure (that returns a result diff --git a/ext/gd/libgd/gd_rotate.c b/ext/gd/libgd/gd_rotate.c index cc89652f03f79..53c6c9470db79 100644 --- a/ext/gd/libgd/gd_rotate.c +++ b/ext/gd/libgd/gd_rotate.c @@ -216,7 +216,7 @@ gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent) if (dst != NULL) { int old_blendmode = dst->alphaBlendingFlag; dst->alphaBlendingFlag = 0; - + dst->saveAlphaFlag = 1; dst->transparent = src->transparent; gdImagePaletteCopy (dst, src); @@ -263,7 +263,7 @@ gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent) if (dst != NULL) { int old_blendmode = dst->alphaBlendingFlag; dst->alphaBlendingFlag = 0; - + dst->saveAlphaFlag = 1; dst->transparent = src->transparent; gdImagePaletteCopy (dst, src); @@ -311,7 +311,7 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) if (dst != NULL) { int old_blendmode = dst->alphaBlendingFlag; dst->alphaBlendingFlag = 0; - + dst->saveAlphaFlag = 1; dst->transparent = src->transparent; gdImagePaletteCopy (dst, src); diff --git a/ext/gd/tests/gh10614.phpt b/ext/gd/tests/gh10614.phpt new file mode 100644 index 0000000000000..c0689141837cd --- /dev/null +++ b/ext/gd/tests/gh10614.phpt @@ -0,0 +1,93 @@ +--TEST-- +GH-10614 (imagerotate will turn the picture all black, when rotated 90) +--EXTENSIONS-- +gd +--SKIPIF-- +=')) die("skip test requires GD 2.3.4 or older"); +?> +--FILE-- + +--EXPECT-- +--- Angle 0 --- +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +--- Angle 90 --- +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +--- Angle 180 --- +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +--- Angle 270 --- +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" +string(1) "0" +string(1) "0" +string(8) "7f000000" +string(8) "7f000000" diff --git a/ext/gd/tests/gh10614.png b/ext/gd/tests/gh10614.png new file mode 100644 index 0000000000000000000000000000000000000000..baf1ea92fc9ce3dcf9c432876ec32f4de97d8dc4 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2|p6gzo_Z~#FKM@k2fFX`#x7{W0# oIUyn82metX5b)v2XxPBOP&0*z_4C4BZ=fOuPgg&ebxsLQ0Hm}QTmS$7 literal 0 HcmV?d00001 From d978ade0a975fa7d801151f5a8444e9f95538efa Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sun, 28 Jan 2024 20:39:17 +0200 Subject: [PATCH 46/51] Retroactively add NEWS entry for ec348a12 Thanks to Kalle Sommer Nielsen for suggesting that the change in ec348a12 should have been called out in NEWS. --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 9738d0ace16e1..a03d4e86ae906 100644 --- a/NEWS +++ b/NEWS @@ -105,6 +105,11 @@ PHP NEWS . Fixed bug GH-12936 (hash() function hangs endlessly if using sha512 on strings >= 4GiB). (nielsdos) +- MBString: + . When operating on a string with invalid encoding, mb_substr (as well + as mb_strstr and its variants) defines character indices in the same + way as other mbstring functions such as mb_strpos. (Alex Dowad) + - ODBC: . Fix crash on Apache shutdown with persistent connections. (nielsdos) From 397d4c244d9e5219ac5c8826c02ecd1a370ba89c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 30 Jan 2024 06:38:30 +0300 Subject: [PATCH 47/51] Fix GH-13193: Significant performance degradation in 'foreach' starting from PHP 8.2.13 (caused by garbage collection) (#13265) * Fix GH-13193: Significant performance degradation in 'foreach' starting from PHP 8.2.13 (caused by garbage collection) * Don't run zend_gc_remove_root_tmpvars() if GC is not active or GC buffer is empty --- Zend/zend_gc.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index ab5a04898de6e..e7d9c8ef29257 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1465,7 +1465,8 @@ static int gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buffe } static void zend_get_gc_buffer_release(void); -static void zend_gc_root_tmpvars(void); +static void zend_gc_check_root_tmpvars(void); +static void zend_gc_remove_root_tmpvars(void); ZEND_API int zend_gc_collect_cycles(void) { @@ -1473,6 +1474,10 @@ ZEND_API int zend_gc_collect_cycles(void) bool should_rerun_gc = 0; bool did_rerun_gc = 0; + if (GC_G(num_roots) && GC_G(gc_active)) { + zend_gc_remove_root_tmpvars(); + } + rerun_gc: if (GC_G(num_roots)) { int count; @@ -1669,7 +1674,7 @@ ZEND_API int zend_gc_collect_cycles(void) finish: zend_get_gc_buffer_release(); - zend_gc_root_tmpvars(); + zend_gc_check_root_tmpvars(); return total_count; } @@ -1707,7 +1712,7 @@ static void zend_get_gc_buffer_release(void) { * cycles. However, there are some rare exceptions where this is possible, in which case we rely * on the producing code to root the value. If a GC run occurs between the rooting and consumption * of the value, we would end up leaking it. To avoid this, root all live TMPVAR values here. */ -static void zend_gc_root_tmpvars(void) { +static void zend_gc_check_root_tmpvars(void) { zend_execute_data *ex = EG(current_execute_data); for (; ex; ex = ex->prev_execute_data) { zend_function *func = ex->func; @@ -1737,6 +1742,36 @@ static void zend_gc_root_tmpvars(void) { } } +static void zend_gc_remove_root_tmpvars(void) { + zend_execute_data *ex = EG(current_execute_data); + for (; ex; ex = ex->prev_execute_data) { + zend_function *func = ex->func; + if (!func || !ZEND_USER_CODE(func->type)) { + continue; + } + + uint32_t op_num = ex->opline - ex->func->op_array.opcodes; + for (uint32_t i = 0; i < func->op_array.last_live_range; i++) { + const zend_live_range *range = &func->op_array.live_range[i]; + if (range->start > op_num) { + break; + } + if (range->end <= op_num) { + continue; + } + + uint32_t kind = range->var & ZEND_LIVE_MASK; + if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) { + uint32_t var_num = range->var & ~ZEND_LIVE_MASK; + zval *var = ZEND_CALL_VAR(ex, var_num); + if (Z_REFCOUNTED_P(var)) { + GC_REMOVE_FROM_BUFFER(Z_COUNTED_P(var)); + } + } + } + } +} + #ifdef ZTS size_t zend_gc_globals_size(void) { From 3a5edcca4702dd1aa8e3141aaaa6764a43087fb5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 29 Jan 2024 17:26:07 +0100 Subject: [PATCH 48/51] Fix create_object checks Since PHP 8.3, object handlers may be changed by setting ce->default_object_handlers, rather than in ce->create_object. Some checks need to be extended to check for the default handlers. Closes GH-13272 --- Zend/Optimizer/escape_analysis.c | 26 ++++++++++++++++++++------ Zend/Optimizer/zend_inference.c | 11 +++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c index b7c0a5ec4466a..193479bae4b74 100644 --- a/Zend/Optimizer/escape_analysis.c +++ b/Zend/Optimizer/escape_analysis.c @@ -164,10 +164,17 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i /* These flags will always cause an exception */ ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT; - if (ce && !ce->parent && !ce->create_object && !ce->constructor && - !ce->destructor && !ce->__get && !ce->__set && - !(ce->ce_flags & forbidden_flags) && - (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (ce + && !ce->parent + && !ce->create_object + && ce->default_object_handlers->get_constructor == zend_std_get_constructor + && ce->default_object_handlers->dtor_obj == zend_objects_destroy_object + && !ce->constructor + && !ce->destructor + && !ce->__get + && !ce->__set + && !(ce->ce_flags & forbidden_flags) + && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { return 1; } break; @@ -227,8 +234,15 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va /* objects with destructors should escape */ zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( script, op_array, opline); - if (ce && !ce->create_object && !ce->constructor && - !ce->destructor && !ce->__get && !ce->__set && !ce->parent) { + if (ce + && !ce->create_object + && ce->default_object_handlers->get_constructor == zend_std_get_constructor + && ce->default_object_handlers->dtor_obj == zend_objects_destroy_object + && !ce->constructor + && !ce->destructor + && !ce->__get + && !ce->__set + && !ce->parent) { return 1; } break; diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 759284f104590..34d31a38c40ce 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -3776,6 +3776,7 @@ static zend_always_inline zend_result _zend_update_type_info( /* Unset properties will resort back to __get/__set */ if (ce && !ce->create_object + && ce->default_object_handlers->read_property == zend_std_read_property && !ce->__get && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; @@ -5069,8 +5070,14 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op const zend_ssa_var_info *var_info = ssa->var_info + ssa_op->op1_use; const zend_class_entry *ce = var_info->ce; - if (var_info->is_instanceof || - !ce || ce->create_object || ce->__get || ce->__set || ce->parent) { + if (var_info->is_instanceof + || !ce + || ce->create_object + || ce->default_object_handlers->write_property != zend_std_write_property + || ce->default_object_handlers->get_property_ptr_ptr != zend_std_get_property_ptr_ptr + || ce->__get + || ce->__set + || ce->parent) { return 1; } From 7c354b7cf2360828bff3566cea350ce1dc07aac2 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Tue, 30 Jan 2024 17:31:55 +0000 Subject: [PATCH 49/51] Move most of this to https://github.com/php/policies as per Policies RFC --- SECURITY.md | 159 ++-------------------------------------------------- 1 file changed, 4 insertions(+), 155 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 161e0810b5862..deb5a7a950a4d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,127 +1,4 @@ -# Vulnerability Disclosure Policy - -*This document was originally published at .* - -## Introduction - -For the sake of our users, we classify some of the issues found in PHP -as "security issues". This document is intended to explain which issues -are thus classified, how we handle those issues and how to report them. - -## Classification - -We classify as security issues bugs that: - -- allow users to execute unauthorized actions -- cross security boundaries -- access data that is not intended to be accessible -- severely impact accessibility or performance of the system - -The purpose of this classification is to alert the users and the -developers about the bugs that need to be prioritized in their handling. - -We define three categories of security issues, by their severity, -described below. Please note that this categorization is in many aspects -subjective, so it ultimately relies on the judgement of the PHP -developers. - -### High severity - -These issues may allow: - -- third party to compromise any, or most installations of PHP -- the execution of arbitrary code -- disabling the system completely -- access to any file a local PHP user can access. - -The issue can be triggered on any, or on most typical installations, and -does not require exotic and non-recommended settings to be triggered. - -This category also includes issues that can be triggered in code or -functions known to be frequently used (session, json, mysql, openssl, -etc.) during typical usage, and that require settings or configurations -that may not be strictly the best practice, but are commonly used. - -This category also may include issues that require special code or code -pattern if such code or pattern is present in many popular libraries. - -This kind of issues usually requires a CVE report. - -### Medium severity - -These issues may have the same potential to compromise an installation -as a high severity issue, but may also require: - -- an extension that is not commonly used -- a particular type of configuration that is used only in narrow - specific circumstances -- relies on old version of a third-party library being used -- code, or patterns of code, that are known to be used infrequently -- code that is very old, or extremely uncommon (and so is used - infrequently) - -This kind of issues usually will have a CVE number, unless the required -configuration is particularly exotic to the point it's not practically -usable. - -### Low severity - -This issue allows theoretical compromise of security, but practical -attack is usually impossible or extremely hard due to common practices -or limitations that are virtually always present or imposed. - -This also includes problems with configuration, documentation, and other -non-code parts of the PHP project that may mislead users, or cause them -to make their system, or their code less secure. - -Issues that can trigger unauthorized actions that do not seem to be -useful for any practical attack can also be categorized as low severity. - -Security issues, that are present only in unstable branches, belong to -this category, too. Any branch that has no stable release, is per se not -intended for the production use. - -Low severity issues usually do not need to have CVE and may, at the -discretion of the PHP developers, be disclosed publicly before the fix -is released or available. - -### Not a security issue - -We do not classify as a security issue any issue that: - -- requires invocation of specific code, which may be valid but is - obviously malicious -- requires invocation of functions with specific arguments, which may - be valid but are obviously malicious -- requires specific actions to be performed on the server, which are - not commonly performed, or are not commonly permissible for the user - (uid) executing PHP -- requires privileges superior to that of the user (uid) executing PHP -- requires the use of debugging facilities - ex. xdebug, var_dump -- requires the use of settings not recommended for production - ex. - error reporting to output -- requires the use of non-standard environment variables - ex. - USE_ZEND_ALLOC -- requires the use of non-standard builds - ex. obscure embedded - platform, not commonly used compiler -- requires the use of code or settings known to be insecure -- requires the use of FFI -- requires an open_basedir bypass - -## Handling issues - -High and medium severity fixes are merged into a private security repository, -and then merged to the main repository before the release is tagged. - -Low severity fixes are merged immediately after the fix is available and -handled like all regular bugs are handled consequently. However, release -managers may choose to pull those fixes into the RC branch after the -branch is created, and also backport them into a security-only release -branch. - -## FAQ - -### How do I report a security issue? +# Reporting Security Issues Please report security vulnerabilities on GitHub at: @@ -134,35 +11,7 @@ Vulnerability reports remain private until published. When published, you will be credited as a contributor, and your contribution will reflect the MITRE Credit System. -### What do you consider a responsible disclosure? - -Please report the issue as described above. Please communicate with -the developers about when the fix will be released - usually it's the -next monthly release after the bug was reported. Some issues can take -longer. After the fix is released (releases usually happen on Thursdays) -please feel free to disclose the issue as you see fit. - -### What if I think it's a security issue but the developers disagree? - -Please read the above and try to explain to us why it fits the -description. - -### What if the developers still don't think it's a security issue? - -We'll have to agree to disagree. - -### The bug I submitted was classified as "not a security issue." You don't believe it's real? - -It has nothing to do with the bug being real or its importance to -you. It just means it does not fit our specific definitions for issues -that we will handle in a special way. We fix a lot of non-security bugs -and pull requests are always welcome. - -### But you classified bug #424242 as a security issue, but not this one?! - -Each bug usually has its aspects, if a short discussion does not -yield agreement we'd rather do more fixing and less arguing. - -### Do you pay bounties for security issues? +# Vulnerability Policy -PHP is a volunteer project. We have no money, thus we can't pay bounties. +Our full policy is described at +https://github.com/php/policies/blob/main/security-classification.rst From 0454f4ade4ad41b86bbcc2c744512341f3f03560 Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Tue, 30 Jan 2024 12:43:37 -0500 Subject: [PATCH 50/51] PHP-8.2 is now for PHP 8.2.17-dev --- NEWS | 5 ++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 8bc955af3d227..42690f24be2cd 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.2.16 +?? ??? ????, PHP 8.2.17 + + +15 Feb 2024, PHP 8.2.16 - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) diff --git a/Zend/zend.h b/Zend/zend.h index 8e60a2de99aab..1c3ba9157d067 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.2.16-dev" +#define ZEND_VERSION "4.2.17-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index c345b92865093..365ce64875f36 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.2.16-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) +AC_INIT([PHP],[8.2.17-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index c9a922dae2608..f5d0211ee65a9 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 2 -#define PHP_RELEASE_VERSION 16 +#define PHP_RELEASE_VERSION 17 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.2.16-dev" -#define PHP_VERSION_ID 80216 +#define PHP_VERSION "8.2.17-dev" +#define PHP_VERSION_ID 80217 From 3a832a2aad405466c24a5e8e5798cf9de14fda14 Mon Sep 17 00:00:00 2001 From: Eric Mann Date: Tue, 13 Feb 2024 07:40:02 -0800 Subject: [PATCH 51/51] Update versions for PHP 8.3.3 --- NEWS | 2 +- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index a03d4e86ae906..dfa7a44b644ad 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.3.3 +15 Feb 2024, PHP 8.3.3 - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) diff --git a/Zend/zend.h b/Zend/zend.h index cddd0f3b04521..dab5bacd533c8 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.3.3-dev" +#define ZEND_VERSION "4.3.3" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index a9e96f3cef952..b0caf4200933e 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.3.3-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) +AC_INIT([PHP],[8.3.3],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index 841fe15f5b2ac..882d64be43ad3 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -3,6 +3,6 @@ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 3 #define PHP_RELEASE_VERSION 3 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.3.3-dev" +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.3.3" #define PHP_VERSION_ID 80303