From 2f17f157cac5ad4287408eecec98fccec20191c3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 29 Jul 2024 21:04:38 +0200 Subject: [PATCH 001/280] Support AVX-512 builds on Windows "Since limited support for `/arch:AVX512` was added in Visual Studio 2017, and expanded in Visual Studio 2019"[1], we can safely offer this option, since PHP 8.4 is supposed to build with Visual Studio 2022, and it is unlikely that someone tries to build PHP 8.4 with Visual Studio, requesting AVX-512 support. [1] --- win32/build/config.w32 | 2 +- win32/build/confutils.js | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index c4a617a2e16ec..668995045725b 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -393,7 +393,7 @@ ARG_WITH("test-ini-ext-exclude", "Comma separated list of shared extensions to \ be excluded from the test.ini", "no"); ARG_ENABLE("native-intrinsics", "Comma separated list of intrinsic optimizations to enable. \ - Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2. \ + Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2, avx512. \ SSE and SSE2 are enabled by default. The best instruction set specified will \ automatically enable all the older instruction sets. Note, that the produced binary \ might not work properly, if the chosen instruction sets are not available on the target \ diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 2288a23888aa8..647f525ee8f20 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3331,8 +3331,6 @@ function toolset_setup_common_cflags() function toolset_setup_intrinsic_cflags() { var default_enabled = "sse2"; - /* XXX AVX and above needs to be reflected in /arch, for now SSE4.2 is - the best possible optimization.*/ var avail = WScript.CreateObject("Scripting.Dictionary"); avail.Add("sse", "__SSE__"); avail.Add("sse2", "__SSE2__"); @@ -3341,7 +3339,7 @@ function toolset_setup_intrinsic_cflags() avail.Add("sse4.1", "__SSE4_1__"); avail.Add("sse4.2", "__SSE4_2__"); /* From oldest to newest. */ - var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2"); + var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512"); if (VS_TOOLSET) { if ("disabled" == PHP_NATIVE_INTRINSICS) { @@ -3367,9 +3365,9 @@ function toolset_setup_intrinsic_cflags() AC_DEFINE(avail.Item(list[i]), 1); } - /* All means all. __AVX__ and __AVX2__ are defined by compiler. */ - ADD_FLAG("CFLAGS","/arch:AVX2"); - configure_subst.Add("PHP_SIMD_SCALE", "AVX2"); + /* All means all. __AVX__, __AVX2__, and __AVX512*__ are defined by compiler. */ + ADD_FLAG("CFLAGS","/arch:AVX512"); + configure_subst.Add("PHP_SIMD_SCALE", "AVX512"); } else { var list = PHP_NATIVE_INTRINSICS.split(","); var j = 0; @@ -3378,7 +3376,7 @@ function toolset_setup_intrinsic_cflags() var it = list[i].toLowerCase(); if (scale[k] == it) { j = k > j ? k : j; - } else if (!avail.Exists(it) && "avx2" != it && "avx" != it) { + } else if (!avail.Exists(it) && "avx512" != it && "avx2" != it && "avx" != it) { WARNING("Unknown intrinsic name '" + it + "' ignored"); } } @@ -3395,7 +3393,10 @@ function toolset_setup_intrinsic_cflags() /* There is no explicit way to enable intrinsics between SSE3 and SSE4.2. The declared macros therefore won't affect the code generation, but will enable the guarded code parts. */ - if ("avx2" == scale[j]) { + if ("avx512" == scale[j]) { + ADD_FLAG("CFLAGS","/arch:AVX512"); + j -= 3; + } else if ("avx2" == scale[j]) { ADD_FLAG("CFLAGS","/arch:AVX2"); j -= 2; } else if ("avx" == scale[j]) { From 0b61b8dc99c2f109b3dd93a18bdc1d9341ccd66d Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 13 Aug 2024 20:16:40 +0100 Subject: [PATCH 002/280] PHP-8.3 is now for PHP-8.3.12-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 705a0b064106b..79dec1525b330 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.3.11 +?? ??? ????, PHP-8.3.12 + + +15 Aug 2024, PHP 8.3.11 - Core: . Fixed bug GH-15020 (Memory leak in Zend/Optimizer/escape_analysis.c). diff --git a/Zend/zend.h b/Zend/zend.h index 97dbc47bdbc11..c466d4bb3d7b6 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.3.11-dev" +#define ZEND_VERSION "4.3.12-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 62606b305c370..a84faac3a8dac 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.11-dev],[https://github.com/php/php-src/issues],[php],[https://www.php.net]) +AC_INIT([PHP],[8.3.12-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 7c89278a6fc12..a616287586ee6 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 11 +#define PHP_RELEASE_VERSION 12 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.3.11-dev" -#define PHP_VERSION_ID 80311 +#define PHP_VERSION "8.3.12-dev" +#define PHP_VERSION_ID 80312 From 5c9c275743df68dab0f7d08ab9002b04f40ab1a6 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 13 Aug 2024 18:12:50 +0100 Subject: [PATCH 003/280] Checks getrandom availability on solaris. To fix part of GH-15381. gcc nor clang provides a constant to distinguish illumos and solaris not the system provides a kernel version stamp like the BSD. thus, we simply check the symbol and remaing purposely conservative in the existing logic, using it only for solaris to avoid unexpected breakages for other systems. would need a different fix for higher branches. Close GH-15390 --- ext/random/config.m4 | 5 +++++ ext/random/random.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ext/random/config.m4 b/ext/random/config.m4 index a8e6d5a568991..bb4214a5c0830 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -14,6 +14,11 @@ AC_CHECK_HEADERS([CommonCrypto/CommonRandom.h], [], [], #include ]) +dnl +dnl Mostly for non Linux systems +dnl +AC_CHECK_FUNCS([getrandom]) + dnl dnl Setup extension dnl diff --git a/ext/random/random.c b/ext/random/random.c index e30a04259fb2b..576c8412f52f5 100644 --- a/ext/random/random.c +++ b/ext/random/random.c @@ -48,7 +48,7 @@ #if HAVE_SYS_PARAM_H # include -# if (__FreeBSD__ && __FreeBSD_version > 1200000) || (__DragonFly__ && __DragonFly_version >= 500700) || defined(__sun) +# if (__FreeBSD__ && __FreeBSD_version > 1200000) || (__DragonFly__ && __DragonFly_version >= 500700) || (defined(__sun) && defined(HAVE_GETRANDOM)) # include # endif #endif @@ -511,7 +511,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw) #else size_t read_bytes = 0; ssize_t n; -# if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || defined(__sun) +# if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || (defined(__sun) && defined(HAVE_GETRANDOM)) /* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD getrandom(2) function*/ /* Keep reading until we get enough entropy */ while (read_bytes < size) { From f1e5c63837cda0f73402180b7a50d271d63a53a7 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 13 Aug 2024 18:12:50 +0100 Subject: [PATCH 004/280] Checks getrandom availability on solaris. To fix part of GH-15381. gcc nor clang provides a constant to distinguish illumos and solaris not the system provides a kernel version stamp like the BSD. thus, we simply check the symbol and remaing purposely conservative in the existing logic, using it only for solaris to avoid unexpected breakages for other systems. would need a different fix for higher branches. Close GH-15390 --- ext/random/config.m4 | 5 +++++ ext/random/csprng.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ext/random/config.m4 b/ext/random/config.m4 index 86f8022475219..253979e3486e9 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -14,6 +14,11 @@ AC_CHECK_HEADERS([CommonCrypto/CommonRandom.h], [], [], #include ]) +dnl +dnl Mostly for non Linux systems +dnl +AC_CHECK_FUNCS([getrandom]) + dnl dnl Setup extension dnl diff --git a/ext/random/csprng.c b/ext/random/csprng.c index 106ec91affa26..bbf12f567c10b 100644 --- a/ext/random/csprng.c +++ b/ext/random/csprng.c @@ -46,7 +46,7 @@ #if HAVE_SYS_PARAM_H # include # if (__FreeBSD__ && __FreeBSD_version > 1200000) || (__DragonFly__ && __DragonFly_version >= 500700) || \ - defined(__sun) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) + (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) # include # endif #endif @@ -98,7 +98,7 @@ PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw) #else size_t read_bytes = 0; # if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ - defined(__sun) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) + (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) /* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD/NetBSD getrandom(2) function * Being a syscall, implemented in the kernel, getrandom offers higher quality output * compared to the arc4random api albeit a fallback to /dev/urandom is considered. From 8c3f5f99f37697f7781f4abf632916f009064289 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 13 Aug 2024 21:01:20 +0100 Subject: [PATCH 005/280] [ci skip] update NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index f6cdb4b34f807..890e67592cc62 100644 --- a/NEWS +++ b/NEWS @@ -54,6 +54,10 @@ PHP NEWS (zend_hash_num_elements() Zend/zend_hash.h)). (nielsdos) . Fixed bug GH-15210 use-after-free on watchpoint allocations. (nielsdos) +- Random: + . Fixed part of bug GH-15381, checking getrandom availability on solaris. + (David Carlier) + - Soap: . Fixed bug #55639 (Digest autentication dont work). (nielsdos) . Fix SoapFault property destruction. (nielsdos) From 0b8fbacd5835357f1b8885ac2692e633a57269d9 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 13 Aug 2024 16:59:43 +0200 Subject: [PATCH 006/280] ext/standard/info.c: Remove unreachable conditional branch --- ext/standard/info.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/standard/info.c b/ext/standard/info.c index 864199d66de10..5e273588cb175 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -680,13 +680,12 @@ PHPAPI zend_string *php_get_uname(char mode) } else if (mode == 'v') { char *winver = php_get_windows_name(); dwBuild = (DWORD)(HIWORD(dwVersion)); - if (winver == NULL) { - return strpprintf(0, "build %d", dwBuild); - } else { - zend_string *build_with_version = strpprintf(0, "build %d (%s)", dwBuild, winver); - efree(winver); - return build_with_version; - } + + ZEND_ASSERT(winver != NULL); + + zend_string *build_with_version = strpprintf(0, "build %d (%s)", dwBuild, winver); + efree(winver); + return build_with_version; } else if (mode == 'm') { php_get_windows_cpu(tmp_uname, sizeof(tmp_uname)); php_uname = tmp_uname; From 40d88cacc1db11787aa2fde6d0ee4b6064746d94 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 13 Aug 2024 22:58:44 +0200 Subject: [PATCH 007/280] Fix test expectation for "Built by..." (#15383) --- sapi/fpm/tests/main-version.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/fpm/tests/main-version.phpt b/sapi/fpm/tests/main-version.phpt index 40ea45ef01026..5ae83562d070b 100644 --- a/sapi/fpm/tests/main-version.phpt +++ b/sapi/fpm/tests/main-version.phpt @@ -16,6 +16,6 @@ echo "Done\n"; --EXPECTF-- string(%d) "PHP %s (fpm%s (built: %s Copyright (c) The PHP Group -Zend Engine v%s, Copyright (c) Zend Technologies +%AZend Engine v%s, Copyright (c) Zend Technologies " Done From 6f44a0d7fe3abb3cb890aeae7d03398cc8059121 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 01:17:57 +0200 Subject: [PATCH 008/280] Autotools: Use AS_* macros in embed SAPI (#15387) --- sapi/embed/config.m4 | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index ef9956763d3a4..86856124f2327 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -8,29 +8,27 @@ PHP_ARG_ENABLE([embed],, AC_MSG_CHECKING([for embedded SAPI library support]) if test "$PHP_EMBED" != "no"; then - case "$PHP_EMBED" in - yes|shared) + AS_CASE([$PHP_EMBED], + [yes|shared], [ LIBPHP_CFLAGS="-shared" PHP_EMBED_TYPE=shared INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0755 $SAPI_SHARED \$(INSTALL_ROOT)\$(orig_libdir)" - ;; - static) + ], + [static], [ LIBPHP_CFLAGS="-static" PHP_EMBED_TYPE=static INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0644 $SAPI_STATIC \$(INSTALL_ROOT)\$(orig_libdir)" - ;; - *) - PHP_EMBED_TYPE=no - ;; - esac - if test "$PHP_EMBED_TYPE" != "no"; then + ], + [PHP_EMBED_TYPE=no]) + + AS_VAR_IF([PHP_EMBED_TYPE], [no],, [ PHP_SUBST([LIBPHP_CFLAGS]) PHP_SELECT_SAPI([embed], [$PHP_EMBED_TYPE], [php_embed.c], [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_INSTALL_HEADERS([sapi/embed], [php_embed.h]) - fi + ]) AC_MSG_RESULT([$PHP_EMBED_TYPE]) AC_SUBST([PHP_EMBED_TYPE]) else From b56f81cddcb2c0642bbc6c4a8de5731dd3956995 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 01:18:28 +0200 Subject: [PATCH 009/280] Add configure phase dependencies to mysqlnd extension (#15380) The hash extension is required in mysqlnd extension for using sha functions when extended SSL is enabled (MYSQLND_HAVE_SSL). --- ext/mysqlnd/config.w32 | 1 + ext/mysqlnd/config9.m4 | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index fbe122ab5d36a..9fb58ed50ddf7 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -38,6 +38,7 @@ if (PHP_MYSQLND != "no") { AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "Define to 1 if mysqlnd core SSL is enabled."); if (CHECK_LIB("crypt32.lib", "mysqlnd")) { AC_DEFINE("MYSQLND_HAVE_SSL", 1, "Define to 1 if mysqlnd extended SSL is enabled through OpenSSL."); + ADD_EXTENSION_DEP('mysqlnd', 'hash'); } } PHP_INSTALL_HEADERS("", "ext/mysqlnd"); diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index af242f46d7e2f..1b1d576d440c8 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -36,11 +36,6 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then AC_DEFINE([MYSQLND_SSL_SUPPORTED], [1], [Define to 1 if mysqlnd core SSL is enabled.]) - AS_VAR_IF([PHP_MYSQLND_SSL], [no],, - [PHP_SETUP_OPENSSL([MYSQLND_SHARED_LIBADD], - [AC_DEFINE([MYSQLND_HAVE_SSL], [1], - [Define to 1 if mysqlnd extended SSL is enabled through OpenSSL.])])]) - PHP_NEW_EXTENSION([mysqlnd], m4_normalize([ mysqlnd_alloc.c mysqlnd_auth.c @@ -68,6 +63,13 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + AS_VAR_IF([PHP_MYSQLND_SSL], [no],, + [PHP_SETUP_OPENSSL([MYSQLND_SHARED_LIBADD], [ + AC_DEFINE([MYSQLND_HAVE_SSL], [1], + [Define to 1 if mysqlnd extended SSL is enabled through OpenSSL.]) + PHP_ADD_EXTENSION_DEP(mysqlnd, hash) + ])]) + PHP_INSTALL_HEADERS([ext/mysqlnd/]) PHP_SUBST([MYSQLND_SHARED_LIBADD]) fi From 65a101f3a70656690c8565872f76816737a21364 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 13 Jun 2024 15:48:05 +0200 Subject: [PATCH 010/280] Disable LSAN for crashing SOAP tests (GH-14562) --- ext/soap/tests/bugs/bug27722.phpt | 2 ++ ext/soap/tests/bugs/bug27742.phpt | 2 ++ ext/soap/tests/server011.phpt | 2 ++ ext/soap/tests/server012.phpt | 2 ++ 4 files changed, 8 insertions(+) diff --git a/ext/soap/tests/bugs/bug27722.phpt b/ext/soap/tests/bugs/bug27722.phpt index 3315b71401840..a38fa75fe568a 100644 --- a/ext/soap/tests/bugs/bug27722.phpt +++ b/ext/soap/tests/bugs/bug27722.phpt @@ -6,6 +6,8 @@ soap wsdl --INI-- soap.wsdl_cache_enabled=0 +--ENV-- +LSAN_OPTIONS=detect_leaks=0 --FILE-- Date: Wed, 14 Aug 2024 12:35:47 +0100 Subject: [PATCH 011/280] Replace uses of php_dirname() with zend_dirname() (#15393) This removes some needs to include the php_string.h header --- ext/spl/spl_directory.c | 4 ++-- ext/standard/link.c | 5 +++-- ext/xmlwriter/php_xmlwriter.c | 3 +-- ext/zip/php_zip.c | 2 +- sapi/cli/php_cli_server.c | 1 - 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 15273cb6c46a4..989f84f1fdd1c 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -23,7 +23,7 @@ #include "ext/standard/php_filestat.h" #include "ext/standard/flock_compat.h" #include "ext/standard/scanf.h" -#include "ext/standard/php_string.h" +#include "ext/standard/php_string.h" /* For php_basename() */ #include "zend_attributes.h" #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -1362,7 +1362,7 @@ PHP_METHOD(SplFileInfo, getPathInfo) path = spl_filesystem_object_get_pathname(intern); if (path && ZSTR_LEN(path)) { zend_string *dpath = zend_string_init(ZSTR_VAL(path), ZSTR_LEN(path), 0); - ZSTR_LEN(dpath) = php_dirname(ZSTR_VAL(dpath), ZSTR_LEN(path)); + ZSTR_LEN(dpath) = zend_dirname(ZSTR_VAL(dpath), ZSTR_LEN(path)); spl_filesystem_object_create_info(dpath, ce, return_value); zend_string_release(dpath); } diff --git a/ext/standard/link.c b/ext/standard/link.c index 0529006d4667c..df2831b878462 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -99,8 +99,9 @@ PHP_FUNCTION(linkinfo) Z_PARAM_PATH(link, link_len) ZEND_PARSE_PARAMETERS_END(); + // TODO Check for empty string dirname = estrndup(link, link_len); - php_dirname(dirname, link_len); + zend_dirname(dirname, link_len); if (php_check_open_basedir(dirname)) { efree(dirname); @@ -141,7 +142,7 @@ PHP_FUNCTION(symlink) } memcpy(dirname, source_p, sizeof(source_p)); - len = php_dirname(dirname, strlen(dirname)); + len = zend_dirname(dirname, strlen(dirname)); if (!expand_filepath_ex(topath, dest_p, dirname, len)) { php_error_docref(NULL, E_WARNING, "No such file or directory"); diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index bbb4b94814a48..6724f4fbfbffb 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -24,7 +24,6 @@ #include "ext/standard/info.h" #include "php_xmlwriter.h" #include "php_xmlwriter_arginfo.h" -#include "ext/standard/php_string.h" /* For php_dirname() */ static zend_class_entry *xmlwriter_class_entry_ce; @@ -158,7 +157,7 @@ static char *_xmlwriter_get_valid_file_path(char *source, char *resolved_path, i } memcpy(file_dirname, source, strlen(source)); - dir_len = php_dirname(file_dirname, strlen(source)); + dir_len = zend_dirname(file_dirname, strlen(source)); if (dir_len > 0) { zend_stat_t buf = {0}; diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 5d331c2fa4b82..342d6aabe7240 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -171,7 +171,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, const char *file, s is_dir_only = 1; } else { memcpy(file_dirname, path_cleaned, path_cleaned_len); - dir_len = php_dirname(file_dirname, path_cleaned_len); + dir_len = zend_dirname(file_dirname, path_cleaned_len); if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) { len = spprintf(&file_dirname_fullpath, 0, "%s", dest); diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index bd030c2010349..a720ce32e356c 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -95,7 +95,6 @@ #include "zend_smart_str.h" #include "ext/standard/html.h" #include "ext/standard/url.h" /* for php_raw_url_decode() */ -#include "ext/standard/php_string.h" /* for php_dirname() */ #include "ext/date/php_date.h" /* for php_format_date() */ #include "php_network.h" From a79c70f5748743b1e22002a8ed119b9eca7557b5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 14 Aug 2024 12:44:12 +0100 Subject: [PATCH 012/280] [RFC] Convert exit (and die) from language constructs to functions (#13483) RFC: https://wiki.php.net/rfc/exit-as-function --- Zend/Optimizer/block_pass.c | 4 +- Zend/Optimizer/pass1.c | 1 - Zend/Optimizer/pass3.c | 3 +- Zend/Optimizer/zend_call_graph.c | 4 - Zend/Optimizer/zend_cfg.c | 2 - Zend/tests/arginfo_zpp_mismatch.inc | 3 + Zend/tests/die_string_cast_exception.phpt | 13 - .../exit/ast_print_assert_die_const.phpt | 16 + .../exit/ast_print_assert_die_function.phpt | 16 + .../exit/ast_print_assert_exit_const.phpt | 16 + .../exit/ast_print_assert_exit_function.phpt | 16 + .../exit/define_class_members_exit_die.phpt | 37 + Zend/tests/exit/define_die_constant.phpt | 12 + .../exit/define_die_constant_namespace.phpt | 14 + Zend/tests/exit/define_die_function.phpt | 10 + .../exit/define_die_function_namespace.phpt | 14 + Zend/tests/exit/define_exit_constant.phpt | 12 + .../exit/define_exit_constant_namespace.phpt | 14 + Zend/tests/exit/define_exit_function.phpt | 10 + .../exit/define_exit_function_namespace.phpt | 12 + Zend/tests/exit/define_goto_label_die.phpt | 14 + .../exit/define_goto_label_die_with_jump.phpt | 14 + Zend/tests/exit/define_goto_label_exit.phpt | 14 + .../define_goto_label_exit_with_jump.phpt | 14 + .../tests/exit/die_string_cast_exception.phpt | 14 + Zend/tests/exit/disabling_die.phpt | 12 + Zend/tests/exit/disabling_exit.phpt | 12 + Zend/tests/exit/exit_as_function.phpt | 42 + Zend/tests/exit/exit_statements.phpt | 46 + .../exit/exit_string_with_buffer_output.phpt | 23 + Zend/tests/exit/exit_values.phpt | 183 ++ Zend/zend_API.c | 7 + Zend/zend_builtin_functions.c | 27 + Zend/zend_builtin_functions.stub.php | 5 + Zend/zend_builtin_functions_arginfo.h | 11 +- Zend/zend_compile.c | 25 - Zend/zend_language_parser.y | 13 +- Zend/zend_string.h | 1 + Zend/zend_vm_def.h | 32 - Zend/zend_vm_execute.h | 429 ++-- Zend/zend_vm_handlers.h | 1935 ++++++++--------- Zend/zend_vm_opcodes.c | 2 +- Zend/zend_vm_opcodes.h | 1 - build/gen_stub.php | 11 +- ext/opcache/jit/zend_jit.c | 2 - ext/opcache/jit/zend_jit_ir.c | 3 +- ext/opcache/jit/zend_jit_trace.c | 1 - ext/opcache/tests/jit/ignored_opcodes.phpt | 7 +- .../tests/array/array_filter_variation9.phpt | 6 +- .../tests/array/array_map_variation16.phpt | 44 +- sapi/phpdbg/phpdbg_prompt.c | 2 - 51 files changed, 1839 insertions(+), 1342 deletions(-) delete mode 100644 Zend/tests/die_string_cast_exception.phpt create mode 100644 Zend/tests/exit/ast_print_assert_die_const.phpt create mode 100644 Zend/tests/exit/ast_print_assert_die_function.phpt create mode 100644 Zend/tests/exit/ast_print_assert_exit_const.phpt create mode 100644 Zend/tests/exit/ast_print_assert_exit_function.phpt create mode 100644 Zend/tests/exit/define_class_members_exit_die.phpt create mode 100644 Zend/tests/exit/define_die_constant.phpt create mode 100644 Zend/tests/exit/define_die_constant_namespace.phpt create mode 100644 Zend/tests/exit/define_die_function.phpt create mode 100644 Zend/tests/exit/define_die_function_namespace.phpt create mode 100644 Zend/tests/exit/define_exit_constant.phpt create mode 100644 Zend/tests/exit/define_exit_constant_namespace.phpt create mode 100644 Zend/tests/exit/define_exit_function.phpt create mode 100644 Zend/tests/exit/define_exit_function_namespace.phpt create mode 100644 Zend/tests/exit/define_goto_label_die.phpt create mode 100644 Zend/tests/exit/define_goto_label_die_with_jump.phpt create mode 100644 Zend/tests/exit/define_goto_label_exit.phpt create mode 100644 Zend/tests/exit/define_goto_label_exit_with_jump.phpt create mode 100644 Zend/tests/exit/die_string_cast_exception.phpt create mode 100644 Zend/tests/exit/disabling_die.phpt create mode 100644 Zend/tests/exit/disabling_exit.phpt create mode 100644 Zend/tests/exit/exit_as_function.phpt create mode 100644 Zend/tests/exit/exit_statements.phpt create mode 100644 Zend/tests/exit/exit_string_with_buffer_output.phpt create mode 100644 Zend/tests/exit/exit_values.phpt diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index cd6dce6a5c10a..6fcbd04f12af5 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -868,7 +868,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array break; case ZEND_RETURN: - case ZEND_EXIT: if (opline->op1_type == IS_TMP_VAR) { src = VAR_SOURCE(opline->op1); if (src && src->opcode == ZEND_QM_ASSIGN) { @@ -1221,8 +1220,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr target = op_array->opcodes + target_block->start; if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || - target->opcode == ZEND_GENERATOR_RETURN || - target->opcode == ZEND_EXIT) && + target->opcode == ZEND_GENERATOR_RETURN) && !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { /* JMP L, L: RETURN to immediate RETURN */ *last_op = *target; diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 7543c15341c97..7c9f1c99a2820 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -331,7 +331,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_THROW: case ZEND_MATCH_ERROR: case ZEND_CATCH: diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 93e431fece440..2cbd0e3406521 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -88,8 +88,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) MAKE_NOP(opline); } else if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || - target->opcode == ZEND_GENERATOR_RETURN || - target->opcode == ZEND_EXIT) && + target->opcode == ZEND_GENERATOR_RETURN) && !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { /* JMP L, L: RETURN to immediate RETURN */ *opline = *target; diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index fd63f587336a3..abd5dac533137 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -162,10 +162,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 call_info->send_unpack = 1; } break; - case ZEND_EXIT: - /* In this case the DO_CALL opcode may have been dropped - * and caller_call_opline will be NULL. */ - break; } opline++; } diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 2a0fe369cfc6a..a05cf6fb79235 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -302,7 +302,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, } break; case ZEND_MATCH_ERROR: - case ZEND_EXIT: case ZEND_THROW: /* Don't treat THROW as terminator if it's used in expression context, * as we may lose live ranges when eliminating unreachable code. */ @@ -506,7 +505,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_THROW: case ZEND_MATCH_ERROR: case ZEND_VERIFY_NEVER_TYPE: diff --git a/Zend/tests/arginfo_zpp_mismatch.inc b/Zend/tests/arginfo_zpp_mismatch.inc index 023bfefa5d501..5b2711fdb6303 100644 --- a/Zend/tests/arginfo_zpp_mismatch.inc +++ b/Zend/tests/arginfo_zpp_mismatch.inc @@ -6,6 +6,9 @@ function skipFunction($function): bool { || $function === 'readline' || $function === 'readline_read_history' || $function === 'readline_write_history' + /* terminates script */ + || $function === 'exit' + || $function === 'die' /* intentionally violate invariants */ || $function === 'zend_create_unterminated_string' || $function === 'zend_test_array_return' diff --git a/Zend/tests/die_string_cast_exception.phpt b/Zend/tests/die_string_cast_exception.phpt deleted file mode 100644 index 9893c3389f970..0000000000000 --- a/Zend/tests/die_string_cast_exception.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Bug #79777: String cast exception during die should be handled gracefully ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught Error: Object of class stdClass could not be converted to string in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d diff --git a/Zend/tests/exit/ast_print_assert_die_const.phpt b/Zend/tests/exit/ast_print_assert_die_const.phpt new file mode 100644 index 0000000000000..7c576666abe4b --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_die_const.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of die "constant" via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_die_function.phpt b/Zend/tests/exit/ast_print_assert_die_function.phpt new file mode 100644 index 0000000000000..c83aff6692738 --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_die_function.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of die function via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_exit_const.phpt b/Zend/tests/exit/ast_print_assert_exit_const.phpt new file mode 100644 index 0000000000000..2f52ee37a42da --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_exit_const.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of exit "constant" via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_exit_function.phpt b/Zend/tests/exit/ast_print_assert_exit_function.phpt new file mode 100644 index 0000000000000..e5fd5635faec0 --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_exit_function.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of exit function via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/define_class_members_exit_die.phpt b/Zend/tests/exit/define_class_members_exit_die.phpt new file mode 100644 index 0000000000000..0a3816dc0d065 --- /dev/null +++ b/Zend/tests/exit/define_class_members_exit_die.phpt @@ -0,0 +1,37 @@ +--TEST-- +Can define die and exit as class methods, constants and property +--FILE-- +exit); +var_dump($o->die); +var_dump($o->exit()); +var_dump($o->die()); + +?> +--EXPECT-- +int(5) +int(10) +NULL +NULL +int(20) +int(15) diff --git a/Zend/tests/exit/define_die_constant.phpt b/Zend/tests/exit/define_die_constant.phpt new file mode 100644 index 0000000000000..393904d9356dd --- /dev/null +++ b/Zend/tests/exit/define_die_constant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define die constant +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_die_constant_namespace.phpt b/Zend/tests/exit/define_die_constant_namespace.phpt new file mode 100644 index 0000000000000..b68038ba10fb7 --- /dev/null +++ b/Zend/tests/exit/define_die_constant_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define die constant in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_die_function.phpt b/Zend/tests/exit/define_die_function.phpt new file mode 100644 index 0000000000000..4ea41d6ced5bd --- /dev/null +++ b/Zend/tests/exit/define_die_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Attempting to define die() function +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_die_function_namespace.phpt b/Zend/tests/exit/define_die_function_namespace.phpt new file mode 100644 index 0000000000000..fece46cb7acd6 --- /dev/null +++ b/Zend/tests/exit/define_die_function_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define die() function in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_exit_constant.phpt b/Zend/tests/exit/define_exit_constant.phpt new file mode 100644 index 0000000000000..33cd073401223 --- /dev/null +++ b/Zend/tests/exit/define_exit_constant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define exit constant +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_exit_constant_namespace.phpt b/Zend/tests/exit/define_exit_constant_namespace.phpt new file mode 100644 index 0000000000000..8d0097bb9da3c --- /dev/null +++ b/Zend/tests/exit/define_exit_constant_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define exit constant in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_exit_function.phpt b/Zend/tests/exit/define_exit_function.phpt new file mode 100644 index 0000000000000..4c406ef0d8905 --- /dev/null +++ b/Zend/tests/exit/define_exit_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Attempting to define exit() function +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_exit_function_namespace.phpt b/Zend/tests/exit/define_exit_function_namespace.phpt new file mode 100644 index 0000000000000..9ea785b0e53ba --- /dev/null +++ b/Zend/tests/exit/define_exit_function_namespace.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define exit() function in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_die.phpt b/Zend/tests/exit/define_goto_label_die.phpt new file mode 100644 index 0000000000000..b94ee13fa0abe --- /dev/null +++ b/Zend/tests/exit/define_goto_label_die.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called die +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token ":" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_die_with_jump.phpt b/Zend/tests/exit/define_goto_label_die_with_jump.phpt new file mode 100644 index 0000000000000..fc755d52a5794 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_die_with_jump.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called die and jump to it +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_exit.phpt b/Zend/tests/exit/define_goto_label_exit.phpt new file mode 100644 index 0000000000000..a72b6bac2d2a4 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_exit.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called exit +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token ":" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_exit_with_jump.phpt b/Zend/tests/exit/define_goto_label_exit_with_jump.phpt new file mode 100644 index 0000000000000..a810f2c44c2d8 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_exit_with_jump.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called exit and jump to it +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/die_string_cast_exception.phpt b/Zend/tests/exit/die_string_cast_exception.phpt new file mode 100644 index 0000000000000..711b0de6322ce --- /dev/null +++ b/Zend/tests/exit/die_string_cast_exception.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #79777: String cast exception during die should be handled gracefully +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +exit(): Argument #1 ($code) must be of type string|int, stdClass given diff --git a/Zend/tests/exit/disabling_die.phpt b/Zend/tests/exit/disabling_die.phpt new file mode 100644 index 0000000000000..8d84067a9abda --- /dev/null +++ b/Zend/tests/exit/disabling_die.phpt @@ -0,0 +1,12 @@ +--TEST-- +Using disable_functions INI to remove die +--INI-- +disable_functions=die +--FILE-- + +--EXPECT-- +Warning: Cannot disable function die() in Unknown on line 0 diff --git a/Zend/tests/exit/disabling_exit.phpt b/Zend/tests/exit/disabling_exit.phpt new file mode 100644 index 0000000000000..a6cf277d38f72 --- /dev/null +++ b/Zend/tests/exit/disabling_exit.phpt @@ -0,0 +1,12 @@ +--TEST-- +Using disable_functions INI to remove exit +--INI-- +disable_functions=exit +--FILE-- + +--EXPECT-- +Warning: Cannot disable function exit() in Unknown on line 0 diff --git a/Zend/tests/exit/exit_as_function.phpt b/Zend/tests/exit/exit_as_function.phpt new file mode 100644 index 0000000000000..2953fadfa6d47 --- /dev/null +++ b/Zend/tests/exit/exit_as_function.phpt @@ -0,0 +1,42 @@ +--TEST-- +exit() as function +--FILE-- + +--EXPECT-- +string(4) "exit" +string(3) "die" +object(Closure)#1 (2) { + ["function"]=> + string(4) "exit" + ["parameter"]=> + array(1) { + ["$code"]=> + string(10) "" + } +} +object(Closure)#2 (2) { + ["function"]=> + string(4) "exit" + ["parameter"]=> + array(1) { + ["$code"]=> + string(10) "" + } +} diff --git a/Zend/tests/exit/exit_statements.phpt b/Zend/tests/exit/exit_statements.phpt new file mode 100644 index 0000000000000..6b3147156709f --- /dev/null +++ b/Zend/tests/exit/exit_statements.phpt @@ -0,0 +1,46 @@ +--TEST-- +Using exit/die as a statement/constant +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' ' . escapeshellarg(FILE_PATH); + +foreach (['exit', 'die'] as $value) { + echo 'Using ', $value, ' as value:', PHP_EOL; + $output = []; + $content = str_replace('FUNCTION', $value, FILE_CONTENT); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; +} + +?> +--CLEAN-- + +--EXPECT-- +Using exit as value: +Exit status is: 0 +Output is: +Before exit +Using die as value: +Exit status is: 0 +Output is: +Before die diff --git a/Zend/tests/exit/exit_string_with_buffer_output.phpt b/Zend/tests/exit/exit_string_with_buffer_output.phpt new file mode 100644 index 0000000000000..a9ed44893cebc --- /dev/null +++ b/Zend/tests/exit/exit_string_with_buffer_output.phpt @@ -0,0 +1,23 @@ +--TEST-- +Throwing output buffer with exit("Message") +--FILE-- +getMessage(), PHP_EOL; +} +echo "After?\n"; + +?> +--EXPECT-- +Handler: Hello world! +Hello world! +Exception: test +After? diff --git a/Zend/tests/exit/exit_values.phpt b/Zend/tests/exit/exit_values.phpt new file mode 100644 index 0000000000000..e081193b94cd2 --- /dev/null +++ b/Zend/tests/exit/exit_values.phpt @@ -0,0 +1,183 @@ +--TEST-- +exit(false); +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' ' . escapeshellarg(FILE_PATH); + +foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) { + foreach ($values as $value) { + echo 'Using ', zend_test_var_export($value), ' as value:', PHP_EOL; + $output = []; + $content = str_replace('VALUE', zend_test_var_export($value), $code); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; + } + + echo 'As a statement:', PHP_EOL; + $output = []; + $content = str_replace('(VALUE)', '', $code); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; +} + +?> +--CLEAN-- + +--EXPECTF-- +Using NULL as value: +Exit status is: 0 +Output is: +Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d +Using false as value: +Exit status is: 0 +Output is: + +Using true as value: +Exit status is: 1 +Output is: + +Using 0 as value: +Exit status is: 0 +Output is: + +Using 1 as value: +Exit status is: 1 +Output is: + +Using 20 as value: +Exit status is: 20 +Output is: + +Using 10.0 as value: +Exit status is: 10 +Output is: + +Using 15.5 as value: +Exit status is: 15 +Output is: +Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d +Using 'Hello world' as value: +Exit status is: 0 +Output is: +Hello world +Using [] as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, array given +Using STDERR as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given +Using new stdClass() as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +As a statement: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +Using NULL as value: +Exit status is: 0 +Output is: +Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d +Using false as value: +Exit status is: 0 +Output is: + +Using true as value: +Exit status is: 1 +Output is: + +Using 0 as value: +Exit status is: 0 +Output is: + +Using 1 as value: +Exit status is: 1 +Output is: + +Using 20 as value: +Exit status is: 20 +Output is: + +Using 10.0 as value: +Exit status is: 10 +Output is: + +Using 15.5 as value: +Exit status is: 15 +Output is: +Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d +Using 'Hello world' as value: +Exit status is: 0 +Output is: +Hello world +Using [] as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, array given +Using STDERR as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given +Using new stdClass() as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +As a statement: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given diff --git a/Zend/zend_API.c b/Zend/zend_API.c index daa98a89253d8..229af38c2a8c4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3605,6 +3605,13 @@ ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t static void zend_disable_function(const char *function_name, size_t function_name_length) { + if (UNEXPECTED( + (function_name_length == strlen("exit") && !memcmp(function_name, "exit", strlen("exit"))) + || (function_name_length == strlen("die") && !memcmp(function_name, "die", strlen("die"))) + )) { + zend_error(E_WARNING, "Cannot disable function %s()", function_name); + return; + } zend_hash_str_del(CG(function_table), function_name, function_name_length); } diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 23bc5f7a3cd57..0335d2498acca 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -69,6 +69,33 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ } /* }}} */ +ZEND_FUNCTION(exit) +{ + zend_string *str = NULL; + zend_long code = 0; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_LONG(str, code) + ZEND_PARSE_PARAMETERS_END(); + + if (str) { + size_t len = ZSTR_LEN(str); + if (len != 0) { + /* An exception might be emitted by an output handler */ + zend_write(ZSTR_VAL(str), len); + if (EG(exception)) { + RETURN_THROWS(); + } + } + } else { + EG(exit_status) = code; + } + + ZEND_ASSERT(!EG(exception)); + zend_throw_unwind_exit(); +} + /* {{{ Get the version of the Zend Engine */ ZEND_FUNCTION(zend_version) { diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index b92b80b917c54..ddf12e117966f 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -7,6 +7,11 @@ class stdClass { } +function exit(string|int $code = 0): never {} + +/** @alias exit */ +function die(string|int $code = 0): never {} + /** @refcount 1 */ function zend_version(): string {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 20e6f0f9b48a3..db9f325c63f00 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c3bec3b17079456ef17e5c992995dcfbe62c6fe0 */ + * Stub hash: a6d7e59d6b7875ddc28ce828ae240c7dfd852023 */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) + ZEND_ARG_TYPE_MASK(0, code, MAY_BE_STRING|MAY_BE_LONG, "0") +ZEND_END_ARG_INFO() + +#define arginfo_die arginfo_exit ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -232,6 +238,7 @@ static const zend_frameless_function_info frameless_function_infos_class_exists[ { 0 }, }; +ZEND_FUNCTION(exit); ZEND_FUNCTION(zend_version); ZEND_FUNCTION(func_num_args); ZEND_FUNCTION(func_get_arg); @@ -292,6 +299,8 @@ ZEND_FUNCTION(gc_disable); ZEND_FUNCTION(gc_status); static const zend_function_entry ext_functions[] = { + ZEND_FE(exit, arginfo_exit) + ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL) ZEND_FE(zend_version, arginfo_zend_version) ZEND_FE(func_num_args, arginfo_func_num_args) ZEND_FE(func_get_arg, arginfo_func_get_arg) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index cfd97e59b7ebd..9e736ea1b37ad 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -10376,27 +10376,6 @@ static void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *expr_ast = ast->child[0]; - znode expr_node; - - if (expr_ast) { - zend_compile_expr(&expr_node, expr_ast); - } else { - expr_node.op_type = IS_UNUSED; - } - - zend_op *opline = zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL); - if (result) { - /* Mark this as an "expression throw" for opcache. */ - opline->extended_value = ZEND_THROW_IS_EXPR; - result->op_type = IS_CONST; - ZVAL_TRUE(&result->u.constant); - } -} -/* }}} */ - static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *value_ast = ast->child[0]; @@ -11366,7 +11345,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_halt_compiler(ast); break; case ZEND_AST_THROW: - case ZEND_AST_EXIT: zend_compile_expr(NULL, ast); break; default: @@ -11469,9 +11447,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_PRINT: zend_compile_print(result, ast); return; - case ZEND_AST_EXIT: - zend_compile_exit(result, ast); - return; case ZEND_AST_YIELD: zend_compile_yield(result, ast); return; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f7822caa88dc3..5423d40185766 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -258,7 +258,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type absolute_trait_method_reference trait_method_reference property echo_expr %type new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable %type internal_functions_in_yacc -%type exit_expr scalar backticks_expr lexical_var function_call member_name property_name +%type scalar backticks_expr lexical_var function_call member_name property_name %type variable_class_name dereferenceable_scalar constant class_constant %type fully_dereferenceable array_object_dereferenceable %type callable_expr callable_variable static_member new_variable @@ -1304,7 +1304,11 @@ expr: | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); } | T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); } | T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); } - | T_EXIT exit_expr { $$ = zend_ast_create(ZEND_AST_EXIT, $2); } + | T_EXIT ctor_arguments { + zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_EXIT)); + name->attr = ZEND_NAME_FQ; + $$ = zend_ast_create(ZEND_AST_CALL, name, $2); + } | '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); } | scalar { $$ = $1; } | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); } @@ -1407,11 +1411,6 @@ class_name_reference: | '(' expr ')' { $$ = $2; } ; -exit_expr: - %empty { $$ = NULL; } - | '(' optional_expr ')' { $$ = $2; } -; - backticks_expr: %empty { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index b62875a6ec1ce..ad6c5e1ee38bf 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -572,6 +572,7 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_ARGS, "args") \ _(ZEND_STR_UNKNOWN, "unknown") \ _(ZEND_STR_UNKNOWN_CAPITALIZED, "Unknown") \ + _(ZEND_STR_EXIT, "exit") \ _(ZEND_STR_EVAL, "eval") \ _(ZEND_STR_INCLUDE, "include") \ _(ZEND_STR_REQUIRE, "require") \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c99cc9c1a2f65..55fdb7d46582b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7610,38 +7610,6 @@ ZEND_VM_C_LABEL(array_key_exists_array): ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ -ZEND_VM_COLD_HANDLER(79, ZEND_EXIT, ANY, ANY) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (OP1_TYPE != IS_UNUSED) { - zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_zval(ptr, 0); - } - } while (0); - FREE_OP1(); - } - - if (!EG(exception)) { - zend_throw_unwind_exit(); - } - HANDLE_EXCEPTION(); -} - ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 75499f028e2cd..16455b6e0cd58 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3013,37 +3013,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (opline->op1_type != IS_UNUSED) { - zval *ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_zval(ptr, 0); - } - } while (0); - FREE_OP(opline->op1_type, opline->op1.var); - } - - if (!EG(exception)) { - zend_throw_unwind_exit(); - } - HANDLE_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -7930,7 +7899,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10307,7 +10275,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12788,7 +12755,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -16950,7 +16916,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -18417,7 +18382,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -19824,7 +19788,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -45235,7 +45198,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -48963,7 +48925,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -54527,7 +54488,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -56322,7 +56282,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FE_RESET_R_SPEC_CV_LABEL, (void*)&&ZEND_FE_FETCH_R_SPEC_VAR_LABEL, - (void*)&&ZEND_EXIT_SPEC_LABEL, (void*)&&ZEND_FETCH_R_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, @@ -58572,11 +58531,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) HYBRID_BREAK(); - HYBRID_CASE(ZEND_EXIT_SPEC): - VM_TRACE(ZEND_EXIT_SPEC) - ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_EXIT_SPEC) - HYBRID_BREAK(); HYBRID_CASE(ZEND_BEGIN_SILENCE_SPEC): VM_TRACE(ZEND_BEGIN_SILENCE_SPEC) ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -65515,7 +65469,6 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_FE_RESET_R_SPEC_CV_HANDLER, ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_EXIT_SPEC_HANDLER, ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, @@ -67460,7 +67413,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3487, + 3486, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -67494,100 +67447,101 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 1590, - 1591 | SPEC_RULE_OP1, - 1596 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1621 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1646 | SPEC_RULE_OP1, - 1651 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1676 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1701 | SPEC_RULE_OP1, - 1706 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1731 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1756 | SPEC_RULE_OP1, - 1761 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1786 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1811 | SPEC_RULE_OP1, - 1816 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1841 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1866 | SPEC_RULE_OP1, - 1871 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1896 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1921 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1946, - 1947 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 3486, + 1590 | SPEC_RULE_OP1, + 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1645 | SPEC_RULE_OP1, + 1650 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1675 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1700 | SPEC_RULE_OP1, + 1705 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1730 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1755 | SPEC_RULE_OP1, + 1760 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1785 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1810 | SPEC_RULE_OP1, + 1815 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1840 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1865 | SPEC_RULE_OP1, + 1870 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1895 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1920 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1945, + 1946 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1956, 1957, 1958, 1959, 1960, - 1961, - 1962 | SPEC_RULE_OP2, - 1967, - 1968 | SPEC_RULE_OP1, - 1973 | SPEC_RULE_OP2, - 1978 | SPEC_RULE_OP1, - 1983 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1993 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2018 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2043 | SPEC_RULE_OP1, - 2048 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2073 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 2123 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2148 | SPEC_RULE_OP2, - 2153, - 2154 | SPEC_RULE_OP1, - 2159 | SPEC_RULE_OP1, - 2164, - 2165 | SPEC_RULE_OP1, - 2170 | SPEC_RULE_OP1, - 2175 | SPEC_RULE_OP1, + 1961 | SPEC_RULE_OP2, + 1966, + 1967 | SPEC_RULE_OP1, + 1972 | SPEC_RULE_OP2, + 1977 | SPEC_RULE_OP1, + 1982 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1992 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2017 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2042 | SPEC_RULE_OP1, + 2047 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 2122 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2147 | SPEC_RULE_OP2, + 2152, + 2153 | SPEC_RULE_OP1, + 2158 | SPEC_RULE_OP1, + 2163, + 2164 | SPEC_RULE_OP1, + 2169 | SPEC_RULE_OP1, + 2174 | SPEC_RULE_OP1, + 2179, 2180, - 2181, - 2182 | SPEC_RULE_OP2, - 2187 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2191 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2195 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2249 | SPEC_RULE_OP1, - 2254, - 2255 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2280, - 2281 | SPEC_RULE_OP1, + 2181 | SPEC_RULE_OP2, + 2186 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2190 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2248 | SPEC_RULE_OP1, + 2253, + 2254 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2279, + 2280 | SPEC_RULE_OP1, + 2285, 2286, 2287, 2288, 2289, 2290, 2291, - 2292, - 2293 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2292 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2317, 2318, 2319, - 2320, - 2321 | SPEC_RULE_OP1, - 2326, - 2327 | SPEC_RULE_ISSET, - 2329 | SPEC_RULE_OP2, - 2334, - 2335 | SPEC_RULE_OP1, - 2340 | SPEC_RULE_OBSERVER, - 2342, - 2343 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2368 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2320 | SPEC_RULE_OP1, + 2325, + 2326 | SPEC_RULE_ISSET, + 2328 | SPEC_RULE_OP2, + 2333, + 2334 | SPEC_RULE_OP1, + 2339 | SPEC_RULE_OBSERVER, + 2341, + 2342 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2367 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2377, 2378, 2379, 2380, - 2381, - 2382 | SPEC_RULE_OP1, + 2381 | SPEC_RULE_OP1, + 2386, 2387, - 2388, - 2389 | SPEC_RULE_OP1, - 2394 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2419, - 2420 | SPEC_RULE_OP1, + 2388 | SPEC_RULE_OP1, + 2393 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2418, + 2419 | SPEC_RULE_OP1, + 2424, 2425, 2426, 2427, @@ -67595,82 +67549,81 @@ void zend_vm_init(void) 2429, 2430, 2431, - 2432, - 2433 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2432 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2457, 2458, 2459, - 2460, - 2461 | SPEC_RULE_OP2, - 2466, - 2467 | SPEC_RULE_OP1, - 2472 | SPEC_RULE_OP1, - 2477 | SPEC_RULE_OP1, - 2482 | SPEC_RULE_OP1, - 2487 | SPEC_RULE_OP1, - 2492, - 2493 | SPEC_RULE_OP1, - 2498 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2523 | SPEC_RULE_OP1, - 2528 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2553 | SPEC_RULE_OP1, - 2558 | SPEC_RULE_OP1, + 2460 | SPEC_RULE_OP2, + 2465, + 2466 | SPEC_RULE_OP1, + 2471 | SPEC_RULE_OP1, + 2476 | SPEC_RULE_OP1, + 2481 | SPEC_RULE_OP1, + 2486 | SPEC_RULE_OP1, + 2491, + 2492 | SPEC_RULE_OP1, + 2497 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2522 | SPEC_RULE_OP1, + 2527 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2552 | SPEC_RULE_OP1, + 2557 | SPEC_RULE_OP1, + 2562, 2563, 2564, 2565, 2566, - 2567, - 2568 | SPEC_RULE_OBSERVER, - 2570 | SPEC_RULE_OBSERVER, - 2572 | SPEC_RULE_OBSERVER, - 2574 | SPEC_RULE_OBSERVER, + 2567 | SPEC_RULE_OBSERVER, + 2569 | SPEC_RULE_OBSERVER, + 2571 | SPEC_RULE_OBSERVER, + 2573 | SPEC_RULE_OBSERVER, + 2575, 2576, - 2577, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -67843,7 +67796,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2586 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2585 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67851,7 +67804,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2611 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2610 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67859,7 +67812,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2636 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2635 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67870,17 +67823,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2661 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2660 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2686 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2685 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2711 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2710 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -67891,17 +67844,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2736 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2735 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2761 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2760 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2786 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2785 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -67912,14 +67865,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3111 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3110 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -67930,14 +67883,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3116 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -67948,12 +67901,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -67964,12 +67917,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -67977,12 +67930,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3121 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3120 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3196 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3195 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -67990,79 +67943,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3271 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3270 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3346 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3345 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3433 | SPEC_RULE_OP1; + spec = 3432 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3438 | SPEC_RULE_OP1; + spec = 3437 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3443 | SPEC_RULE_OP1; + spec = 3442 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3421 | SPEC_RULE_RETVAL; + spec = 3420 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3423 | SPEC_RULE_RETVAL; + spec = 3422 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3425 | SPEC_RULE_RETVAL; + spec = 3424 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3427 | SPEC_RULE_RETVAL; + spec = 3426 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3429; + spec = 3428; } else if (op1_info == MAY_BE_LONG) { - spec = 3430; + spec = 3429; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3431; + spec = 3430; } else if (op1_info == MAY_BE_LONG) { - spec = 3432; + spec = 3431; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2585; + spec = 2584; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2578; + spec = 2577; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2579; + spec = 2578; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3483; + spec = 3482; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3478 | SPEC_RULE_OP1; + spec = 3477 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3485 | SPEC_RULE_RETVAL; + spec = 3484 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -68070,22 +68023,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3448 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3447 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3484; + spec = 3483; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3473 | SPEC_RULE_OP1; + spec = 3472 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2580 | SPEC_RULE_OP1; + spec = 2579 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 99abc0ffb12de..7f3a3cb5de260 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -751,1124 +751,1123 @@ _(1586, ZEND_FE_RESET_R_SPEC_VAR) \ _(1588, ZEND_FE_RESET_R_SPEC_CV) \ _(1589, ZEND_FE_FETCH_R_SPEC_VAR) \ - _(1590, ZEND_EXIT_SPEC) \ - _(1591, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ + _(1590, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ + _(1591, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ _(1592, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1593, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1595, ZEND_FETCH_R_SPEC_CV_UNUSED) \ - _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ + _(1594, ZEND_FETCH_R_SPEC_CV_UNUSED) \ + _(1595, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ + _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ _(1597, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1598, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1600, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ - _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1599, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ + _(1600, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1602, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1603, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1604, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ + _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1608, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1610, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1616, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(1609, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ + _(1615, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ _(1617, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1618, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1620, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ - _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ + _(1619, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ + _(1620, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ + _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ _(1622, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1623, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1625, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ - _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1624, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ + _(1625, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1627, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1628, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1629, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ + _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1632, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1633, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1635, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(1634, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ + _(1635, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ _(1637, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1638, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1640, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ - _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ + _(1639, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ + _(1640, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ + _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ _(1642, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1643, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1645, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ - _(1646, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ + _(1644, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ + _(1645, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ + _(1646, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ _(1647, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1648, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1650, ZEND_FETCH_W_SPEC_CV_UNUSED) \ - _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ + _(1649, ZEND_FETCH_W_SPEC_CV_UNUSED) \ + _(1660, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ + _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ _(1662, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ - _(1665, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ - _(1671, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ + _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ + _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ + _(1670, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ + _(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ _(1672, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1673, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1674, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ - _(1675, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ - _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ + _(1673, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ + _(1674, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ + _(1685, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ + _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ _(1687, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1688, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1690, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ - _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ + _(1689, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ + _(1690, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ + _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ _(1692, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1693, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1695, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ - _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ + _(1694, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ + _(1695, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ + _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ _(1697, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1698, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1700, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ - _(1701, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ + _(1699, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ + _(1700, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ + _(1701, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ _(1702, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1703, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1705, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ - _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ + _(1704, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ + _(1715, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ + _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ _(1717, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ - _(1720, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ - _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ + _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ + _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ + _(1725, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ + _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ _(1727, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ - _(1730, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ - _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ + _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ + _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ + _(1740, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ + _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ _(1742, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1743, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1745, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ - _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ + _(1744, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ + _(1745, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ + _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ _(1747, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1748, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1750, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ - _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ + _(1749, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ + _(1750, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ + _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ _(1752, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1753, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1755, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ - _(1756, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ + _(1754, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ + _(1755, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ + _(1756, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ _(1757, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1758, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1760, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ - _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ + _(1759, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ + _(1760, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ + _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ _(1762, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1763, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1765, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ - _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1764, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ + _(1765, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1767, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1768, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1769, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ + _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1773, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1775, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(1774, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ + _(1780, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ _(1782, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1783, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1785, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ - _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ + _(1784, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ + _(1785, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ + _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ _(1787, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1788, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1790, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ - _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1789, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ + _(1790, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1792, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1793, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1794, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ + _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1797, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1798, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1800, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(1799, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ + _(1800, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ _(1802, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1803, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1805, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ - _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ + _(1804, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ + _(1805, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ + _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ _(1807, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1808, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1810, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ - _(1811, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1809, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ + _(1810, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ _(1812, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1813, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1815, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ + _(1814, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1815, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ + _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ _(1817, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ - _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ + _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ + _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ + _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ - _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ - _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ + _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ + _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ + _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ + _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(1830, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ - _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ + _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ + _(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ + _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ _(1837, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1840, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ - _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ + _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ + _(1840, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ + _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ _(1842, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1843, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ - _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ + _(1844, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ + _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ + _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1848, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ - _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ + _(1849, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ + _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ + _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1853, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ - _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1854, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ + _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1858, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ - _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ + _(1859, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ + _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ + _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1863, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1865, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ - _(1866, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ + _(1864, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ + _(1865, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ + _(1866, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ _(1867, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1868, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1870, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ - _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ + _(1869, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ + _(1880, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ + _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ _(1882, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1883, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1885, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ - _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ + _(1884, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ + _(1890, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ + _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ _(1892, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1893, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1895, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ - _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ + _(1894, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ + _(1905, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ + _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ _(1907, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1908, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ - _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ + _(1909, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ + _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ + _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1913, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ - _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ + _(1914, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ + _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ + _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1918, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1920, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ - _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ + _(1919, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ + _(1920, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ + _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ _(1922, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1923, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1925, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ - _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1924, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ + _(1925, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1927, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1928, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1929, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1933, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1935, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1934, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1942, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1943, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1945, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1946, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ + _(1944, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1945, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ + _(1946, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ _(1947, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1948, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ - _(1954, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ - _(1957, ZEND_EXT_STMT_SPEC) \ - _(1958, ZEND_EXT_FCALL_BEGIN_SPEC) \ - _(1959, ZEND_EXT_FCALL_END_SPEC) \ - _(1960, ZEND_EXT_NOP_SPEC) \ - _(1961, ZEND_TICKS_SPEC) \ - _(1962, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ - _(1965, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ - _(1967, ZEND_CATCH_SPEC_CONST) \ - _(1968, ZEND_THROW_SPEC_CONST) \ + _(1952, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ + _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ + _(1956, ZEND_EXT_STMT_SPEC) \ + _(1957, ZEND_EXT_FCALL_BEGIN_SPEC) \ + _(1958, ZEND_EXT_FCALL_END_SPEC) \ + _(1959, ZEND_EXT_NOP_SPEC) \ + _(1960, ZEND_TICKS_SPEC) \ + _(1961, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ + _(1964, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ + _(1966, ZEND_CATCH_SPEC_CONST) \ + _(1967, ZEND_THROW_SPEC_CONST) \ + _(1968, ZEND_THROW_SPEC_TMPVAR) \ _(1969, ZEND_THROW_SPEC_TMPVAR) \ - _(1970, ZEND_THROW_SPEC_TMPVAR) \ - _(1972, ZEND_THROW_SPEC_CV) \ - _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(1971, ZEND_THROW_SPEC_CV) \ + _(1972, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ _(1974, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ - _(1977, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ - _(1978, ZEND_CLONE_SPEC_CONST) \ + _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ + _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ + _(1977, ZEND_CLONE_SPEC_CONST) \ + _(1978, ZEND_CLONE_SPEC_TMPVAR) \ _(1979, ZEND_CLONE_SPEC_TMPVAR) \ - _(1980, ZEND_CLONE_SPEC_TMPVAR) \ - _(1981, ZEND_CLONE_SPEC_UNUSED) \ - _(1982, ZEND_CLONE_SPEC_CV) \ - _(1983, ZEND_RETURN_BY_REF_SPEC_CONST) \ - _(1984, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1985, ZEND_RETURN_BY_REF_SPEC_TMP) \ - _(1986, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1987, ZEND_RETURN_BY_REF_SPEC_VAR) \ - _(1988, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1991, ZEND_RETURN_BY_REF_SPEC_CV) \ - _(1992, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ + _(1980, ZEND_CLONE_SPEC_UNUSED) \ + _(1981, ZEND_CLONE_SPEC_CV) \ + _(1982, ZEND_RETURN_BY_REF_SPEC_CONST) \ + _(1983, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1984, ZEND_RETURN_BY_REF_SPEC_TMP) \ + _(1985, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1986, ZEND_RETURN_BY_REF_SPEC_VAR) \ + _(1987, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1990, ZEND_RETURN_BY_REF_SPEC_CV) \ + _(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1992, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ + _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ _(1994, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(1995, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(1997, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ - _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(1996, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ + _(1997, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(1999, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2000, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(2001, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ + _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(2004, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2005, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2007, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2006, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ + _(2007, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ _(2009, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2010, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2012, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ + _(2011, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2012, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ + _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ _(2014, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2015, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2017, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ - _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ + _(2016, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ + _(2017, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ + _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ _(2019, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ - _(2022, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ - _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ + _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ + _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ + _(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ + _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ _(2029, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ - _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ - _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ + _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ + _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ - _(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ + _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ + _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2042, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ + _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ _(2044, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2045, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2047, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ - _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ + _(2046, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ + _(2047, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ + _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ _(2049, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2050, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ - _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2051, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ + _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ + _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2059, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2060, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2062, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(2061, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ + _(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ _(2069, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2070, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2072, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ + _(2071, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ + _(2072, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ _(2073, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2074, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ - _(2080, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ + _(2078, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ + _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ + _(2082, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ _(2083, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2084, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ - _(2090, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ - _(2133, ZEND_SEND_VAR_SPEC_VAR_CONST) \ - _(2136, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ - _(2143, ZEND_SEND_VAR_SPEC_CV_CONST) \ - _(2146, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ - _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ + _(2088, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ + _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ + _(2132, ZEND_SEND_VAR_SPEC_VAR_CONST) \ + _(2135, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ + _(2142, ZEND_SEND_VAR_SPEC_CV_CONST) \ + _(2145, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ + _(2147, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ + _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ _(2149, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2150, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2152, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ - _(2153, ZEND_SEND_ARRAY_SPEC) \ - _(2154, ZEND_SEND_USER_SPEC_CONST) \ - _(2155, ZEND_SEND_USER_SPEC_TMP) \ - _(2156, ZEND_SEND_USER_SPEC_VAR) \ - _(2158, ZEND_SEND_USER_SPEC_CV) \ - _(2159, ZEND_STRLEN_SPEC_CONST) \ + _(2151, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ + _(2152, ZEND_SEND_ARRAY_SPEC) \ + _(2153, ZEND_SEND_USER_SPEC_CONST) \ + _(2154, ZEND_SEND_USER_SPEC_TMP) \ + _(2155, ZEND_SEND_USER_SPEC_VAR) \ + _(2157, ZEND_SEND_USER_SPEC_CV) \ + _(2158, ZEND_STRLEN_SPEC_CONST) \ + _(2159, ZEND_STRLEN_SPEC_TMPVAR) \ _(2160, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2161, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2163, ZEND_STRLEN_SPEC_CV) \ - _(2164, ZEND_DEFINED_SPEC_CONST) \ - _(2165, ZEND_TYPE_CHECK_SPEC_CONST) \ + _(2162, ZEND_STRLEN_SPEC_CV) \ + _(2163, ZEND_DEFINED_SPEC_CONST) \ + _(2164, ZEND_TYPE_CHECK_SPEC_CONST) \ + _(2165, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ _(2166, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2167, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2169, ZEND_TYPE_CHECK_SPEC_CV) \ - _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ - _(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ - _(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ - _(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ - _(2174, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ - _(2175, ZEND_FE_RESET_RW_SPEC_CONST) \ - _(2176, ZEND_FE_RESET_RW_SPEC_TMP) \ - _(2177, ZEND_FE_RESET_RW_SPEC_VAR) \ - _(2179, ZEND_FE_RESET_RW_SPEC_CV) \ - _(2180, ZEND_FE_FETCH_RW_SPEC_VAR) \ - _(2181, ZEND_FE_FREE_SPEC_TMPVAR) \ - _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ + _(2168, ZEND_TYPE_CHECK_SPEC_CV) \ + _(2169, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ + _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ + _(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ + _(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ + _(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ + _(2174, ZEND_FE_RESET_RW_SPEC_CONST) \ + _(2175, ZEND_FE_RESET_RW_SPEC_TMP) \ + _(2176, ZEND_FE_RESET_RW_SPEC_VAR) \ + _(2178, ZEND_FE_RESET_RW_SPEC_CV) \ + _(2179, ZEND_FE_FETCH_RW_SPEC_VAR) \ + _(2180, ZEND_FE_FREE_SPEC_TMPVAR) \ + _(2181, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ + _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ _(2183, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2184, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2186, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ - _(2187, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ - _(2188, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ + _(2185, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ + _(2186, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ + _(2187, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ + _(2188, ZEND_DO_ICALL_SPEC_OBSERVER) \ _(2189, ZEND_DO_ICALL_SPEC_OBSERVER) \ - _(2190, ZEND_DO_ICALL_SPEC_OBSERVER) \ - _(2191, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ - _(2192, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2190, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ + _(2191, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2192, ZEND_DO_UCALL_SPEC_OBSERVER) \ _(2193, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2194, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ - _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2194, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ + _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ _(2197, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2198, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ _(2210, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2211, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2213, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ - _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ + _(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ _(2215, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2216, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2218, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ - _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ + _(2218, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ _(2220, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2221, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2223, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ - _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ + _(2233, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ _(2235, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2236, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2238, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ - _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ + _(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ _(2240, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2241, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2243, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ - _(2244, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ + _(2243, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ _(2245, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2246, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2248, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ - _(2249, ZEND_ECHO_SPEC_CONST) \ + _(2247, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ + _(2248, ZEND_ECHO_SPEC_CONST) \ + _(2249, ZEND_ECHO_SPEC_TMPVAR) \ _(2250, ZEND_ECHO_SPEC_TMPVAR) \ - _(2251, ZEND_ECHO_SPEC_TMPVAR) \ - _(2253, ZEND_ECHO_SPEC_CV) \ - _(2260, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2263, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2265, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2268, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2275, ZEND_INSTANCEOF_SPEC_CV_CONST) \ - _(2277, ZEND_INSTANCEOF_SPEC_CV_VAR) \ - _(2278, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ - _(2280, ZEND_GENERATOR_CREATE_SPEC) \ - _(2283, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ - _(2285, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ - _(2286, ZEND_DECLARE_FUNCTION_SPEC) \ - _(2287, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ - _(2288, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ - _(2289, ZEND_DECLARE_CLASS_SPEC_CONST) \ - _(2290, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ - _(2291, ZEND_DECLARE_ANON_CLASS_SPEC) \ - _(2292, ZEND_ADD_ARRAY_UNPACK_SPEC) \ - _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2252, ZEND_ECHO_SPEC_CV) \ + _(2259, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ + _(2264, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ + _(2274, ZEND_INSTANCEOF_SPEC_CV_CONST) \ + _(2276, ZEND_INSTANCEOF_SPEC_CV_VAR) \ + _(2277, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ + _(2279, ZEND_GENERATOR_CREATE_SPEC) \ + _(2282, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ + _(2284, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ + _(2285, ZEND_DECLARE_FUNCTION_SPEC) \ + _(2286, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ + _(2287, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ + _(2288, ZEND_DECLARE_CLASS_SPEC_CONST) \ + _(2289, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ + _(2290, ZEND_DECLARE_ANON_CLASS_SPEC) \ + _(2291, ZEND_ADD_ARRAY_UNPACK_SPEC) \ + _(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ _(2294, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2295, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ - _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2299, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ + _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2304, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2305, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ + _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ _(2309, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ - _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ + _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ _(2314, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2317, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ - _(2318, ZEND_HANDLE_EXCEPTION_SPEC) \ - _(2319, ZEND_USER_OPCODE_SPEC) \ - _(2320, ZEND_ASSERT_CHECK_SPEC) \ - _(2321, ZEND_JMP_SET_SPEC_CONST) \ - _(2322, ZEND_JMP_SET_SPEC_TMP) \ - _(2323, ZEND_JMP_SET_SPEC_VAR) \ - _(2325, ZEND_JMP_SET_SPEC_CV) \ - _(2326, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ - _(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ - _(2328, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ - _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ + _(2317, ZEND_HANDLE_EXCEPTION_SPEC) \ + _(2318, ZEND_USER_OPCODE_SPEC) \ + _(2319, ZEND_ASSERT_CHECK_SPEC) \ + _(2320, ZEND_JMP_SET_SPEC_CONST) \ + _(2321, ZEND_JMP_SET_SPEC_TMP) \ + _(2322, ZEND_JMP_SET_SPEC_VAR) \ + _(2324, ZEND_JMP_SET_SPEC_CV) \ + _(2325, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ + _(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ + _(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ + _(2328, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ _(2330, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2331, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2333, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ - _(2334, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ + _(2333, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ _(2336, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2337, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2338, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ - _(2339, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ - _(2340, ZEND_CALL_TRAMPOLINE_SPEC) \ - _(2341, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ - _(2342, ZEND_DISCARD_EXCEPTION_SPEC) \ - _(2343, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2337, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ + _(2338, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ + _(2339, ZEND_CALL_TRAMPOLINE_SPEC) \ + _(2340, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ + _(2341, ZEND_DISCARD_EXCEPTION_SPEC) \ + _(2342, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \ _(2344, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2345, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2346, ZEND_YIELD_SPEC_CONST_UNUSED) \ - _(2347, ZEND_YIELD_SPEC_CONST_CV) \ - _(2348, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2345, ZEND_YIELD_SPEC_CONST_UNUSED) \ + _(2346, ZEND_YIELD_SPEC_CONST_CV) \ + _(2347, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \ _(2349, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2350, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2351, ZEND_YIELD_SPEC_TMP_UNUSED) \ - _(2352, ZEND_YIELD_SPEC_TMP_CV) \ - _(2353, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2350, ZEND_YIELD_SPEC_TMP_UNUSED) \ + _(2351, ZEND_YIELD_SPEC_TMP_CV) \ + _(2352, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \ _(2354, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2355, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2356, ZEND_YIELD_SPEC_VAR_UNUSED) \ - _(2357, ZEND_YIELD_SPEC_VAR_CV) \ - _(2358, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2355, ZEND_YIELD_SPEC_VAR_UNUSED) \ + _(2356, ZEND_YIELD_SPEC_VAR_CV) \ + _(2357, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ _(2359, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2360, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2361, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ - _(2362, ZEND_YIELD_SPEC_UNUSED_CV) \ - _(2363, ZEND_YIELD_SPEC_CV_CONST) \ + _(2360, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ + _(2361, ZEND_YIELD_SPEC_UNUSED_CV) \ + _(2362, ZEND_YIELD_SPEC_CV_CONST) \ + _(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \ _(2364, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2365, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2366, ZEND_YIELD_SPEC_CV_UNUSED) \ - _(2367, ZEND_YIELD_SPEC_CV_CV) \ - _(2368, ZEND_GENERATOR_RETURN_SPEC_CONST) \ - _(2369, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2370, ZEND_GENERATOR_RETURN_SPEC_TMP) \ - _(2371, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2372, ZEND_GENERATOR_RETURN_SPEC_VAR) \ - _(2373, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2376, ZEND_GENERATOR_RETURN_SPEC_CV) \ - _(2377, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2378, ZEND_FAST_CALL_SPEC) \ - _(2379, ZEND_FAST_RET_SPEC) \ - _(2380, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ - _(2381, ZEND_SEND_UNPACK_SPEC) \ - _(2382, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2365, ZEND_YIELD_SPEC_CV_UNUSED) \ + _(2366, ZEND_YIELD_SPEC_CV_CV) \ + _(2367, ZEND_GENERATOR_RETURN_SPEC_CONST) \ + _(2368, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2369, ZEND_GENERATOR_RETURN_SPEC_TMP) \ + _(2370, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2371, ZEND_GENERATOR_RETURN_SPEC_VAR) \ + _(2372, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2375, ZEND_GENERATOR_RETURN_SPEC_CV) \ + _(2376, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2377, ZEND_FAST_CALL_SPEC) \ + _(2378, ZEND_FAST_RET_SPEC) \ + _(2379, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ + _(2380, ZEND_SEND_UNPACK_SPEC) \ + _(2381, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \ _(2383, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2384, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2386, ZEND_YIELD_FROM_SPEC_CV) \ - _(2387, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ - _(2388, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ - _(2389, ZEND_COALESCE_SPEC_CONST) \ - _(2390, ZEND_COALESCE_SPEC_TMP) \ - _(2391, ZEND_COALESCE_SPEC_VAR) \ - _(2393, ZEND_COALESCE_SPEC_CV) \ - _(2394, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2385, ZEND_YIELD_FROM_SPEC_CV) \ + _(2386, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ + _(2387, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ + _(2388, ZEND_COALESCE_SPEC_CONST) \ + _(2389, ZEND_COALESCE_SPEC_TMP) \ + _(2390, ZEND_COALESCE_SPEC_VAR) \ + _(2392, ZEND_COALESCE_SPEC_CV) \ + _(2393, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ _(2395, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2396, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2398, ZEND_SPACESHIP_SPEC_CONST_CV) \ - _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2397, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2398, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2400, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2401, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ + _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2405, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2406, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2408, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2414, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ + _(2413, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ _(2415, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2416, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2418, ZEND_SPACESHIP_SPEC_CV_CV) \ - _(2419, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ - _(2420, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ - _(2423, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ - _(2425, ZEND_FETCH_STATIC_PROP_R_SPEC) \ - _(2426, ZEND_FETCH_STATIC_PROP_W_SPEC) \ - _(2427, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ - _(2428, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ - _(2429, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ - _(2430, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ - _(2431, ZEND_UNSET_STATIC_PROP_SPEC) \ - _(2432, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ - _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2417, ZEND_SPACESHIP_SPEC_CV_CV) \ + _(2418, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ + _(2419, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ + _(2422, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ + _(2424, ZEND_FETCH_STATIC_PROP_R_SPEC) \ + _(2425, ZEND_FETCH_STATIC_PROP_W_SPEC) \ + _(2426, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ + _(2427, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ + _(2428, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ + _(2429, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ + _(2430, ZEND_UNSET_STATIC_PROP_SPEC) \ + _(2431, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ + _(2432, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ _(2434, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2435, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2437, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2443, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ + _(2442, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2443, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ _(2444, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2445, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2446, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ + _(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ _(2449, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2450, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2452, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2458, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ - _(2459, ZEND_BIND_STATIC_SPEC_CV) \ - _(2460, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ - _(2461, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ - _(2464, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(2466, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ - _(2467, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2451, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ + _(2457, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ + _(2458, ZEND_BIND_STATIC_SPEC_CV) \ + _(2459, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ + _(2460, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ + _(2463, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(2465, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ + _(2466, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2467, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ _(2468, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2469, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2471, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2472, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2470, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2471, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2472, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ _(2473, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2474, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2476, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2477, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ - _(2478, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ - _(2479, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ - _(2481, ZEND_IN_ARRAY_SPEC_CV_CONST) \ - _(2482, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2475, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2476, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ + _(2477, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ + _(2478, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ + _(2480, ZEND_IN_ARRAY_SPEC_CV_CONST) \ + _(2481, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2482, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ _(2483, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2484, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2486, ZEND_COUNT_SPEC_CV_UNUSED) \ - _(2487, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2485, ZEND_COUNT_SPEC_CV_UNUSED) \ + _(2486, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2487, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ _(2488, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2489, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2490, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ - _(2491, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ - _(2492, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ - _(2493, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ - _(2494, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ - _(2495, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ - _(2497, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ - _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2489, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ + _(2490, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ + _(2491, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ + _(2492, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ + _(2493, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ + _(2494, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ + _(2496, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ + _(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ _(2499, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2500, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ - _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2504, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2505, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ + _(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2509, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2510, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2512, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2511, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ + _(2517, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ _(2519, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2520, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2522, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ - _(2523, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2521, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ + _(2522, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2523, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ _(2524, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2525, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2527, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2533, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ - _(2534, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ - _(2535, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ - _(2537, ZEND_CASE_STRICT_SPEC_TMP_CV) \ - _(2538, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ - _(2539, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ - _(2540, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ - _(2542, ZEND_CASE_STRICT_SPEC_VAR_CV) \ - _(2553, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2526, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2532, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ + _(2533, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ + _(2534, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ + _(2536, ZEND_CASE_STRICT_SPEC_TMP_CV) \ + _(2537, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ + _(2538, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ + _(2539, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ + _(2541, ZEND_CASE_STRICT_SPEC_VAR_CV) \ + _(2552, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2553, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ _(2554, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2555, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2557, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2558, ZEND_JMP_NULL_SPEC_CONST) \ - _(2559, ZEND_JMP_NULL_SPEC_TMP) \ - _(2560, ZEND_JMP_NULL_SPEC_VAR) \ - _(2562, ZEND_JMP_NULL_SPEC_CV) \ - _(2563, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ - _(2564, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ - _(2565, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ - _(2566, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2567, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ - _(2568, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ - _(2569, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ - _(2570, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ - _(2571, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ - _(2572, ZEND_FRAMELESS_ICALL_2_SPEC) \ - _(2573, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ - _(2574, ZEND_FRAMELESS_ICALL_3_SPEC) \ - _(2575, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ - _(2576, ZEND_JMP_FRAMELESS_SPEC_CONST) \ - _(2577, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ - _(2578, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2579, ZEND_RECV_NOTYPE_SPEC) \ + _(2556, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2557, ZEND_JMP_NULL_SPEC_CONST) \ + _(2558, ZEND_JMP_NULL_SPEC_TMP) \ + _(2559, ZEND_JMP_NULL_SPEC_VAR) \ + _(2561, ZEND_JMP_NULL_SPEC_CV) \ + _(2562, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ + _(2563, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ + _(2564, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ + _(2565, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ + _(2566, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ + _(2567, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ + _(2568, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ + _(2569, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ + _(2570, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ + _(2571, ZEND_FRAMELESS_ICALL_2_SPEC) \ + _(2572, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ + _(2573, ZEND_FRAMELESS_ICALL_3_SPEC) \ + _(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ + _(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \ + _(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ + _(2577, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2578, ZEND_RECV_NOTYPE_SPEC) \ + _(2580, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ _(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2582, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2584, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2585, ZEND_JMP_FORWARD_SPEC) \ - _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2583, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2584, ZEND_JMP_FORWARD_SPEC) \ + _(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2593, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2594, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2598, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2599, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2605, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2608, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2609, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2618, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2619, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2623, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2624, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2630, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2633, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2634, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2643, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2644, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2648, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2649, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2655, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2658, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2659, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2668, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2673, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2674, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2680, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2683, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2684, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2686, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ _(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2688, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2690, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2689, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2693, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2694, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2698, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2699, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2705, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2708, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2709, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2711, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ _(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2713, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2715, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2714, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2718, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2719, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2723, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2724, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2730, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2733, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2734, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2743, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2744, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2748, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2749, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2755, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2758, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2759, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2768, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2769, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2773, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2774, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2780, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2783, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2784, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2793, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2794, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2798, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2799, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2805, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2808, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2885, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2960, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3035, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3111, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3115, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3116, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3120, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3135, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3165, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3195, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3240, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3270, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3390, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3420, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3422, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3424, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3426, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3428, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3429, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3430, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3431, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3432, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3433, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(2809, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3110, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3114, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3115, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3119, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3123, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3420, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3422, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3424, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3426, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3428, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3429, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3430, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3431, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3432, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3433, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ _(3434, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3435, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3437, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3436, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3437, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ _(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3440, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3442, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3441, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3442, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3445, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3447, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3446, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3448, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3450, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3460, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3462, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ _(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3470, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3472, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3475, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3477, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3480, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3482, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3483, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3484, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3486, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3486+1, ZEND_NULL) + _(3471, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3474, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3476, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3479, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3481, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3482, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3483, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3484, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3485+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index d29fc069255db..202dfd3f734f3 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -102,7 +102,7 @@ static const char *zend_vm_opcodes_names[210] = { "ZEND_UNSET_OBJ", "ZEND_FE_RESET_R", "ZEND_FE_FETCH_R", - "ZEND_EXIT", + NULL, "ZEND_FETCH_R", "ZEND_FETCH_DIM_R", "ZEND_FETCH_OBJ_R", diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 2f59a5c874462..d472b5b9660f5 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -161,7 +161,6 @@ END_EXTERN_C() #define ZEND_UNSET_OBJ 76 #define ZEND_FE_RESET_R 77 #define ZEND_FE_FETCH_R 78 -#define ZEND_EXIT 79 #define ZEND_FETCH_R 80 #define ZEND_FETCH_DIM_R 81 #define ZEND_FETCH_OBJ_R 82 diff --git a/build/gen_stub.php b/build/gen_stub.php index 2898002094040..970214c9419c0 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -83,9 +83,15 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = } } + /* As exit() and die() are proper token/keywords an need to hack-around */ + $hasSpecialExitAsFunctionHandling = str_ends_with($stubFile, 'zend_builtin_functions.stub.php'); if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) { initPhpParser(); - $fileInfo = parseStubFile($stubCode ?? file_get_contents($stubFile)); + $stubContent = $stubCode ?? file_get_contents($stubFile); + if ($hasSpecialExitAsFunctionHandling) { + $stubContent = str_replace(['exit', 'die'], ['exit_dummy', 'die_dummy'], $stubContent); + } + $fileInfo = parseStubFile($stubContent); $context->parsedFiles[$stubFile] = $fileInfo; foreach ($fileInfo->dependencies as $dependency) { @@ -118,6 +124,9 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = $context->allConstInfos, $stubHash ); + if ($hasSpecialExitAsFunctionHandling) { + $arginfoCode = str_replace(['exit_dummy', 'die_dummy'], ['exit', 'die'], $arginfoCode); + } if (($context->forceRegeneration || $stubHash !== $oldStubHash) && file_put_contents($arginfoFile, $arginfoCode)) { echo "Saved $arginfoFile\n"; } diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 17333fc0d5067..379a5122217d1 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2557,7 +2557,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_GENERATOR_RETURN: case ZEND_RETURN_BY_REF: case ZEND_RETURN: - case ZEND_EXIT: case ZEND_MATCH_ERROR: /* switch through trampoline */ case ZEND_YIELD: @@ -3470,7 +3469,6 @@ ZEND_EXT_API int zend_jit_check_support(void) /* JIT has no effect on these opcodes */ case ZEND_BEGIN_SILENCE: case ZEND_END_SILENCE: - case ZEND_EXIT: break; default: if (zend_get_user_opcode_handler(i) != NULL) { diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 174b07ac10c1d..bb0caf477e511 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -16450,8 +16450,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr } else { ir_GUARD(ir_GE(ref, ir_CONST_I32(0)), jit_STUB_ADDR(jit, jit_stub_trace_halt)); } - } else if (opline->opcode == ZEND_EXIT || - opline->opcode == ZEND_GENERATOR_RETURN || + } else if (opline->opcode == ZEND_GENERATOR_RETURN || opline->opcode == ZEND_YIELD || opline->opcode == ZEND_YIELD_FROM) { ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_halt)); diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index de2481fb8d2bc..c7cd330970dff 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -314,7 +314,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op case ZEND_FAST_RET: case ZEND_GENERATOR_CREATE: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_YIELD: case ZEND_YIELD_FROM: case ZEND_INCLUDE_OR_EVAL: diff --git a/ext/opcache/tests/jit/ignored_opcodes.phpt b/ext/opcache/tests/jit/ignored_opcodes.phpt index 761a0b699a73a..eac4c237a9c09 100644 --- a/ext/opcache/tests/jit/ignored_opcodes.phpt +++ b/ext/opcache/tests/jit/ignored_opcodes.phpt @@ -9,7 +9,7 @@ opcache.jit=function zend_test.observer.enabled=1 zend_test.observer.show_output=1 zend_test.observer.observe_all=1 -zend_test.observer.show_opcode_in_user_handler=ZEND_EXIT, ZEND_BEGIN_SILENCE, ZEND_END_SILENCE +zend_test.observer.show_opcode_in_user_handler=ZEND_BEGIN_SILENCE, ZEND_END_SILENCE --EXTENSIONS-- opcache zend_test @@ -27,6 +27,9 @@ exit(@test()); - + + + + diff --git a/ext/standard/tests/array/array_filter_variation9.phpt b/ext/standard/tests/array/array_filter_variation9.phpt index d9c1f9258f3a9..ff0dc7711718b 100644 --- a/ext/standard/tests/array/array_filter_variation9.phpt +++ b/ext/standard/tests/array/array_filter_variation9.phpt @@ -23,9 +23,9 @@ try { echo $e->getMessage(), "\n"; } -// using language construct 'exit' as 'callback' +// using language construct 'isset' as 'callback' try { - var_dump( array_filter($input, 'exit') ); + var_dump( array_filter($input, 'isset') ); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -63,5 +63,5 @@ array(6) { int(1000) } array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name -array_filter(): Argument #2 ($callback) must be a valid callback or null, function "exit" not found or invalid function name +array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name Done diff --git a/ext/standard/tests/array/array_map_variation16.phpt b/ext/standard/tests/array/array_map_variation16.phpt index b7c6690040162..7ee1f04967c5c 100644 --- a/ext/standard/tests/array/array_map_variation16.phpt +++ b/ext/standard/tests/array/array_map_variation16.phpt @@ -2,32 +2,24 @@ Test array_map() function : usage variations - failing built-in functions & language constructs --FILE-- getMessage(), "\n"; } @@ -36,21 +28,11 @@ for($count = 0; $count < count($callback_names); $count++) echo "Done"; ?> --EXPECT-- -*** Testing array_map() : non-permmited built-in functions *** --- Iteration 1 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "echo" not found or invalid function name --- Iteration 2 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "array" not found or invalid function name --- Iteration 3 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "empty" not found or invalid function name --- Iteration 4 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "eval" not found or invalid function name --- Iteration 5 -- -array_map(): Argument #1 ($callback) must be a valid callback or null, function "exit" not found or invalid function name --- Iteration 6 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "isset" not found or invalid function name --- Iteration 7 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "list" not found or invalid function name --- Iteration 8 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "print" not found or invalid function name Done diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index d3a3ea2144548..2314068044fb8 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -608,7 +608,6 @@ int phpdbg_skip_line_helper(void) /* {{{ */ { || opline->opcode == ZEND_RETURN || opline->opcode == ZEND_FAST_RET || opline->opcode == ZEND_GENERATOR_RETURN - || opline->opcode == ZEND_EXIT || opline->opcode == ZEND_YIELD || opline->opcode == ZEND_YIELD_FROM ) { @@ -652,7 +651,6 @@ static void phpdbg_seek_to_end(void) /* {{{ */ { case ZEND_RETURN: case ZEND_FAST_RET: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_YIELD: case ZEND_YIELD_FROM: zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline); From d100caa476f62a9f6576dcf2c5d8dbb88ed9c57e Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Wed, 14 Aug 2024 13:52:07 +0200 Subject: [PATCH 013/280] [skip ci] Add NEWS/UPGRADING + wording amendment for GH-13483 --- NEWS | 6 ++++++ UPGRADING | 7 +++++++ build/gen_stub.php | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 2c65e9799aba4..f25196e738501 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,12 @@ PHP NEWS - Core: . Exiting a namespace now clears seen symbols. (ilutov) + . The exit (and die) language constructs now behave more like a function. + They can be passed liked callables, are affected by the strict_types + declare statement, and now perform the usual type coercions instead of + casting any non-integer value to a string. + As such, passing invalid types to exit/die may now result in a TypeError + being thrown. (Girgias) 15 Aug 2024, PHP 8.4.0beta1 diff --git a/UPGRADING b/UPGRADING index bcf95365538b9..438ab25f5c6d8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -37,6 +37,13 @@ PHP 8.4 UPGRADE NOTES allowed, e.g. $ref = &$this->readonly. This was already forbidden for readonly initialization, and was an oversight in the "readonly reinitialization during cloning" implementation. + . The exit (and die) language constructs now behave more like a function. + They can be passed liked callables, are affected by the strict_types + declare statement, and now perform the usual type coercions instead of + casting any non-integer value to a string. + As such, passing invalid types to exit/die may now result in a TypeError + being thrown. + RFC: https://wiki.php.net/rfc/exit-as-function - DBA: . dba_open() and dba_popen() will now return a Dba\Connection diff --git a/build/gen_stub.php b/build/gen_stub.php index 970214c9419c0..1d92ddd46b9ee 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -83,7 +83,7 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = } } - /* As exit() and die() are proper token/keywords an need to hack-around */ + /* Because exit() and die() are proper token/keywords we need to hack-around */ $hasSpecialExitAsFunctionHandling = str_ends_with($stubFile, 'zend_builtin_functions.stub.php'); if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) { initPhpParser(); From 74bf8949502db3e3cd2bdf7fbf0c764f0f24baff Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 14 Aug 2024 13:20:26 +0100 Subject: [PATCH 014/280] ext/standard/info.c: Throw ValueErrors on invalid inputs to php_uname() (#15385) --- NEWS | 3 ++ UPGRADING | 1 + ext/standard/info.c | 23 +++++++++++++-- .../general_functions/php_uname_error.phpt | 29 ++++++++++++------- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index f25196e738501..0eb4a2837b000 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ PHP NEWS As such, passing invalid types to exit/die may now result in a TypeError being thrown. (Girgias) +- Standard: + . php_uname() now throws ValueErrors on invalid inputs. (Girgias) + 15 Aug 2024, PHP 8.4.0beta1 - Core: diff --git a/UPGRADING b/UPGRADING index 438ab25f5c6d8..0932ba539d3ba 100644 --- a/UPGRADING +++ b/UPGRADING @@ -200,6 +200,7 @@ PHP 8.4 UPGRADE NOTES $enclosure arguments are not one byte long, or if the $escape is not one byte long or the empty string. This aligns the behaviour to be identical to that of fputcsv() and fgetcsv(). + . php_uname() now throws ValueErrors on invalid inputs. - Tidy: . Failures in the constructor now throw exceptions rather than emitting diff --git a/ext/standard/info.c b/ext/standard/info.c index 5e273588cb175..2da58f3cccef6 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -656,10 +656,16 @@ static void php_get_windows_cpu(char *buf, size_t bufsize) /* }}} */ #endif +static inline bool php_is_valid_uname_mode(char mode) { + return mode == 'a' || mode == 'm' || mode == 'n' || mode == 'r' || mode == 's' || mode == 'v'; +} + /* {{{ php_get_uname */ PHPAPI zend_string *php_get_uname(char mode) { char *php_uname; + + ZEND_ASSERT(php_is_valid_uname_mode(mode)); #ifdef PHP_WIN32 char tmp_uname[256]; DWORD dwBuild=0; @@ -1313,15 +1319,26 @@ PHP_FUNCTION(php_sapi_name) /* {{{ Return information about the system PHP was built on */ PHP_FUNCTION(php_uname) { - char *mode = "a"; + char *mode_str = "a"; size_t modelen = sizeof("a")-1; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STRING(mode, modelen) + Z_PARAM_STRING(mode_str, modelen) ZEND_PARSE_PARAMETERS_END(); - RETURN_STR(php_get_uname(*mode)); + if (modelen != 1) { + zend_argument_value_error(1, "must be a single character"); + RETURN_THROWS(); + } + + char mode = *mode_str; + if (!php_is_valid_uname_mode(mode)) { + zend_argument_value_error(1, "must be one of \"a\", \"m\", \"n\", \"r\", \"s\", or \"v\""); + RETURN_THROWS(); + } + + RETURN_STR(php_get_uname(mode)); } /* }}} */ diff --git a/ext/standard/tests/general_functions/php_uname_error.phpt b/ext/standard/tests/general_functions/php_uname_error.phpt index 2f65ed587d36c..694ec19fb6b39 100644 --- a/ext/standard/tests/general_functions/php_uname_error.phpt +++ b/ext/standard/tests/general_functions/php_uname_error.phpt @@ -1,17 +1,26 @@ --TEST-- -Test php_uname() function - error conditions - pass function incorrect arguments +php_uname(): Invalid arguments --FILE-- getMessage(), PHP_EOL; +} +try { + var_dump(php_uname('test')); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + var_dump(php_uname('z')); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- -*** Testing php_uname() - error test - --- Testing php_uname() function with invalid mode -- -bool(true) +ValueError: php_uname(): Argument #1 ($mode) must be a single character +ValueError: php_uname(): Argument #1 ($mode) must be a single character +ValueError: php_uname(): Argument #1 ($mode) must be one of "a", "m", "n", "r", "s", or "v" From a2a3c5ba8a79cfda1071b19fe59391bf896dc728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 14 Aug 2024 15:18:07 +0200 Subject: [PATCH 015/280] hash: Consistently check for PHP_HASH_INTRIN_SHA_* to guard compilation of SHA256_Transform_shani (#15404) This fixes the build for amd64 platforms that do not have `HAVE_FUNC_ATTRIBUTE_TARGET`, specifically Alpine/Musl as of now. Closes GH-15384. Related to GH-15312. --- NEWS | 3 +++ ext/hash/hash_sha_ni.c | 2 +- ext/hash/php_hash_sha.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 0eb4a2837b000..e76fa144dbe13 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ PHP NEWS As such, passing invalid types to exit/die may now result in a TypeError being thrown. (Girgias) +- Hash: + . Fix GH-15384 (Build fails on Alpine / Musl for amd64). (timwolla) + - Standard: . php_uname() now throws ValueErrors on invalid inputs. (Girgias) diff --git a/ext/hash/hash_sha_ni.c b/ext/hash/hash_sha_ni.c index 3c98786c73fd2..92a2235e28415 100644 --- a/ext/hash/hash_sha_ni.c +++ b/ext/hash/hash_sha_ni.c @@ -27,7 +27,7 @@ #include "php_hash.h" #include "php_hash_sha.h" -#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IMMINTRIN_H) +#if defined(PHP_HASH_INTRIN_SHA_NATIVE) || defined(PHP_HASH_INTRIN_SHA_RESOLVER) # include diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index d5282026b96a6..7336a5ba0aa40 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -62,7 +62,9 @@ void SHA256_Transform_sse2(uint32_t state[PHP_STATIC_RESTRICT 8], const uint8_t # elif defined(HAVE_FUNC_ATTRIBUTE_TARGET) # define PHP_HASH_INTRIN_SHA_RESOLVER 1 # endif +#endif +#if defined(PHP_HASH_INTRIN_SHA_NATIVE) || defined(PHP_HASH_INTRIN_SHA_RESOLVER) void SHA256_Transform_shani(uint32_t state[PHP_STATIC_RESTRICT 8], const uint8_t block[PHP_STATIC_RESTRICT 64]); #endif From f6dcca00bc94fe1734dea67e31add7d8a949a9df Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 16:40:10 +0200 Subject: [PATCH 016/280] Autotools: Substitute PHP_EMBED_TYPE conditionally (#15396) If passing wrong argument at --enable-embed=ARGUMENT the AC_SUBST don't need to be used for it in php-config. --- sapi/embed/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index 86856124f2327..7029f94c7137e 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -23,6 +23,7 @@ if test "$PHP_EMBED" != "no"; then AS_VAR_IF([PHP_EMBED_TYPE], [no],, [ PHP_SUBST([LIBPHP_CFLAGS]) + AC_SUBST([PHP_EMBED_TYPE]) PHP_SELECT_SAPI([embed], [$PHP_EMBED_TYPE], [php_embed.c], @@ -30,7 +31,6 @@ if test "$PHP_EMBED" != "no"; then PHP_INSTALL_HEADERS([sapi/embed], [php_embed.h]) ]) AC_MSG_RESULT([$PHP_EMBED_TYPE]) - AC_SUBST([PHP_EMBED_TYPE]) else AC_MSG_RESULT([no]) fi From 68d5c8145d6355f9dbea98329fe2adfa14ff4067 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 08:52:32 +0200 Subject: [PATCH 017/280] [skip ci] 8.4 | UPGRADING: add missing RFC links Includes fixing up existing (deprecations) RFC links which didn't directly link to the section within the RFC. --- UPGRADING | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/UPGRADING b/UPGRADING index 0932ba539d3ba..8bb8f0b9dfbe0 100644 --- a/UPGRADING +++ b/UPGRADING @@ -64,8 +64,8 @@ PHP 8.4 UPGRADE NOTES object. This is no longer possible, and cloning a DOMXPath object now throws an error. . DOMDocument::$actualEncoding, DOMDocument::config, DOMEntity::$actualEncoding, - DOMEntity::$encoding, DOMEntity::$version have been deprecated as part of the - https://wiki.php.net/rfc/deprecations_php_8_4 RFC. + DOMEntity::$encoding, DOMEntity::$version have been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#formally_deprecate_soft-deprecated_domdocument_and_domentity_properties - GMP: . The GMP class is now final and cannot be extended anymore. @@ -305,6 +305,7 @@ PHP 8.4 UPGRADE NOTES . Added support for driver specific SQL parsers. The default parser supports: - single and double quoted literals, with doubling as escaping mechanism. - two-dashes and non-nested C-style comments. + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_MYSQL: . Added custom parser supporting: @@ -313,6 +314,7 @@ PHP 8.4 UPGRADE NOTES - backtick literal identifiers and with doubling as escaping mechanism - two dashes followed by at least 1 whitespace, non-nested C-style comments, and hash-comments + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_PGSQL: . Added custom parser supporting: @@ -321,12 +323,14 @@ PHP 8.4 UPGRADE NOTES - dollar-quoted string literals - two-dashes and C-style comments (non-nested) - support for "??" as escape sequence for the "?" operator + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_SQLITE: . Added custom parser supporting: - single, double quoted, and backtick literals, with doubling as escaping mechanism - square brackets quoting for identifiers - two-dashes and C-style comments (non-nested) + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - Phar: . Added support for the unix timestamp extension for zip archives. @@ -443,7 +447,7 @@ PHP 8.4 UPGRADE NOTES . Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and SUNFUNCS_RET_DOUBLE are now deprecated, following the deprecation of the associated date_sunset() and date_sunrise() functions in PHP 8.1. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#constants_sunfuncs_ret_string_sunfuncs_ret_double_sunfuncs_ret_timestamp - DBA: . Passing null or false to dba_key_split() is deprecated. @@ -455,7 +459,7 @@ PHP 8.4 UPGRADE NOTES - Hash: . Deprecated passing incorrect data types for options to ext/hash functions. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_incorrect_data_types_for_options_to_exthash_functions - Intl: . Calling intlcal_set() as well as calling IntlCalendar::set() with @@ -505,7 +509,7 @@ PHP 8.4 UPGRADE NOTES - Random: . lcg_value() is deprecated, as the function is broken in multiple ways. Use \Random\Randomizer::getFloat() instead. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_lcg_value - Reflection: . Calling ReflectionMethod::__construct() with 1 argument is deprecated. @@ -517,7 +521,7 @@ PHP 8.4 UPGRADE NOTES . Changing the INI settings session.sid_length and session.sid_bits_per_character is deprecated. Update the session storage backend to accept 32 character hexadecimal session IDs and stop changing these two INI settings. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#sessionsid_length_and_sessionsid_bits_per_character - SOAP: . Passing an int to SoapServer::addFunction() is now deprecated. @@ -543,7 +547,7 @@ PHP 8.4 UPGRADE NOTES . Raising zero to the power of negative number is deprecated. RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number . Unserializing strings using the uppercase 'S' tag is deprecated. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#unserialize_s_s_tag . Passing a non-empty string for the $enclosure parameter of: - fputcsv() - fgetcsv() @@ -683,11 +687,9 @@ PHP 8.4 UPGRADE NOTES earlier PHP versions. . The $mode parameter of the round() function has been widened to RoundingMode|int, accepting instances of a new RoundingMode enum. - RFC: https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum . Four new modes have been added to the round() function: RoundingMode::PositiveInfinity, RoundingMode::NegativeInfinity, RoundingMode::TowardsZero, RoundingMode::AwayFromZero. - RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function . Fixed a bug caused by "pre-rounding" of the round() function. Previously, using "pre-rounding" to treat a value like 0.285 (actually 0.28499999999999998) as a @@ -699,7 +701,6 @@ PHP 8.4 UPGRADE NOTES but now returns `4503599627370496`. . The default value of the 'cost' option for PASSWORD_BCRYPT for password_hash() has been increased from '10' to '12'. - RFC: https://wiki.php.net/rfc/bcrypt_cost_2023 . debug_zval_dump() now indicates whether an array is packed. . long2ip() now returns string instead of string|false. From 0abd54d5389e141b83a75c1db06855dcdb1d7e7f Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 08:56:11 +0200 Subject: [PATCH 018/280] [skip ci] 8.4 | UPGRADING: join PDO entries There were multiple headers for the same PDO extensions in the "New features" section. This joins these together. --- UPGRADING | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/UPGRADING b/UPGRADING index 8bb8f0b9dfbe0..b19f972725ba4 100644 --- a/UPGRADING +++ b/UPGRADING @@ -302,12 +302,25 @@ PHP 8.4 UPGRADE NOTES extended to support those keys. - PDO: + . Added support for driver-specific subclasses. + RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses + This RFC adds subclasses for PDO in order to better support + database-specific functionalities. The new classes are + instantiatable either via calling the PDO::connect() method + or by invoking their constructor directly. . Added support for driver specific SQL parsers. The default parser supports: - single and double quoted literals, with doubling as escaping mechanism. - two-dashes and non-nested C-style comments. RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers +- PDO_DBLIB: + . Added class Pdo\DbLib. + +- PDO_FIREBIRD: + . Added class Pdo\Firebird. + - PDO_MYSQL: + . Added class Pdo\Mysql. . Added custom parser supporting: - single and double-quoted literals, with doubling and backslash as escaping mechanism @@ -316,7 +329,11 @@ PHP 8.4 UPGRADE NOTES and hash-comments RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers +- PDO_ODBC: + . Added class Pdo\Odbc. + - PDO_PGSQL: + . Added class Pdo\Pgsql. . Added custom parser supporting: - single and double quoted literals, with doubling as escaping mechanism - C-style "escape" string literals (E'string') @@ -326,6 +343,7 @@ PHP 8.4 UPGRADE NOTES RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_SQLITE: + . Added class Pdo\Sqlite. . Added custom parser supporting: - single, double quoted, and backtick literals, with doubling as escaping mechanism - square brackets quoting for identifiers @@ -347,32 +365,6 @@ PHP 8.4 UPGRADE NOTES modifier ("i"), the expression locks out mixing of ASCII and non-ASCII characters. -- PDO: - . Added support for driver-specific subclasses. - RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses - This RFC adds subclasses for PDO in order to better support - database-specific functionalities. The new classes are - instantiatable either via calling the PDO::connect() method - or by invoking their constructor directly. - -- PDO_DBLIB: - . Added class Pdo\DbLib. - -- PDO_FIREBIRD: - . Added class Pdo\Firebird. - -- PDO_MYSQL: - . Added class Pdo\Mysql. - -- PDO_ODBC: - . Added class Pdo\Odbc. - -- PDO_PGSQL: - . Added class Pdo\Pgsql. - -- PDO_SQLITE: - . Added class Pdo\Sqlite. - - POSIX: . Added constant POSIX_SC_CHILD_MAX . Added constant POSIX_SC_CLK_TCK From d61cb70e6527fc793cc853e36c5ab8169c126793 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 09:21:59 +0200 Subject: [PATCH 019/280] [skip ci] 8.4 | UPGRADING: fix extension order A number of times, extensions were not listed in alphabetic order. Fixed now. Includes a few minor fixes where extension names were using inconsistent casing across the file. --- UPGRADING | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/UPGRADING b/UPGRADING index b19f972725ba4..237c1c47089fe 100644 --- a/UPGRADING +++ b/UPGRADING @@ -126,6 +126,22 @@ PHP 8.4 UPGRADE NOTES has changed. Consult https://github.com/PCRE2Project/pcre2/blob/master/NEWS for a full changelog. +- PCNTL: + . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and + pcntl_sigtimedwait() now throw: + - A ValueError if the $signals array is empty (except for + pcntl_sigprocmask() if the $mode is SIG_SETMASK). + - A TypeError if a value of the $signals array is not an integer + - A ValueError if a value of the $signals array is not a valid signal number + Moreover, those functions now always return false on failure. + In some case previously it could return the value -1. + . The function pcntl_sigprocmask() will also now throw: + - A ValueError if $mode is not one of SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK + . The function pcntl_sigtimedwait() will also now throw: + - A ValueError if $seconds is less than 0 + - A ValueError if $nanoseconds is less than 0 or greater than 1e9 + - A ValueError if both $seconds and $nanoseconds are 0 + - PDO_DBLIB: . setAttribute, DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER and DBLIB_ATTR_DATETIME_CONVERT have been changed to set value as a bool. @@ -143,22 +159,6 @@ PHP 8.4 UPGRADE NOTES . The DSN's credentials, when set, are given priority over their PDO constructor counterparts, being closer to the documentation states. -- PCNTL: - . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and - pcntl_sigtimedwait() now throw: - - A ValueError if the $signals array is empty (except for - pcntl_sigprocmask() if the $mode is SIG_SETMASK). - - A TypeError if a value of the $signals array is not an integer - - A ValueError if a value of the $signals array is not a valid signal number - Moreover, those functions now always return false on failure. - In some case previously it could return the value -1. - . The function pcntl_sigprocmask() will also now throw: - - A ValueError if $mode is not one of SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK - . The function pcntl_sigtimedwait() will also now throw: - - A ValueError if $seconds is less than 0 - - A ValueError if $nanoseconds is less than 0 or greater than 1e9 - - A ValueError if both $seconds and $nanoseconds are 0 - - SimpleXML: . Get methods called, or casting to a string on a SimpleXMLElement will no longer implicitly reset the iterator data, unless explicitly rewound. @@ -301,6 +301,18 @@ PHP 8.4 UPGRADE NOTES openssl_pkey_get_details as well as openssl_sign and openssl_verify were extended to support those keys. +- PCRE: + . The bundled pcre2lib has been updated to version 10.44. + As a consequence, LoongArch JIT support has been added, spaces + are now allowed between braces in Perl-compatible items, and + variable-length lookbehind assertions are now supported. + . With pcre2lib version 10.44, the maximum length of named capture groups + has changed from 32 to 128. + . Added support for the "r" (PCRE2_EXTRA_CASELESS_RESTRICT) modifier, as well + as the (?r) mode modifier. When enabled along with the case-insensitive + modifier ("i"), the expression locks out mixing of ASCII and non-ASCII + characters. + - PDO: . Added support for driver-specific subclasses. RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses @@ -353,18 +365,6 @@ PHP 8.4 UPGRADE NOTES - Phar: . Added support for the unix timestamp extension for zip archives. -- PCRE: - . The bundled pcre2lib has been updated to version 10.44. - As a consequence, LoongArch JIT support has been added, spaces - are now allowed between braces in Perl-compatible items, and - variable-length lookbehind assertions are now supported. - . With pcre2lib version 10.44, the maximum length of named capture groups - has changed from 32 to 128. - . Added support for the "r" (PCRE2_EXTRA_CASELESS_RESTRICT) modifier, as well - as the (?r) mode modifier. When enabled along with the case-insensitive - modifier ("i"), the expression locks out mixing of ASCII and non-ASCII - characters. - - POSIX: . Added constant POSIX_SC_CHILD_MAX . Added constant POSIX_SC_CLK_TCK @@ -602,6 +602,12 @@ PHP 8.4 UPGRADE NOTES . The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16 strings. (For valid UTF-8 and UTF-16 strings, there is no change.) +- ODBC: + . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and + odbc_fetch_into() now has a default value of null, consistent with + odbc_fetch_row(). Previously, the default values were -1, -1, and 0, + respectively. + - OpenSSL: . The extra_attributes parameter in openssl_csr_new sets CSR attributes instead of subject DN which was incorrectly done previously. @@ -613,12 +619,6 @@ PHP 8.4 UPGRADE NOTES for OpenSSL version below 3.2 (-1 is returned for such fields). The OpenSSL version 3.3+ does not load such certificates already. -- ODBC: - . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and - odbc_fetch_into() now has a default value of null, consistent with - odbc_fetch_row(). Previously, the default values were -1, -1, and 0, - respectively. - - Output: . Output handler status flags passed to the flags parameter of ob_start are now cleared. @@ -869,7 +869,7 @@ PHP 8.4 UPGRADE NOTES - MBString: . Unicode data tables have been updated to Unicode 15.1. -- mysqli: +- Mysqli: . The unused and undocumented constant MYSQLI_SET_CHARSET_DIR has been removed. @@ -879,10 +879,10 @@ PHP 8.4 UPGRADE NOTES - PDO: . The class constants are typed now. -- pdo_pgsql: +- PDO_PGSQL: . The pdo_pgsql extension now requires at least libpq 10.0. -- pgsql: +- PgSQL: . The pgsql extension now requires at least libpq 10.0. - Reflection: From ba321af07cb5ff70157503d8090352a5f49ab054 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 10:29:22 +0200 Subject: [PATCH 020/280] [skip ci] 8.4 | UPGRADING: fix typo --- UPGRADING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADING b/UPGRADING index 237c1c47089fe..281b036a01aa2 100644 --- a/UPGRADING +++ b/UPGRADING @@ -490,7 +490,7 @@ PHP 8.4 UPGRADE NOTES is no longer necessary to escape question marks inside them. - PgSQL: - . Calling pgsql_fetch_result() with 2 arguments is deprecated. Use the + . Calling pg_fetch_result() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. . Calling pg_field_prtlen() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. From d245bf12e73927cba908a2feb458190ea5015489 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 10:37:34 +0200 Subject: [PATCH 021/280] [skip ci] 8.4 | UPGRADING: move new function to correct section The `pg_result_memory_size()` function is a new feature, not a deprecated feature. --- UPGRADING | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UPGRADING b/UPGRADING index 281b036a01aa2..e1f03e2b06d42 100644 --- a/UPGRADING +++ b/UPGRADING @@ -365,6 +365,9 @@ PHP 8.4 UPGRADE NOTES - Phar: . Added support for the unix timestamp extension for zip archives. +- PgSQL: + . Added pg_result_memory_size to get the visibility the memory used by a query result. + - POSIX: . Added constant POSIX_SC_CHILD_MAX . Added constant POSIX_SC_CLK_TCK @@ -496,7 +499,6 @@ PHP 8.4 UPGRADE NOTES 3-parameter signature with a null $row parameter instead. . Calling pg_field_is_null() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. - . Added pg_result_memory_size to get the visibility the memory used by a query result. - Random: . lcg_value() is deprecated, as the function is broken in multiple ways. From ddaeb203b2cd1c9506c684fb6c928cbbe8daa7a3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 13:18:27 +0200 Subject: [PATCH 022/280] [skip ci] 8.4 | UPGRADING: fix incorrect function names Ref: https://github.com/php/php-src/commit/1cf8291c8519919eb58d00f25f0b917363fed971#diff-d22d5ad00ee9f000cb8c8f9a5cfb905a8de91e7dc4a633896e2c5ab4ad1513d1 --- NEWS | 2 +- UPGRADING | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index e76fa144dbe13..a71c9967b0ff6 100644 --- a/NEWS +++ b/NEWS @@ -410,7 +410,7 @@ PHP NEWS - PCNTL: . Added pcntl_setns for Linux. (David Carlier) - . Added pcntl_getaffinity/pcntl_setaffinity. (David Carlier) + . Added pcntl_getcpuaffinity/pcntl_setcpuaffinity. (David Carlier) . Updated pcntl_get_signal_handler signal id upper limit to be more in line with platforms limits. (David Carlier) . Added pcntl_getcpu for Linux/FreeBSD/Solaris/Illumos. (David Carlier) diff --git a/UPGRADING b/UPGRADING index e1f03e2b06d42..87c74d51ea828 100644 --- a/UPGRADING +++ b/UPGRADING @@ -739,8 +739,8 @@ PHP 8.4 UPGRADE NOTES - PCNTL: . Added pcntl_setns allowing a process to be reassociated with a namespace in order to share resources with other processes within this context. - . Added pcntl_getaffinity to get the cpu(s) bound to a process and - pcntl_setaffinity to bind 1 or more cpus to a process. + . Added pcntl_getcpuaffinity to get the cpu(s) bound to a process and + pcntl_setcpuaffinity to bind 1 or more cpus to a process. . Added pcntl_getcpu to get the cpu id from where the current process runs. . Added pcntl_getqos_class to get the QoS level (aka performance and related energy consumption) of the current process and pcntl_setqos_class to set it. From d2810f575759fcbef42a37a174f655026b2a9c20 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 14 Aug 2024 14:00:54 +0200 Subject: [PATCH 023/280] [skip ci] 8.4 | UPGRADING: add missing constant Ref: https://github.com/php/php-src/commit/564914ac1ac872d5d3dd97bdc4c4c17539ce2fb2#diff-c5961ea04ab805b0059964fac68d6e159095a4b56aaaded0b1b941b8768c0f52 --- UPGRADING | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UPGRADING b/UPGRADING index 87c74d51ea828..c6dd6f0b10380 100644 --- a/UPGRADING +++ b/UPGRADING @@ -961,6 +961,9 @@ PHP 8.4 UPGRADE NOTES . P_SID (NetBSD/FreeBSD only). . P_JAILID (FreeBSD only). +- PgSQL: + . PGSQL_TUPLES_CHUNK + - Sockets: . SO_EXCLUSIVEADDRUSE (Windows only). . SOCK_CONN_DGRAM (NetBSD only). From 390088bf551b4ac1cdb17c49dfbf133a207bc0e3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 14 Aug 2024 19:52:47 +0200 Subject: [PATCH 024/280] Remove detection of unsupported Windows versions (GH-15399) Windows 2008 and Vista are no longer supported as of PHP 7.2.0, and Windows 2008 R2 and Windows 7 are no longer supported as of PHP 8.3.0. Therefore we remove the respective detection code, and assert that these versions can no longer be used. --- ext/standard/info.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/ext/standard/info.c b/ext/standard/info.c index 2da58f3cccef6..8a706ef62eb57 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -296,19 +296,8 @@ static char* php_get_windows_name() } } else if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 6) { if (osvi.dwMajorVersion == 6) { - if (osvi.dwMinorVersion == 0) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - major = "Windows Vista"; - } else { - major = "Windows Server 2008"; - } - } else if (osvi.dwMinorVersion == 1) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - major = "Windows 7"; - } else { - major = "Windows Server 2008 R2"; - } - } else if (osvi.dwMinorVersion == 2) { + ZEND_ASSERT(osvi.dwMinorVersion >= 2); + if (osvi.dwMinorVersion == 2) { /* could be Windows 8/Windows Server 2012, could be Windows 8.1/Windows Server 2012 R2 */ /* XXX and one more X - the above comment is true if no manifest is used for two cases: - if the PHP build doesn't use the correct manifest From 25afbdb09e18d4477df1822fbfe76480e6c2aa79 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 14 Aug 2024 20:00:27 +0200 Subject: [PATCH 025/280] GetSystemTimePreciseAsFileTime() is now always available (GH-15400) * GetSystemTimePreciseAsFileTime() is now always available As of PHP 8.3.0, we require Windows Server 2012 or Windows 8 as bare minimum. Since GetSystemTimePreciseAsFileTime() is always available on these Windows versions[1], there is no more need for the workaround described in dllmain.c; we just can call the function directly. [1] --- win32/dllmain.c | 14 -------------- win32/time.c | 31 +------------------------------ 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/win32/dllmain.c b/win32/dllmain.c index a507f1e169246..ab625bf3e597b 100644 --- a/win32/dllmain.c +++ b/win32/dllmain.c @@ -38,20 +38,6 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy) switch (reason) { case DLL_PROCESS_ATTACH: - /* - * We do not need to check the return value of php_win32_init_gettimeofday() - * because the symbol bare minimum symbol we need is always available on our - * lowest supported platform. - * - * On Windows 8 or greater, we use a more precise symbol to obtain the system - * time, which is dynamically. The fallback allows us to proper support - * Vista/7/Server 2003 R2/Server 2008/Server 2008 R2. - * - * Instead simply initialize the global in win32/time.c for gettimeofday() - * use later on - */ - php_win32_init_gettimeofday(); - ret = ret && php_win32_ioutil_init(); if (!ret) { fprintf(stderr, "ioutil initialization failed"); diff --git a/win32/time.c b/win32/time.c index d1fe51458ec57..57db914e6a8f6 100644 --- a/win32/time.c +++ b/win32/time.c @@ -23,42 +23,13 @@ #include #include "php_win32_globals.h" -typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); - -static MyGetSystemTimeAsFileTime timefunc = NULL; - -#ifdef PHP_EXPORTS -static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void) -{/*{{{*/ - MyGetSystemTimeAsFileTime timefunc = NULL; - HMODULE hMod = GetModuleHandle("kernel32.dll"); - - if (hMod) { - /* Max possible resolution <1us, win8/server2012 */ - timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); - } - - if(!timefunc) { - /* 100ns blocks since 01-Jan-1641 */ - timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime; - } - - return timefunc; -}/*}}}*/ - -void php_win32_init_gettimeofday(void) -{/*{{{*/ - timefunc = get_time_func(); -}/*}}}*/ -#endif - static zend_always_inline int getfilesystemtime(struct timeval *tv) {/*{{{*/ FILETIME ft; unsigned __int64 ff = 0; ULARGE_INTEGER fft; - timefunc(&ft); + GetSystemTimePreciseAsFileTime(&ft); /* * Do not cast a pointer to a FILETIME structure to either a From 53d6ed8a6be74a4d2e11e83bbac780ccd67fc0f6 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 20:05:18 +0200 Subject: [PATCH 026/280] Autotools: Fix typo in FPM TCP_CONNECTION_INFO check (#15411) Otherwise, the check even works with such typo, but this fixes the TCP_CONNECTION_INFO check on macOS machines for FPM. --- sapi/fpm/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 3648cae63af10..97138280c0708 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -235,7 +235,7 @@ AC_DEFUN([PHP_FPM_LQ], AS_VAR_IF([php_cv_have_TCP_INFO], [yes], [AC_DEFINE([HAVE_LQ_TCP_INFO], [1], [Define to 1 if you have 'TCP_INFO'.])]) -AC_CACHE_CHECK([for TCP_CONNECTION_INFO], [php_cv_have_TCP_CONNECTION_INFO] +AC_CACHE_CHECK([for TCP_CONNECTION_INFO], [php_cv_have_TCP_CONNECTION_INFO], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [ struct tcp_connection_info ti; int x = TCP_CONNECTION_INFO; From 059fe6c28b6d9104c439180b6b5d4ee7b46cd0dc Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 14 Aug 2024 20:04:51 +0100 Subject: [PATCH 027/280] ext/standard/php_string.h: Remove declarations that do not have an implementation (#15402) This was overlooked, by my younger self, in GH-8195. --- ext/standard/php_string.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 654ce5d0eddff..1be7d9b283772 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -58,10 +58,6 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); -PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive); -PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2); -PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2); - PHPAPI bool php_binary_string_shuffle(php_random_algo_with_state engine, char *str, zend_long len); #ifdef _REENTRANT From ec2655f88b8a4cad2619fa8b92dbdee2e57a9031 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 14 Aug 2024 21:09:26 +0200 Subject: [PATCH 028/280] Voidify getfilesystemtime() (GH-15413) The function always returned 0, and the return values was never used, so we declare it to return void. While we're at it, we also fix the space indentation of the comment. --- win32/time.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/win32/time.c b/win32/time.c index 57db914e6a8f6..ac1abbc9e9c7b 100644 --- a/win32/time.c +++ b/win32/time.c @@ -23,7 +23,7 @@ #include #include "php_win32_globals.h" -static zend_always_inline int getfilesystemtime(struct timeval *tv) +static zend_always_inline void getfilesystemtime(struct timeval *tv) {/*{{{*/ FILETIME ft; unsigned __int64 ff = 0; @@ -31,7 +31,7 @@ static zend_always_inline int getfilesystemtime(struct timeval *tv) GetSystemTimePreciseAsFileTime(&ft); - /* + /* * Do not cast a pointer to a FILETIME structure to either a * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows. * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx @@ -45,8 +45,6 @@ static zend_always_inline int getfilesystemtime(struct timeval *tv) tv->tv_sec = (long)(ff / 1000000Ui64); tv->tv_usec = (long)(ff % 1000000Ui64); - - return 0; }/*}}}*/ PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) From 809389349635a0b0f223b19d86d9997cbe160bb9 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 14 Aug 2024 20:20:11 +0100 Subject: [PATCH 029/280] ext/dba: Remove arg num check prior to ZPP checks (#15401) --- ext/dba/dba.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/dba/dba.c b/ext/dba/dba.c index b1876f75f345e..6f4f78de7a61e 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -1103,9 +1103,6 @@ PHP_FUNCTION(dba_key_split) char *key, *name; size_t key_len; - if (ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &zkey) == SUCCESS) { if (Z_TYPE_P(zkey) == IS_NULL || (Z_TYPE_P(zkey) == IS_FALSE)) { php_error_docref(NULL, E_DEPRECATED, "Passing false or null is deprecated since 8.4"); From bca18bc585d2662bcdc6e3ea0e0dfa3d6dfb753a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 21:38:36 +0200 Subject: [PATCH 030/280] Autotools: Sync CS in sapi/litespeed (#15409) - AS_CASE macro used --- sapi/litespeed/config.m4 | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4 index db201300cc8a6..bb226e7482cfa 100644 --- a/sapi/litespeed/config.m4 +++ b/sapi/litespeed/config.m4 @@ -10,18 +10,16 @@ if test "$PHP_LITESPEED" != "no"; then [sapi/litespeed]) SAPI_LITESPEED_PATH=sapi/litespeed/php PHP_SELECT_SAPI([litespeed], [program], [lsapi_main.c lsapilib.c]) - case $host_alias in - *darwin*) - BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - *cygwin*) - SAPI_LITESPEED_PATH=sapi/litespeed/php.exe - 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) --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 + AS_CASE([$host_alias], + [*darwin*], [ + BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + ], + [*cygwin*], [ + SAPI_LITESPEED_PATH=sapi/litespeed/php.exe + 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) --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)" + ]) PHP_SUBST([SAPI_LITESPEED_PATH]) PHP_SUBST([BUILD_LITESPEED]) From f09354e5d06c8bb56b1b8cfd7c561d03d53814cf Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 14 Aug 2024 21:39:19 +0200 Subject: [PATCH 031/280] Autotools: Sync CS in sapi/cli (#15410) - AS_* macros used --- sapi/cli/config.m4 | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index 5b81106064f9e..76c2d64e8c8a3 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -35,21 +35,19 @@ if test "$PHP_CLI" != "no"; then [php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c], [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) - 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) --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) --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) --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 + AS_CASE([$host_alias], + [*aix*], [ + AS_VAR_IF([php_sapi_module], [shared], [ + 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)" + ], [ + 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)" + ]) + ], + [*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) --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)" + ]) dnl Set executable for tests. PHP_EXECUTABLE="\$(top_builddir)/\$(SAPI_CLI_PATH)" From 9a70b7c221df1ce83bf78306af76efee6b38f2e4 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Wed, 14 Aug 2024 17:30:20 -0300 Subject: [PATCH 032/280] [ci skip] Update NEWS for PHP 8.4.0 beta2 --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a71c9967b0ff6..167442bafb178 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.4.0beta2 +?? ??? ????, PHP 8.4.0beta3 + + +15 Aug 2024, PHP 8.4.0beta2 - Core: . Exiting a namespace now clears seen symbols. (ilutov) From d5d537bf7c50be80b4db5b17bc3643d6c1c940ad Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Wed, 14 Aug 2024 18:05:43 -0300 Subject: [PATCH 033/280] [ci skip] Update NEWS for PHP 8.4.0 beta3 Skipping beta2 due to a release issue. --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 167442bafb178..e21730dc917cd 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.4.0beta3 +?? ??? ????, PHP 8.4.0beta4 -15 Aug 2024, PHP 8.4.0beta2 +15 Aug 2024, PHP 8.4.0beta3 - Core: . Exiting a namespace now clears seen symbols. (ilutov) From 4a4aae540b161230c0dfc808503d6d0a7e789ef8 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Thu, 15 Aug 2024 00:08:10 +0200 Subject: [PATCH 034/280] Zend/zend_object_handlers.c: Remove unused include --- Zend/zend_object_handlers.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index b365189a11dd5..4c096d26b1b7b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -31,7 +31,6 @@ #include "zend_compile.h" #include "zend_hash.h" #include "zend_property_hooks.h" -#include "ext/reflection/php_reflection.h" #define DEBUG_OBJECT_HANDLERS 0 From 04320d2fba9a1ea2fb51779d5d6b8b8098417b3f Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Thu, 15 Aug 2024 01:02:33 +0200 Subject: [PATCH 035/280] ext/phar: Use standard C types --- ext/phar/phar_object.c | 2 +- ext/phar/util.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 9d16512ec5d13..688e3981e67d9 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3036,7 +3036,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - phar_obj->archive->sig_flags = (php_uint32)algo; + phar_obj->archive->sig_flags = (uint32_t)algo; phar_obj->archive->is_modified = 1; PHAR_G(openssl_privatekey) = key; PHAR_G(openssl_privatekey_len) = key_len; diff --git a/ext/phar/util.c b/ext/phar/util.c index aed95e635dd8c..d5a574cfd2ccb 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -34,7 +34,7 @@ #include #include #else -static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type); +static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); #endif /* for links to relative location, prepend cwd of the entry */ @@ -1382,7 +1382,7 @@ static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* }}} */ #ifndef PHAR_HAVE_OPENSSL -static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type) /* {{{ */ +static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ { zend_fcall_info fci; zend_fcall_info_cache fcc; From 4b2dc586518cc603d5453d2568eb693965a62d63 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 15 Aug 2024 10:59:10 +0200 Subject: [PATCH 036/280] Fix format specifiers and arguments in com_dotnet (GH-15398) This is mostly about minor glitches (signedness or length confusion), but also fixes two occasions where `zend_string`s still have been regarded as `char *`. We also add a regression test case for failing property name lookup, since that is the most relevant issue we're fixing here. --- ext/com_dotnet/com_com.c | 4 ++-- ext/com_dotnet/com_dotnet.c | 8 ++++---- ext/com_dotnet/com_typeinfo.c | 2 +- ext/com_dotnet/com_wrapper.c | 18 +++++++++--------- ext/com_dotnet/tests/lookup_error.phpt | 15 +++++++++++++++ 5 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 ext/com_dotnet/tests/lookup_error.phpt diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index 24063c5c550b7..fd2d1ee9a4394 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -392,7 +392,7 @@ HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, default: desc = php_win32_error_to_msg(hr); - spprintf(&msg, 0, "Error [0x%08x] %s", hr, desc); + spprintf(&msg, 0, "Error [0x%08lx] %s", hr, desc); php_win32_error_msg_free(desc); break; } @@ -639,7 +639,7 @@ zend_result php_com_do_invoke(php_com_dotnet_object *obj, zend_string *name, if (FAILED(hr)) { char *winerr = php_win32_error_to_msg(hr); - spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr); + spprintf(&msg, 0, "Unable to lookup `%s': %s", ZSTR_VAL(name), winerr); php_win32_error_msg_free(winerr); php_com_throw_exception(hr, msg); efree(msg); diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index 1b479a2d34de3..f52554fb3d87a 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -245,7 +245,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to init .Net runtime [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to init .Net runtime [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); RETURN_THROWS(); @@ -258,7 +258,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); @@ -270,7 +270,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); @@ -344,7 +344,7 @@ PHP_METHOD(dotnet, __construct) if (ret == FAILURE) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to instantiate .Net object [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to instantiate .Net object [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); RETURN_THROWS(); diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index f5094942914f7..4f6a3309b8cd5 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -543,7 +543,7 @@ bool php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, bool p /* first element is the function name */ SysFreeString(names[0]); - php_printf("\t/* DISPID=%d */\n", func->memid); + php_printf("\t/* DISPID=%ld */\n", func->memid); if (func->elemdescFunc.tdesc.vt != VT_VOID) { php_printf("\t/* %s [%d] */\n", diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 3b19d89cf705d..e505dc654026f 100644 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -53,7 +53,7 @@ static inline void trace(char *fmt, ...) va_list ap; char buf[4096]; - snprintf(buf, sizeof(buf), "T=%08x ", GetCurrentThreadId()); + snprintf(buf, sizeof(buf), "T=%08lx ", GetCurrentThreadId()); OutputDebugString(buf); va_start(ap, fmt); @@ -70,7 +70,7 @@ static inline void trace(char *fmt, ...) if (COMG(rshutdown_started)) { \ trace(" PHP Object:%p (name:unknown) %s\n", Z_OBJ(disp->object), methname); \ } else { \ - trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val, methname); \ + trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), ZSTR_VAL(Z_OBJCE(disp->object)->name), methname); \ } \ if (GetCurrentThreadId() != disp->engine_thread) { \ return RPC_E_WRONG_THREAD; \ @@ -109,7 +109,7 @@ static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This) FETCH_DISP("Release"); ret = InterlockedDecrement(&disp->refcount); - trace("-- refcount now %d\n", ret); + trace("-- refcount now %lu\n", ret); if (ret == 0) { /* destroy it */ disp_destructor(disp); @@ -201,7 +201,7 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( name = php_com_olestring_to_string(bstrName, COMG(code_page)); - trace("Looking for %s, namelen=%d in %p\n", ZSTR_VAL(name), ZSTR_LEN(name), disp->name_to_dispid); + trace("Looking for %s, namelen=%lu in %p\n", ZSTR_VAL(name), ZSTR_LEN(name), disp->name_to_dispid); /* Lookup the name in the hash */ if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { @@ -235,7 +235,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { /* TODO: add support for overloaded objects */ - trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); + trace("-- Invoke: %ld %20s [%lu] flags=%08x args=%u\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); /* convert args into zvals. * Args are in reverse order */ @@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( arg = &pdp->rgvarg[ pdp->cArgs - 1 - i]; - trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg)); + trace("alloc zval for arg %u VT=%08x\n", i, V_VT(arg)); php_com_wrap_variant(¶ms[i], arg, COMG(code_page)); } @@ -275,7 +275,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( VARIANT *srcvar = &obj->v; VARIANT *dstvar = &pdp->rgvarg[ pdp->cArgs - 1 - i]; if ((V_VT(dstvar) & VT_BYREF) && obj->modified ) { - trace("percolate modified value for arg %d VT=%08x\n", i, V_VT(dstvar)); + trace("percolate modified value for arg %u VT=%08x\n", i, V_VT(dstvar)); php_com_copy_variant(dstvar, srcvar); } } @@ -311,7 +311,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( } } else { - trace("InvokeEx: I don't support DISPID=%d\n", id); + trace("InvokeEx: I don't support DISPID=%ld\n", id); } return ret; @@ -508,7 +508,7 @@ static php_dispatchex *disp_constructor(zval *object) { php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex)); - trace("constructing a COM wrapper for PHP object %p (%s)\n", object, Z_OBJCE_P(object)->name); + trace("constructing a COM wrapper for PHP object %p (%s)\n", object, ZSTR_VAL(Z_OBJCE_P(object)->name)); if (disp == NULL) return NULL; diff --git a/ext/com_dotnet/tests/lookup_error.phpt b/ext/com_dotnet/tests/lookup_error.phpt new file mode 100644 index 0000000000000..beb276eb8d99b --- /dev/null +++ b/ext/com_dotnet/tests/lookup_error.phpt @@ -0,0 +1,15 @@ +--TEST-- +Property name lookup error +--EXTENSIONS-- +com_dotnet +--FILE-- +unknownProperty; +} catch (com_exception $ex) { + echo $ex->getMessage(), "\n"; +} +?> +--EXPECTF-- +Unable to lookup `unknownProperty': %s From 1e4ed4adaac6cc0f97c8b24e62d4d9fa4685b3de Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 15 Aug 2024 11:38:34 +0200 Subject: [PATCH 037/280] Autotools: Sync CS in sapi/fuzzer (#15417) - AS_VAR_IF macro used - redundant quotes removed - PHP_FUZZER_TARGET macro body synced with the rest of the macros in php-src - PHP_FUZZER_TARGET arguments quoted --- sapi/fuzzer/config.m4 | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/sapi/fuzzer/config.m4 b/sapi/fuzzer/config.m4 index c948d37067d50..21a44cd6d886e 100644 --- a/sapi/fuzzer/config.m4 +++ b/sapi/fuzzer/config.m4 @@ -8,13 +8,15 @@ PHP_ARG_ENABLE([fuzzer], dnl For newer Clang versions see https://llvm.org/docs/LibFuzzer.html#fuzzer-usage dnl for relevant flags. -dnl Macro to define fuzzing target +dnl dnl PHP_FUZZER_TARGET(name, target-var) dnl +dnl Macro to define the fuzzing target. +dnl AC_DEFUN([PHP_FUZZER_TARGET], [ PHP_FUZZER_BINARIES="$PHP_FUZZER_BINARIES $SAPI_FUZZER_PATH/php-fuzz-$1" PHP_SUBST([$2]) - PHP_ADD_SOURCES_X([sapi/fuzzer],[fuzzer-$1.c],[],$2) + PHP_ADD_SOURCES_X([sapi/fuzzer], [fuzzer-$1.c], [], [$2]) $2="[$]$2 $FUZZER_COMMON_OBJS" ]) @@ -30,19 +32,18 @@ if test "$PHP_FUZZER" != "no"; then PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/fuzzer/Makefile.frag]) SAPI_FUZZER_PATH=sapi/fuzzer PHP_SUBST([SAPI_FUZZER_PATH]) - if test -z "$LIB_FUZZING_ENGINE"; then + AS_VAR_IF([LIB_FUZZING_ENGINE],, [ FUZZING_LIB="-fsanitize=fuzzer" - FUZZING_CC="$CC" + FUZZING_CC=$CC AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link], [ CFLAGS="$CFLAGS -fsanitize=fuzzer-no-link" CXXFLAGS="$CXXFLAGS -fsanitize=fuzzer-no-link" - ],[ - AC_MSG_ERROR([Compiler doesn't support -fsanitize=fuzzer-no-link]) - ]) - else - FUZZING_LIB="$LIB_FUZZING_ENGINE" + ], + [AC_MSG_ERROR([Compiler doesn't support -fsanitize=fuzzer-no-link])]) + ], [ + FUZZING_LIB=$LIB_FUZZING_ENGINE FUZZING_CC="$CXX -stdlib=libc++" - fi + ]) PHP_SUBST([FUZZING_LIB]) PHP_SUBST([FUZZING_CC]) @@ -55,21 +56,21 @@ if test "$PHP_FUZZER" != "no"; then PHP_ADD_SOURCES_X([sapi/fuzzer], [fuzzer-sapi.c], [], [FUZZER_COMMON_OBJS]) - PHP_FUZZER_TARGET([parser], PHP_FUZZER_PARSER_OBJS) - PHP_FUZZER_TARGET([execute], PHP_FUZZER_EXECUTE_OBJS) - PHP_FUZZER_TARGET([function-jit], PHP_FUZZER_FUNCTION_JIT_OBJS) - PHP_FUZZER_TARGET([tracing-jit], PHP_FUZZER_TRACING_JIT_OBJS) - PHP_FUZZER_TARGET([unserialize], PHP_FUZZER_UNSERIALIZE_OBJS) - PHP_FUZZER_TARGET([unserializehash], PHP_FUZZER_UNSERIALIZEHASH_OBJS) - PHP_FUZZER_TARGET([json], PHP_FUZZER_JSON_OBJS) + PHP_FUZZER_TARGET([parser], [PHP_FUZZER_PARSER_OBJS]) + PHP_FUZZER_TARGET([execute], [PHP_FUZZER_EXECUTE_OBJS]) + PHP_FUZZER_TARGET([function-jit], [PHP_FUZZER_FUNCTION_JIT_OBJS]) + PHP_FUZZER_TARGET([tracing-jit], [PHP_FUZZER_TRACING_JIT_OBJS]) + PHP_FUZZER_TARGET([unserialize], [PHP_FUZZER_UNSERIALIZE_OBJS]) + PHP_FUZZER_TARGET([unserializehash], [PHP_FUZZER_UNSERIALIZEHASH_OBJS]) + PHP_FUZZER_TARGET([json], [PHP_FUZZER_JSON_OBJS]) if test -n "$enable_exif" && test "$enable_exif" != "no"; then - PHP_FUZZER_TARGET([exif], PHP_FUZZER_EXIF_OBJS) + PHP_FUZZER_TARGET([exif], [PHP_FUZZER_EXIF_OBJS]) fi if test -n "$enable_mbstring" && test "$enable_mbstring" != "no"; then - PHP_FUZZER_TARGET([mbstring], PHP_FUZZER_MBSTRING_OBJS) + PHP_FUZZER_TARGET([mbstring], [PHP_FUZZER_MBSTRING_OBJS]) if test -n "$enable_mbregex" && test "$enable_mbregex" != "no"; then - PHP_FUZZER_TARGET([mbregex], PHP_FUZZER_MBREGEX_OBJS) + PHP_FUZZER_TARGET([mbregex], [PHP_FUZZER_MBREGEX_OBJS]) fi fi From 4f4794b12dc73853093d076794a1fda8113eb692 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 15 Aug 2024 11:39:09 +0200 Subject: [PATCH 038/280] Autotools: Sync CS in fpm SAPI (#15412) - AS_* macros used - obsolete backticks replaced with $(...) - redundant double quotes removed --- sapi/fpm/config.m4 | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 97138280c0708..8277cd518b3e1 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -486,24 +486,24 @@ if test "$PHP_FPM" != "no"; then ]) if test -z "$PHP_FPM_USER" || test "$PHP_FPM_USER" = "yes" || test "$PHP_FPM_USER" = "no"; then - php_fpm_user="nobody" + php_fpm_user=nobody else - php_fpm_user="$PHP_FPM_USER" + php_fpm_user=$PHP_FPM_USER fi if test -z "$PHP_FPM_GROUP" || test "$PHP_FPM_GROUP" = "yes" || test "$PHP_FPM_GROUP" = "no"; then - php_fpm_group="nobody" + php_fpm_group=nobody else - php_fpm_group="$PHP_FPM_GROUP" + php_fpm_group=$PHP_FPM_GROUP fi AC_SUBST([php_fpm_user]) AC_SUBST([php_fpm_group]) - php_fpm_sysconfdir=`eval echo $sysconfdir` + php_fpm_sysconfdir=$(eval echo $sysconfdir) AC_SUBST([php_fpm_sysconfdir]) - php_fpm_localstatedir=`eval echo $localstatedir` + php_fpm_localstatedir=$(eval echo $localstatedir) AC_SUBST([php_fpm_localstatedir]) - php_fpm_prefix=`eval echo $prefix` + php_fpm_prefix=$(eval echo $prefix) AC_SUBST([php_fpm_prefix]) PHP_ADD_BUILD_DIR([sapi/fpm/fpm]) @@ -560,17 +560,15 @@ if test "$PHP_FPM" != "no"; then [$PHP_FPM_FILES $PHP_FPM_TRACE_FILES $PHP_FPM_SD_FILES], [$PHP_FPM_CFLAGS]) - 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) --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) --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 + AS_CASE([$host_alias], + [*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) --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) --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)" + ]) PHP_SUBST([SAPI_FPM_PATH]) PHP_SUBST([BUILD_FPM]) From 794ba29a57e2532eb362139cd280053dee3eb371 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 15 Aug 2024 11:42:47 +0200 Subject: [PATCH 039/280] Autotools: Fix PHP_EMBED_TYPE variable substitution (#15414) This is a follow-up of f6dcca00bc94fe1734dea67e31add7d8a949a9df as Autoconf always seems to do a variable substitution, even when called conditionally. When passing argument other than shared or static to --enable-embed=ARGUMENT this now puts an empty string inside generated php-config script. --- sapi/embed/config.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index 7029f94c7137e..c385e289a70ee 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -19,9 +19,10 @@ if test "$PHP_EMBED" != "no"; then PHP_EMBED_TYPE=static INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0644 $SAPI_STATIC \$(INSTALL_ROOT)\$(orig_libdir)" ], - [PHP_EMBED_TYPE=no]) + [PHP_EMBED_TYPE=]) - AS_VAR_IF([PHP_EMBED_TYPE], [no],, [ + AS_VAR_IF([PHP_EMBED_TYPE],, [AC_MSG_RESULT([no])], [ + AC_MSG_RESULT([$PHP_EMBED_TYPE]) PHP_SUBST([LIBPHP_CFLAGS]) AC_SUBST([PHP_EMBED_TYPE]) PHP_SELECT_SAPI([embed], @@ -30,7 +31,6 @@ if test "$PHP_EMBED" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_INSTALL_HEADERS([sapi/embed], [php_embed.h]) ]) - AC_MSG_RESULT([$PHP_EMBED_TYPE]) else AC_MSG_RESULT([no]) fi From 21fa5e15f9829ef5dfbd67a02d29d0fef3951cc0 Mon Sep 17 00:00:00 2001 From: Jorg Adam Sowa Date: Thu, 15 Aug 2024 12:10:18 +0200 Subject: [PATCH 040/280] ext/session: session_create_id() now throws a ValueError for large prefix (#15338) --- ext/session/session.c | 4 ++++ .../session_create_id_invalid_prefix.phpt | 21 ++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index aa9883ab1df33..32de7c36d7813 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2383,6 +2383,10 @@ PHP_FUNCTION(session_create_id) } if (prefix && ZSTR_LEN(prefix)) { + if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { + zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); + RETURN_THROWS(); + } if (php_session_valid_key(ZSTR_VAL(prefix)) == FAILURE) { /* E_ERROR raised for security reason. */ php_error_docref(NULL, E_WARNING, "Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, \"-\", and \",\" characters are allowed"); diff --git a/ext/session/tests/session_create_id_invalid_prefix.phpt b/ext/session/tests/session_create_id_invalid_prefix.phpt index 0a4e2c2d40013..7de7e8061f689 100644 --- a/ext/session/tests/session_create_id_invalid_prefix.phpt +++ b/ext/session/tests/session_create_id_invalid_prefix.phpt @@ -12,8 +12,18 @@ session var_dump(session_create_id('_')); var_dump(session_create_id('%')); -var_dump(session_create_id("AB\0CD")); +try { + var_dump(session_create_id('ABTgdPs68S3M4HMaqKwj33TzqLMv5PHpWQxJbfpeogEhrJRY7o9f33pKLCmhf0tXCtoBkIu0yxXYCSHfJhPd2miPUW4MIpd91dnEiOwWDfaBnfdJZOwgvgmYLSfDGaebqmnCAoyuzlcq2j59nNRhccgJIkr9ytY3RwFTTXszpcjpx6mlJuG9GksKAhPsnnaEwSEb0eFyqvn80gYI2roKSjaFSmJxg0xgXuCF4csMo8DxiSvovho5QTKx5u7h8VyQL')); +} catch (Throwable $e) { + echo $e::class . ': ' . $e->getMessage() . "\n"; +} + +try { + var_dump(session_create_id("AB\0CD")); +} catch (Throwable $e) { + echo $e::class . ': ' . $e->getMessage() . "\n"; +} ?> Done @@ -23,9 +33,6 @@ bool(false) Warning: session_create_id(): Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in %s on line %d bool(false) - -Fatal error: Uncaught ValueError: session_create_id(): Argument #1 ($prefix) must not contain any null bytes in %s:%d -Stack trace: -#0 %s(5): session_create_id('AB\x00CD') -#1 {main} - thrown in %s +ValueError: session_create_id(): Argument #1 ($prefix) cannot be longer than 256 characters +ValueError: session_create_id(): Argument #1 ($prefix) must not contain any null bytes +Done From 3e226af533083ce47a46f05feb748cc7876f7e0c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 15 Aug 2024 11:12:04 +0100 Subject: [PATCH 041/280] ext/opcache/ZendAccelerator.c: Restrict MD5 header include to Windows (#15418) As it is only ever used in accel_gen_uname_id() which is Windows only --- ext/opcache/ZendAccelerator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 0bd55d319e31e..f9514d4807c4e 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -47,10 +47,11 @@ #include "zend_accelerator_hash.h" #include "zend_file_cache.h" #include "ext/pcre/php_pcre.h" -#include "ext/standard/md5.h" +#include "ext/standard/basic_functions.h" #ifdef ZEND_WIN32 # include "ext/hash/php_hash.h" +# include "ext/standard/md5.h" #endif #ifdef HAVE_JIT From a6b7f134a90aece2c025121fe1c9c8a9f7cf1c9f Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 15 Aug 2024 12:13:32 +0200 Subject: [PATCH 042/280] exit_as_funtion RFC follow-up: ensure default INI settings used in status test (#15420) --- Zend/tests/exit/exit_values.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/tests/exit/exit_values.phpt b/Zend/tests/exit/exit_values.phpt index e081193b94cd2..7b774a961c7e9 100644 --- a/Zend/tests/exit/exit_values.phpt +++ b/Zend/tests/exit/exit_values.phpt @@ -49,7 +49,7 @@ try { TEMPLATE; $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -$command = $php . ' ' . escapeshellarg(FILE_PATH); +$command = $php . ' --no-php-ini ' . escapeshellarg(FILE_PATH); foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) { foreach ($values as $value) { From b0ac9bf669d20ae211cc3e004060c1d7fa1e4f37 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 15 Aug 2024 14:30:23 +0200 Subject: [PATCH 043/280] Explicitly drop support for old clang versions on Windows (GH-15415) * Explicitly drop support for old clang versions on Windows This ensures compatibility with the typedef redefinitions we use, and makes it clear during the `configure` stage that old compiler versions are not supported. See regarding the release history of clang. We also remove support for two number versions of clang, since as of LLVM 4.0.0 the project uses a three number versioning scheme; see . --- win32/build/confutils.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win32/build/confutils.js b/win32/build/confutils.js index b72950954c0f7..78d4291f2feed 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3073,8 +3073,9 @@ function toolset_get_compiler_version() if (full.match(/clang version ([\d\.]+)/)) { version = RegExp.$1; version = version.replace(/\./g, ''); - version = version/100 < 1 ? version*10 : version; - + if (version < 400) { + ERROR("Building with clang " + version + " is no longer supported"); + } return version; } } else if (ICC_TOOLSET) { From 8853cf3ae950a1658054f286117bc8f77f724f00 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 15 Aug 2024 16:40:23 +0200 Subject: [PATCH 044/280] Autotools: Add note about PHP_ADD_EXTENSION_DEP usage Until the AWK regex is implemented better, this macro must be called on its own line with unquoted arguments. [skip ci] --- build/php.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/php.m4 b/build/php.m4 index dc92e56f2140b..3d1b6b1f2516f 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -986,7 +986,10 @@ dnl $1 = name of extension, $2 = extension upon which it depends dnl $3 = optional: if true, it's ok for $2 to have not been configured default dnl is false and should halt the build. To be effective, this macro must be dnl invoked *after* PHP_NEW_EXTENSION. The extension on which it depends must -dnl also have been configured. See ADD_EXTENSION_DEP in win32 build. +dnl also have been configured. Due to the limited genif.sh parsing and regex +dnl matching implementation, this macro must be called on its own line, and its +dnl arguments must be passed unquoted (without Autoconf '[' and ']' characters. +dnl For Windows, see 'ADD_EXTENSION_DEP' in the win32 build. dnl AC_DEFUN([PHP_ADD_EXTENSION_DEP], [ am_i_shared=$[PHP_]translit($1,a-z_-,A-Z__)[_SHARED] From d6afe053807b720792665a4b212edf17f8fdc1a4 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 01:18:25 +0900 Subject: [PATCH 045/280] libtool: Don't remove gcov *.gcno files (#15441) The libtool bundled with PHP is outdated and deletes *.gcno files used by gcov during the build process. While this issue has already been resolved upstream [1], incorporating the fix at this point may not be practical. Therefore, we attempt to apply a fix to the current version. This change will enable proper coverage output for third-party PHP extensions. [1]: https://github.com/autotools-mirror/libtool/blob/master/NEWS#L605 --- build/ltmain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/ltmain.sh b/build/ltmain.sh index ff1685c8a89f9..3c00e79157079 100755 --- a/build/ltmain.sh +++ b/build/ltmain.sh @@ -3467,7 +3467,7 @@ EOF tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in - *.$objext) + *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then From 24387176d0cdaf7852c2748d78b7ba915146262a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 16 Aug 2024 18:30:51 +0200 Subject: [PATCH 046/280] Autotools: Sync CS in sapi/cgi (#15407) - AS_* macros used - Indentation level synced - Obsolete backticks replaced with recommended $(...) (on shells where the "newer" style still doesn't work, for example on Solaris 10 default shell, Autoconf takes care of that by re-executing the script itself) --- sapi/cgi/config9.m4 | 96 ++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 53 deletions(-) diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4 index 31a6dc9953411..3752ffc4396a1 100644 --- a/sapi/cgi/config9.m4 +++ b/sapi/cgi/config9.m4 @@ -6,57 +6,47 @@ PHP_ARG_ENABLE([cgi], [no]) if test "$PHP_CGI" != "no"; then - dnl BSD systems. - AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[#include ]) - - AC_MSG_CHECKING([whether cross-process locking is required by accept()]) - case "`uname -sr`" in - SunOS\ 5.*) - AC_MSG_RESULT([yes]) - AC_DEFINE([USE_LOCKING], [1], - [Define to 1 if cross-process locking is required by 'accept()'.]) - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac - - PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/cgi/Makefile.frag]) - - dnl Set filename. - case $host_alias in - *cygwin* ) - SAPI_CGI_PATH=sapi/cgi/php-cgi.exe - ;; - * ) - SAPI_CGI_PATH=sapi/cgi/php-cgi - ;; - esac - - dnl Select SAPI. - PHP_SELECT_SAPI([cgi], - [program], - [cgi_main.c], - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) - - case $host_alias in - *aix*) - if test "$php_sapi_module" = "shared"; then - 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) --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) --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 - - PHP_SUBST([SAPI_CGI_PATH]) - PHP_SUBST([BUILD_CGI]) - - AC_CONFIG_FILES([sapi/cgi/php-cgi.1]) + dnl BSD systems. + AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[#include ]) + + AC_MSG_CHECKING([whether cross-process locking is required by accept()]) + AS_CASE([$(uname -sr)], + [SunOS\ 5.*], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([USE_LOCKING], [1], + [Define to 1 if cross-process locking is required by 'accept()'.]) + ], + [AC_MSG_RESULT([no])]) + + PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/cgi/Makefile.frag]) + + dnl Set filename. + AS_CASE([$host_alias], + [*cygwin*], [SAPI_CGI_PATH=sapi/cgi/php-cgi.exe], + [SAPI_CGI_PATH=sapi/cgi/php-cgi]) + + dnl Select SAPI. + PHP_SELECT_SAPI([cgi], + [program], + [cgi_main.c], + [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + + AS_CASE([$host_alias], + [*aix*], [ + AS_VAR_IF([php_sapi_module], [shared], [ + 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)" + ], [ + 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)" + ]) + ], + [*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) --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)" + ]) + + PHP_SUBST([SAPI_CGI_PATH]) + PHP_SUBST([BUILD_CGI]) + + AC_CONFIG_FILES([sapi/cgi/php-cgi.1]) fi From 173965331c6b60ac09db42b19bf61547b3290f86 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 16 Aug 2024 18:32:13 +0200 Subject: [PATCH 047/280] Autotools: Use AS_* macros in apache2handler SAPI (#15423) --- sapi/apache2handler/config.m4 | 78 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index 9012d472b19c3..a705f0b3acc26 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -7,15 +7,14 @@ PHP_ARG_WITH([apxs2], [no]) if test "$PHP_APXS2" != "no"; then - if test "$PHP_APXS2" = "yes"; then + AS_VAR_IF([PHP_APXS2], [yes], [ APXS=apxs $APXS -q CFLAGS >/dev/null 2>&1 if test "$?" != "0" && test -x /usr/sbin/apxs; then APXS=/usr/sbin/apxs fi - else - PHP_EXPAND_PATH([$PHP_APXS2], [APXS]) - fi + ], + [PHP_EXPAND_PATH([$PHP_APXS2], [APXS])]) $APXS -q CFLAGS >/dev/null 2>&1 if test "$?" != "0"; then @@ -53,9 +52,7 @@ if test "$PHP_APXS2" != "no"; then APU_CFLAGS="`$APU_CONFIG --includes`" for flag in $APXS_CFLAGS; do - case $flag in - -D*) APACHE_CPPFLAGS="$APACHE_CPPFLAGS $flag";; - esac + AS_CASE([$flag], [-D*], [APACHE_CPPFLAGS="$APACHE_CPPFLAGS $flag"]) done APACHE_CFLAGS="$APACHE_CPPFLAGS -I$APXS_INCLUDEDIR $APR_CFLAGS $APU_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" @@ -82,42 +79,41 @@ if test "$PHP_APXS2" != "no"; then LIBPHP_CFLAGS="-shared" PHP_SUBST([LIBPHP_CFLAGS]) - case $host_alias in - *aix*) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-brtl -Wl,-bI:$APXS_LIBEXECDIR/httpd.exp" - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" - ;; - *darwin*) - dnl When using bundles on Darwin, we must resolve all symbols. However, the - dnl linker does not recursively look at the bundle loader and pull in its - dnl dependencies. Therefore, we must pull in the APR and APR-util libraries. - if test -x "$APR_CONFIG"; then + AS_CASE([$host_alias], + [*aix*], [ + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-brtl -Wl,-bI:$APXS_LIBEXECDIR/httpd.exp" + PHP_SELECT_SAPI([apache2handler], + [shared], + [mod_php.c sapi_apache2.c apache_config.c php_functions.c], + [$APACHE_CFLAGS]) + INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" + ], + [*darwin*], [ + dnl When using bundles on Darwin, we must resolve all symbols. However, + dnl the linker does not recursively look at the bundle loader and pull in + dnl its dependencies. Therefore, we must pull in the APR and APR-util + dnl libraries. + if test -x "$APR_CONFIG"; then MH_BUNDLE_FLAGS="`$APR_CONFIG --ldflags --link-ld --libs`" - fi - if test -x "$APU_CONFIG"; then + fi + if test -x "$APU_CONFIG"; then MH_BUNDLE_FLAGS="`$APU_CONFIG --ldflags --link-ld --libs` $MH_BUNDLE_FLAGS" - fi - MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" - PHP_SUBST([MH_BUNDLE_FLAGS]) - PHP_SELECT_SAPI([apache2handler], - [bundle], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - SAPI_SHARED=libs/libphp.so - INSTALL_IT="$INSTALL_IT $SAPI_SHARED" - ;; - *) - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" - ;; - esac + fi + MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" + PHP_SUBST([MH_BUNDLE_FLAGS]) + PHP_SELECT_SAPI([apache2handler], + [bundle], + [mod_php.c sapi_apache2.c apache_config.c php_functions.c], + [$APACHE_CFLAGS]) + SAPI_SHARED=libs/libphp.so + INSTALL_IT="$INSTALL_IT $SAPI_SHARED" + ], [ + PHP_SELECT_SAPI([apache2handler], + [shared], + [mod_php.c sapi_apache2.c apache_config.c php_functions.c], + [$APACHE_CFLAGS]) + INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" + ]) AS_IF([$APXS_HTTPD -V 2>/dev/null | grep 'threaded:.*yes' >/dev/null 2>&1], [ APACHE_THREADED_MPM=yes From 80825672d11a03a08915b9a9d63199347751c4e0 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 16 Aug 2024 19:21:13 +0200 Subject: [PATCH 048/280] Autotools: Fix external PCRE JIT check (#15430) If using a custom PCRE library installation, also CFLAGS and LIBS variables need to be adapted for the JIT check to be able to find it. --- ext/pcre/config0.m4 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 3b13ad5400560..7c2a8460cc5d1 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -28,7 +28,12 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then AS_VAR_IF([PHP_PCRE_JIT], [no],, [AC_CACHE_CHECK([whether external PCRE2 library has JIT supported], [php_cv_have_pcre2_jit], - [AC_RUN_IFELSE([AC_LANG_SOURCE([ + [ + CFLAGS_SAVE=$CFLAGS + LIBS_SAVE=$LIBS + CFLAGS="$CFLAGS $PCRE2_CFLAGS" + LIBS="$LIBS $PCRE2_LIBS" + AC_RUN_IFELSE([AC_LANG_SOURCE([ #include #include int main(void) { @@ -42,7 +47,10 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then [AS_CASE([$host_cpu], [arm*|i[[34567]]86|x86_64|mips*|powerpc*|sparc], [php_cv_have_pcre2_jit=yes], - [php_cv_have_pcre2_jit=no])])]) + [php_cv_have_pcre2_jit=no])]) + CFLAGS=$CFLAGS_SAVE + LIBS=$LIBS_SAVE + ]) AS_VAR_IF([php_cv_have_pcre2_jit], [yes], [AC_DEFINE([HAVE_PCRE_JIT_SUPPORT], [1])]) ]) From ec9cdcd2bc71d3995be3679d2d21f39c2e17b03d Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 02:54:03 +0900 Subject: [PATCH 049/280] Fix MSan false-positive in zend_max_execution_timer (#15408) Explicitly mark memory regions as unpoisoned for zend_max_execution_timer on ZTS, as MemorySanitizer in clang >= 18 causes false positives. --- Zend/zend_max_execution_timer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index f9f9740fd8a00..6ab2c0892c038 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -24,6 +24,10 @@ #include #include +#if __has_feature(memory_sanitizer) +# include +#endif + #include "zend.h" #include "zend_globals.h" @@ -47,6 +51,12 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ sev.sigev_signo = SIGRTMIN; sev.sigev_notify_thread_id = (pid_t) syscall(SYS_gettid); +#if __has_feature(memory_sanitizer) + /* MSan does not intercept timer_create() */ + __msan_unpoison(&EG(max_execution_timer_timer), + sizeof(EG(max_execution_timer_timer))); +#endif + // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 if (timer_create(CLOCK_BOOTTIME, &sev, &EG(max_execution_timer_timer)) != 0) { zend_strerror_noreturn(E_ERROR, errno, "Could not create timer"); From ad998356dd0d0f1c75a8327b6b556a03f93b6e59 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 02:57:42 +0900 Subject: [PATCH 050/280] [ci skip] Update NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 890e67592cc62..6017bc1f98017 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.24 +- Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) 29 Aug 2024, PHP 8.2.23 From 140a257f2f6faad2442b857635a9865f9e4d14f8 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 02:58:25 +0900 Subject: [PATCH 051/280] [ci skip] Update NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 769977deb7f91..26d9657c924f3 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP-8.3.12 +- Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) 15 Aug 2024, PHP 8.3.11 From 14390a04bb4843d144a8d5165d32b51fc900f052 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 02:59:24 +0900 Subject: [PATCH 052/280] [ci skip] Update NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index e21730dc917cd..d9760d08f6403 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.0beta4 +- Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) 15 Aug 2024, PHP 8.4.0beta3 From bd843d760f13311c6f1d2dc3f008be4fadafafe0 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 03:12:32 +0900 Subject: [PATCH 053/280] [ci skip] fix NEWS --- NEWS | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 6017bc1f98017..d845ea39635f9 100644 --- a/NEWS +++ b/NEWS @@ -2,13 +2,11 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.24 -- Core: - . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). - (zeriyoshi) - 29 Aug 2024, PHP 8.2.23 - Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) . Fixed bug GH-15020 (Memory leak in Zend/Optimizer/escape_analysis.c). (nielsdos) . Fixed bug GH-15023 (Memory leak in Zend/zend_ini.c). (nielsdos) From bb0c32583af4e3d198e03ae290298d23e0fe066a Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 03:26:08 +0900 Subject: [PATCH 054/280] [ci skip] Update ext/random year for zeriyoshi in EXTENSIONS --- EXTENSIONS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXTENSIONS b/EXTENSIONS index 35f5c76f1d1dd..ec75284085b71 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -409,7 +409,7 @@ MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- EXTENSION: random -PRIMARY MAINTAINER Go Kudo (2022 - 2022) +PRIMARY MAINTAINER Go Kudo (2022 - 2024) Tim Düsterhus (2022 - 2024) MAINTENANCE: Maintained STATUS: Working From b5568a008f9303c133ed09d4ec8e17428e899afa Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Fri, 16 Aug 2024 21:47:41 +0200 Subject: [PATCH 055/280] GH-15440: adding CURLOPT_TCP_KEEPCNT constant (8.9.0) (#15446) close GH-15446 --- NEWS | 4 ++++ UPGRADING | 1 + ext/curl/curl.stub.php | 7 +++++++ ext/curl/curl_arginfo.h | 5 ++++- ext/curl/interface.c | 3 +++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d9760d08f6403..dfea4ff1a3c8b 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,10 @@ PHP NEWS As such, passing invalid types to exit/die may now result in a TypeError being thrown. (Girgias) +- CURL: + . Added CURLOPT_TCP_KEEPCNT to set the number of probes to send before + dropping the connection. (David Carlier) + - Hash: . Fix GH-15384 (Build fails on Alpine / Musl for amd64). (timwolla) diff --git a/UPGRADING b/UPGRADING index c6dd6f0b10380..6a56342a85e98 100644 --- a/UPGRADING +++ b/UPGRADING @@ -917,6 +917,7 @@ PHP 8.4 UPGRADE NOTES - Curl: . CURL_HTTP_VERSION_3. . CURL_HTTP_VERSION_3ONLY. + . CURL_TCP_KEEPCNT - Intl: . The IntlDateFormatter class exposes now the new PATTERN constant diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index 0adfb17c4d3f3..473e8b6297e98 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -407,6 +407,13 @@ * @cvalue CURLOPT_STDERR */ const CURLOPT_STDERR = UNKNOWN; +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ +/** + * @var int + * @cvalue CURLOPT_TCP_KEEPCNT + */ +const CURLOPT_TCP_KEEPCNT = UNKNOWN; +#endif /** * @var int * @cvalue CURLOPT_TELNETOPTIONS diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index 044763d57df0f..3bb825af8d146 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b5a3bd62bcb62b2e7e4aacfcd4621cc632be1564 */ + * Stub hash: ddfcdd8a0bf0ee6c338ec1689c6de5d7fd87303d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -307,6 +307,9 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_STDERR", CURLOPT_STDERR, CONST_PERSISTENT); +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ + REGISTER_LONG_CONSTANT("CURLOPT_TCP_KEEPCNT", CURLOPT_TCP_KEEPCNT, CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("CURLOPT_TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_TIMEOUT", CURLOPT_TIMEOUT, CONST_PERSISTENT); diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 994bac82f3809..8ec2ec33520ec 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1728,6 +1728,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue #if LIBCURL_VERSION_NUM >= 0x075700 /* Available since 7.87.0 */ case CURLOPT_CA_CACHE_TIMEOUT: case CURLOPT_QUICK_EXIT: +#endif +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ + case CURLOPT_TCP_KEEPCNT: #endif lval = zval_get_long(zvalue); if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) && From 836e6fa90077d2b0648eb301c3321652874380bb Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 05:20:04 +0900 Subject: [PATCH 056/280] zend_max_execution_timer: fix gcc compatibility (#15447) --- Zend/zend_max_execution_timer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 6ab2c0892c038..6cd2300d3ff43 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -24,13 +24,14 @@ #include #include +#include "zend.h" +#include "zend_globals.h" +#include "zend_portability.h" + #if __has_feature(memory_sanitizer) # include #endif -#include "zend.h" -#include "zend_globals.h" - // Musl Libc defines this macro, glibc does not // According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 # ifndef sigev_notify_thread_id @@ -53,8 +54,8 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ #if __has_feature(memory_sanitizer) /* MSan does not intercept timer_create() */ - __msan_unpoison(&EG(max_execution_timer_timer), - sizeof(EG(max_execution_timer_timer))); + __msan_unpoison(&EG(max_execution_timer_timer), + sizeof(EG(max_execution_timer_timer))); #endif // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 From 5df1b55038856f446ee2c995559b00399f5ae8ce Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Fri, 16 Aug 2024 20:26:31 +0000 Subject: [PATCH 057/280] [ci skip] fix NEWS --- NEWS | 2 -- 1 file changed, 2 deletions(-) diff --git a/NEWS b/NEWS index 8b647cfb34b49..26d9657c924f3 100644 --- a/NEWS +++ b/NEWS @@ -9,8 +9,6 @@ PHP NEWS 15 Aug 2024, PHP 8.3.11 - Core: - . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). - (zeriyoshi) . Fixed bug GH-15020 (Memory leak in Zend/Optimizer/escape_analysis.c). (nielsdos) . Fixed bug GH-15023 (Memory leak in Zend/zend_ini.c). (nielsdos) From 4c5767f62f285b5c1b8d8c1f205882b5c1508d28 Mon Sep 17 00:00:00 2001 From: Juliette <663378+jrfnl@users.noreply.github.com> Date: Fri, 16 Aug 2024 23:35:16 +0200 Subject: [PATCH 058/280] PHP 8.4 | Exit as function: fix incorrect parameter name (#15433) Follow up on 13483 As previously reported in https://github.com/php/php-src/pull/13483#discussion_r1718546927: > The parameter names seem to be incorrect. > > It should be `$status`, not `$code`. > > The RFC explicitly uses that parameter name in the proposal: https://wiki.php.net/rfc/exit-as-function#proposal > > It is also the name already used in the [manual](https://www.php.net/exit). > > Lastly, the parameter name `$status` better covers what can be passed: either a status _message_ or a status _code_. > While `$code` would read pretty weird when passing a message: > ```php > exit(code: 'message'); > ``` This commit attempts to fix this. Includes adding a test for exit/die using a named argument. Co-authored-by: jrfnl --- .../tests/exit/die_string_cast_exception.phpt | 2 +- Zend/tests/exit/exit_as_function.phpt | 4 +- Zend/tests/exit/exit_named_arg.phpt | 59 +++++++++++++++++++ Zend/tests/exit/exit_values.phpt | 20 +++---- Zend/zend_builtin_functions.c | 6 +- Zend/zend_builtin_functions.stub.php | 4 +- Zend/zend_builtin_functions_arginfo.h | 4 +- 7 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 Zend/tests/exit/exit_named_arg.phpt diff --git a/Zend/tests/exit/die_string_cast_exception.phpt b/Zend/tests/exit/die_string_cast_exception.phpt index 711b0de6322ce..c20a873939dfa 100644 --- a/Zend/tests/exit/die_string_cast_exception.phpt +++ b/Zend/tests/exit/die_string_cast_exception.phpt @@ -11,4 +11,4 @@ try { ?> --EXPECT-- -exit(): Argument #1 ($code) must be of type string|int, stdClass given +exit(): Argument #1 ($status) must be of type string|int, stdClass given diff --git a/Zend/tests/exit/exit_as_function.phpt b/Zend/tests/exit/exit_as_function.phpt index 2953fadfa6d47..fb95b9f288171 100644 --- a/Zend/tests/exit/exit_as_function.phpt +++ b/Zend/tests/exit/exit_as_function.phpt @@ -27,7 +27,7 @@ object(Closure)#1 (2) { string(4) "exit" ["parameter"]=> array(1) { - ["$code"]=> + ["$status"]=> string(10) "" } } @@ -36,7 +36,7 @@ object(Closure)#2 (2) { string(4) "exit" ["parameter"]=> array(1) { - ["$code"]=> + ["$status"]=> string(10) "" } } diff --git a/Zend/tests/exit/exit_named_arg.phpt b/Zend/tests/exit/exit_named_arg.phpt new file mode 100644 index 0000000000000..7f7d362c0bdcf --- /dev/null +++ b/Zend/tests/exit/exit_named_arg.phpt @@ -0,0 +1,59 @@ +--TEST-- +Using exit()/die() as function call with a named argument +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' --no-php-ini ' . escapeshellarg(FILE_PATH); + +foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) { + foreach ($values as $value) { + echo 'Using ', var_export($value, true), ' as value:', PHP_EOL; + $output = []; + $content = str_replace('VALUE', var_export($value, true), $code); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; + } +} + +?> +--CLEAN-- + +--EXPECT-- +Using 12 as value: +Exit status is: 12 +Output is: + +Using 'Goodbye!' as value: +Exit status is: 0 +Output is: +Goodbye! +Using 12 as value: +Exit status is: 12 +Output is: + +Using 'Goodbye!' as value: +Exit status is: 0 +Output is: +Goodbye! diff --git a/Zend/tests/exit/exit_values.phpt b/Zend/tests/exit/exit_values.phpt index 7b774a961c7e9..d3909ff156828 100644 --- a/Zend/tests/exit/exit_values.phpt +++ b/Zend/tests/exit/exit_values.phpt @@ -80,7 +80,7 @@ const FILE_PATH = __DIR__ . '/exit_values_test.php'; Using NULL as value: Exit status is: 0 Output is: -Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d +Deprecated: exit(): Passing null to parameter #1 ($status) of type string|int is deprecated in %s on line %d Using false as value: Exit status is: 0 Output is: @@ -116,23 +116,23 @@ Hello world Using [] as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, array given +TypeError: exit(): Argument #1 ($status) must be of type string|int, array given Using STDERR as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given +TypeError: exit(): Argument #1 ($status) must be of type string|int, resource given Using new stdClass() as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given As a statement: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given Using NULL as value: Exit status is: 0 Output is: -Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d +Deprecated: exit(): Passing null to parameter #1 ($status) of type string|int is deprecated in %s on line %d Using false as value: Exit status is: 0 Output is: @@ -168,16 +168,16 @@ Hello world Using [] as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, array given +TypeError: exit(): Argument #1 ($status) must be of type string|int, array given Using STDERR as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given +TypeError: exit(): Argument #1 ($status) must be of type string|int, resource given Using new stdClass() as value: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given As a statement: Exit status is: 0 Output is: -TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 0335d2498acca..245552d094609 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -72,11 +72,11 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ ZEND_FUNCTION(exit) { zend_string *str = NULL; - zend_long code = 0; + zend_long status = 0; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STR_OR_LONG(str, code) + Z_PARAM_STR_OR_LONG(str, status) ZEND_PARSE_PARAMETERS_END(); if (str) { @@ -89,7 +89,7 @@ ZEND_FUNCTION(exit) } } } else { - EG(exit_status) = code; + EG(exit_status) = status; } ZEND_ASSERT(!EG(exception)); diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index ddf12e117966f..f7009c4ffba6e 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -7,10 +7,10 @@ class stdClass { } -function exit(string|int $code = 0): never {} +function exit(string|int $status = 0): never {} /** @alias exit */ -function die(string|int $code = 0): never {} +function die(string|int $status = 0): never {} /** @refcount 1 */ function zend_version(): string {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index db9f325c63f00..b6b9b8753a450 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,8 +1,8 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a6d7e59d6b7875ddc28ce828ae240c7dfd852023 */ + * Stub hash: 3dbc84896823c9aaa9ac8aeef8841266920c3e50 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) - ZEND_ARG_TYPE_MASK(0, code, MAY_BE_STRING|MAY_BE_LONG, "0") + ZEND_ARG_TYPE_MASK(0, status, MAY_BE_STRING|MAY_BE_LONG, "0") ZEND_END_ARG_INFO() #define arginfo_die arginfo_exit From 565a31c7c57acb62f8e70281f218ec2563968ce0 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 00:19:44 +0200 Subject: [PATCH 059/280] Autotools: Simplify PHP_SELECT_SAPI in apache2handler SAPI (#15444) --- sapi/apache2handler/config.m4 | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index a705f0b3acc26..0abc8a52368a2 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -79,13 +79,10 @@ if test "$PHP_APXS2" != "no"; then LIBPHP_CFLAGS="-shared" PHP_SUBST([LIBPHP_CFLAGS]) + php_sapi_apache2handler_type=shared AS_CASE([$host_alias], [*aix*], [ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-brtl -Wl,-bI:$APXS_LIBEXECDIR/httpd.exp" - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" ], [*darwin*], [ @@ -101,19 +98,16 @@ if test "$PHP_APXS2" != "no"; then fi MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" PHP_SUBST([MH_BUNDLE_FLAGS]) - PHP_SELECT_SAPI([apache2handler], - [bundle], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) + php_sapi_apache2handler_type=bundle SAPI_SHARED=libs/libphp.so INSTALL_IT="$INSTALL_IT $SAPI_SHARED" - ], [ - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" - ]) + ], + [INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL"]) + + PHP_SELECT_SAPI([apache2handler], + [$php_sapi_apache2handler_type], + [mod_php.c sapi_apache2.c apache_config.c php_functions.c], + [$APACHE_CFLAGS]) AS_IF([$APXS_HTTPD -V 2>/dev/null | grep 'threaded:.*yes' >/dev/null 2>&1], [ APACHE_THREADED_MPM=yes From a400298d96fd817dc2ca440a7d09a71fe9416211 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 00:20:20 +0200 Subject: [PATCH 060/280] Add hash extension to soap dependencies (#15449) This adds the hash extension to the configure phase as a required dependency. --- ext/soap/config.m4 | 1 + ext/soap/config.w32 | 1 + 2 files changed, 2 insertions(+) diff --git a/ext/soap/config.m4 b/ext/soap/config.m4 index 1f4370fdf8022..d4eda59cec5ef 100644 --- a/ext/soap/config.m4 +++ b/ext/soap/config.m4 @@ -20,6 +20,7 @@ if test "$PHP_SOAP" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_SUBST([SOAP_SHARED_LIBADD]) ]) + PHP_ADD_EXTENSION_DEP(soap, hash) PHP_ADD_EXTENSION_DEP(soap, libxml) PHP_ADD_EXTENSION_DEP(soap, session, true) fi diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index f30d108465fdc..ca052f912db83 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -10,6 +10,7 @@ if (PHP_SOAP != "no") { ) { EXTENSION('soap', 'soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c', null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_SOAP', 1, "Define to 1 if the PHP extension 'soap' is available."); + ADD_EXTENSION_DEP('soap', 'hash'); ADD_EXTENSION_DEP('soap', 'session', true); if (!PHP_SOAP_SHARED) { From 8db3d36f2fc7bc440d3a0697a2ce04dca5e73ad1 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 10:02:33 +0200 Subject: [PATCH 061/280] Autotools: Remove redundant SAPI_SHARED assignment (#15453) When the target system is Darwin, the SAPI_SHARED is already set to libs/libphp.so (instead of libs/libphp.dylib) in configure.ac and in php.m4 via PHP_SHLIB_SUFFIX_NAMES. --- sapi/apache2handler/config.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index 0abc8a52368a2..9bb94e6c11361 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -99,7 +99,6 @@ if test "$PHP_APXS2" != "no"; then MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" PHP_SUBST([MH_BUNDLE_FLAGS]) php_sapi_apache2handler_type=bundle - SAPI_SHARED=libs/libphp.so INSTALL_IT="$INSTALL_IT $SAPI_SHARED" ], [INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL"]) From b86dfd76a26f00610e19071fabb4c9001791074c Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 13:58:40 +0200 Subject: [PATCH 062/280] Remove php_win32_init_gettimeofday declaration (#15451) * Remove php_win32_init_gettimeofday declaration Follow-up of GH-15400 (25afbdb09e18d4477df1822fbfe76480e6c2aa79). * Remove unused header include * Include php.h before win32/ioutil.h --- win32/dllmain.c | 3 +-- win32/time.h | 6 ------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/win32/dllmain.c b/win32/dllmain.c index ab625bf3e597b..38d143acfedb2 100644 --- a/win32/dllmain.c +++ b/win32/dllmain.c @@ -16,9 +16,8 @@ #include -#include -#include #include +#include #ifdef HAVE_LIBXML #include diff --git a/win32/time.h b/win32/time.h index 51090ccfd8a8c..77d1cbfd311e1 100644 --- a/win32/time.h +++ b/win32/time.h @@ -54,10 +54,4 @@ PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp ); PHPAPI int usleep(unsigned int useconds); -#ifdef PHP_EXPORTS -/* This symbols are needed only for the DllMain, but should not be exported - or be available when used with PHP binaries. */ -void php_win32_init_gettimeofday(void); -#endif - #endif From b2640ee7f78d4e55fce9d7d4ec49e159e3532986 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 14:37:32 +0200 Subject: [PATCH 063/280] Autotools: Replace obsolete backticks with $(...) in apache2handler (#15454) Obsolete backticks can be replaced with the recommended $(...) (on shells where the "newer" style still doesn't work, for example, on Solaris 10 default shell, Autoconf takes care of that by re-executing the script itself). --- sapi/apache2handler/config.m4 | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index 9bb94e6c11361..ff0829846b8c6 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -31,25 +31,23 @@ if test "$PHP_APXS2" != "no"; then AC_MSG_ERROR([Aborting]) fi - APXS_INCLUDEDIR=`$APXS -q INCLUDEDIR` - APXS_HTTPD=`$APXS -q SBINDIR`/`$APXS -q TARGET` + APXS_INCLUDEDIR=$($APXS -q INCLUDEDIR) + APXS_HTTPD=$($APXS -q SBINDIR)/$($APXS -q TARGET) AS_IF([test ! -x "$APXS_HTTPD"], [AC_MSG_ERROR(m4_text_wrap([ $APXS_HTTPD executable not found. Please, install Apache HTTP Server command-line utility. ]))]) - APXS_CFLAGS=`$APXS -q CFLAGS` - APU_BINDIR=`$APXS -q APU_BINDIR` - APR_BINDIR=`$APXS -q APR_BINDIR` + APXS_CFLAGS=$($APXS -q CFLAGS) + APU_BINDIR=$($APXS -q APU_BINDIR) + APR_BINDIR=$($APXS -q APR_BINDIR) dnl Pick up ap[ru]-N-config. - APR_CONFIG=`$APXS -q APR_CONFIG 2>/dev/null || - echo $APR_BINDIR/apr-config` - APU_CONFIG=`$APXS -q APU_CONFIG 2>/dev/null || - echo $APU_BINDIR/apu-config` + APR_CONFIG=$($APXS -q APR_CONFIG 2>/dev/null || echo $APR_BINDIR/apr-config) + APU_CONFIG=$($APXS -q APU_CONFIG 2>/dev/null || echo $APU_BINDIR/apu-config) - APR_CFLAGS="`$APR_CONFIG --cppflags --includes`" - APU_CFLAGS="`$APU_CONFIG --includes`" + APR_CFLAGS="$($APR_CONFIG --cppflags --includes)" + APU_CFLAGS="$($APU_CONFIG --includes)" for flag in $APXS_CFLAGS; do AS_CASE([$flag], [-D*], [APACHE_CPPFLAGS="$APACHE_CPPFLAGS $flag"]) @@ -62,13 +60,13 @@ if test "$PHP_APXS2" != "no"; then AS_VERSION_COMPARE([$APACHE_VERSION], [2004000], [AC_MSG_ERROR([Please note that Apache version >= 2.4 is required])]) - APXS_LIBEXECDIR='$(INSTALL_ROOT)'`$APXS -q LIBEXECDIR` - if test -z `$APXS -q SYSCONFDIR`; then + APXS_LIBEXECDIR='$(INSTALL_ROOT)'$($APXS -q LIBEXECDIR) + if test -z $($APXS -q SYSCONFDIR); then INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ -i -n php" else - APXS_SYSCONFDIR='$(INSTALL_ROOT)'`$APXS -q SYSCONFDIR` + APXS_SYSCONFDIR='$(INSTALL_ROOT)'$($APXS -q SYSCONFDIR) INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ \$(mkinstalldirs) '$APXS_SYSCONFDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ @@ -91,10 +89,10 @@ if test "$PHP_APXS2" != "no"; then dnl its dependencies. Therefore, we must pull in the APR and APR-util dnl libraries. if test -x "$APR_CONFIG"; then - MH_BUNDLE_FLAGS="`$APR_CONFIG --ldflags --link-ld --libs`" + MH_BUNDLE_FLAGS="$($APR_CONFIG --ldflags --link-ld --libs)" fi if test -x "$APU_CONFIG"; then - MH_BUNDLE_FLAGS="`$APU_CONFIG --ldflags --link-ld --libs` $MH_BUNDLE_FLAGS" + MH_BUNDLE_FLAGS="$($APU_CONFIG --ldflags --link-ld --libs) $MH_BUNDLE_FLAGS" fi MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" PHP_SUBST([MH_BUNDLE_FLAGS]) From 0064c4221536ec6135280dd4aa6d71ae85773a00 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 15:10:10 +0200 Subject: [PATCH 064/280] Autotools: Simplify PHP_PDO_DBLIB conditions The PHP_PDO_DBLIB value no is already checked in the main if sentence. --- ext/pdo_dblib/config.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/pdo_dblib/config.m4 b/ext/pdo_dblib/config.m4 index 0adf020c29505..1b68a9913b362 100644 --- a/ext/pdo_dblib/config.m4 +++ b/ext/pdo_dblib/config.m4 @@ -4,14 +4,14 @@ PHP_ARG_WITH([pdo-dblib], [PDO: DBLIB-DB support. DIR is the FreeTDS home directory])]) if test "$PHP_PDO_DBLIB" != "no"; then - if test "$PHP_PDO_DBLIB" = "yes"; then + AS_VAR_IF([PHP_PDO_DBLIB], [yes], [ dnl FreeTDS must be on the default system include/library path. dnl Only perform a sanity check that this is really the case. PHP_CHECK_LIBRARY([sybdb], [dbsqlexec], [], [AC_MSG_FAILURE([Cannot find FreeTDS in known installation directories.])]) PHP_ADD_LIBRARY([sybdb],, [PDO_DBLIB_SHARED_LIBADD]) - elif test "$PHP_PDO_DBLIB" != "no"; then + ], [ if test -f $PHP_PDO_DBLIB/include/sybdb.h; then PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include @@ -32,7 +32,7 @@ if test "$PHP_PDO_DBLIB" != "no"; then PHP_ADD_LIBRARY_WITH_PATH([sybdb], [$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR], [PDO_DBLIB_SHARED_LIBADD]) - fi + ]) PHP_CHECK_PDO_INCLUDES From a3196b3f72294b7eae3d342db70384d8db482bea Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 17 Aug 2024 17:45:07 +0200 Subject: [PATCH 065/280] Drop support for MYSQL_TEST_SKIP_CONNECT_FAILURE (#15461) Closes GH-15457. --- ext/mysqli/tests/connect.inc | 1 - ext/mysqli/tests/skipifconnectfailure.inc | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index 18e4902624ee8..3a7d578e97713 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -16,7 +16,6 @@ $db = getenv("MYSQL_TEST_DB") ?: "test"; $engine = getenv("MYSQL_TEST_ENGINE") ?: "InnoDB"; $socket = getenv("MYSQL_TEST_SOCKET") ?: null; - $skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ?: true; if ($socket) { ini_set('mysqli.default_socket', $socket); } diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc index 2e770426d4c0b..986f646f8bb92 100644 --- a/ext/mysqli/tests/skipifconnectfailure.inc +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -1,9 +1,7 @@ From 0dfafdbc85768967f766ab8ff0aaeb201e83dc6a Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sat, 17 Aug 2024 18:05:01 +0200 Subject: [PATCH 066/280] Remove PHP 6 leftovers and fix mysqli tests (#15464) --- ext/mysqli/tests/mysqli_fetch_all_oo.phpt | 34 ++++++------ ext/mysqli/tests/mysqli_fetch_array.phpt | 16 ------ ext/mysqli/tests/mysqli_fetch_array_oo.phpt | 34 ++++++------ ext/mysqli/tests/mysqli_get_charset.phpt | 8 +-- ext/mysqli/tests/mysqli_get_client_stats.phpt | 1 - ext/mysqli/tests/mysqli_stmt_bind_result.phpt | 49 ++++++----------- .../tests/mysqli_stmt_get_result_types.phpt | 53 ++++++------------- 7 files changed, 65 insertions(+), 130 deletions(-) diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index 6bb2fd80bb12d..cfe8f8464be2d 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -121,25 +121,21 @@ require_once 'skipifconnectfailure.inc'; } $row = $tmp[0]; - $fields = mysqli_fetch_fields($res); - - if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { - if ($regexp_comparison) { - if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { - printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, $regexp_comparison, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $link->errno, $link->error); - return false; - } - } else { - if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $link->errno, $link->error); - return false; - } + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; } } diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt index ed1c76f3dedd2..2ec58913fb552 100644 --- a/ext/mysqli/tests/mysqli_fetch_array.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array.phpt @@ -109,22 +109,6 @@ require_once 'skipifconnectfailure.inc'; gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); return false; } - } else if ((gettype($php_value) == 'unicode') && $binary_type) { - // Unicode is on and we are told that the MySQL column type is a binary type. - // Don't expect a unicode value from the database, you'll get binary string - if (($row['label'] != $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 5, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); - return false; - } - if (gettype($row['label']) == 'unicode') { - var_dump(mysqli_fetch_field_direct($res, 1), $row['label']); - printf("[%04d] SQL Type: '%s', binary columns are supposed to return binary string and not unicode\n", - $offset + 6, $sql_type); - return false; - } } else { if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 7, diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt index 23ae16cdd2e23..8639b7419b129 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -103,27 +103,25 @@ require_once 'skipifconnectfailure.inc'; printf("[%04d] [%d] %s\n", $offset + 3, $mysqli->errno, $mysqli->error); return false; } - $fields = mysqli_fetch_fields($res); - - if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { - if ($regexp_comparison) { - if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { - printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, $regexp_comparison, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); return false; - } - } else { - if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); - return false; - } } } + return true; } diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index 7718263bc451b..0bc49bab8abc0 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -49,12 +49,12 @@ require_once 'skipifconnectfailure.inc'; printf("[015] Expecting object/std_class, got %s/%s\n", gettype($charset), $charset); if (!isset($charset->charset) || - !in_array(gettype($charset->charset), array("string", "unicode")) || - ($character_set_connection !== $charset->charset)) + !is_string($charset->charset) || + $character_set_connection !== $charset->charset) printf("[016] Expecting string/%s, got %s/%s\n", $character_set_connection, gettype($charset->charset), $charset->charset); if (!isset($charset->collation) || - !in_array(gettype($charset->collation), array("string", "unicode")) || - ($collation_connection !== $charset->collation)) + !is_string($charset->collation) || + $collation_connection !== $charset->collation) printf("[017] Expecting string/%s, got %s/%s\n", $collation_connection, gettype($charset->collation), $charset->collation); if (!isset($charset->dir) || diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt index a8d509eb62760..90823854d41ff 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -112,7 +112,6 @@ mysqli.allow_local_infile=1 // we assume the above as tested and in the following we check only those mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter); - /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter); diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index 11d8e64e9660e..5a210f3d2e356 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -80,14 +80,12 @@ require_once 'skipifconnectfailure.inc'; $id = null; if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } for ($id = 1; $id < 4; $id++) { if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } } @@ -97,37 +95,28 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } - $result = mysqli_stmt_result_metadata($stmt); - $bind_res = null; if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } $num = 0; - $fields = mysqli_fetch_fields($result); while (mysqli_stmt_fetch($stmt)) { - if (!gettype($bind_res)=="unicode") { - if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { - printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", - $offset + 10, $num, - gettype($bind_value), $bind_value, $type_hint, - gettype($bind_res), $bind_res); - mysqli_stmt_close($stmt); - return false; - } + if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { + printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", + $offset + 10, $num, + gettype($bind_value), $bind_value, $type_hint, + gettype($bind_res), $bind_res); + return false; } $num++; } @@ -135,11 +124,9 @@ require_once 'skipifconnectfailure.inc'; if ($num != 3) { printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); - mysqli_stmt_close($stmt); return false; } - mysqli_stmt_close($stmt); return true; } @@ -193,26 +180,20 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); - func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); - func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); - func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9237.21, 600); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", NULL, 620); - func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18467.5, 640); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); // Yes, we need the temporary variable. The PHP casting will foul us otherwise. - $tmp = strval('-99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", '-99999999.99', 680, "double"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); - $tmp = strval('99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", '99999999.99' , 720, "double"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); - $tmp = strval('-99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", '-99999999.99', 760, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); - $tmp = strval('99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", '99999999.99', 800, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); // don't care about date() strict TZ warnings... @@ -231,8 +212,8 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", NULL, 1020); $tmp = intval(@date('Y')); - func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); - func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "string"); // YEAR is a string with implicit display width of 4 + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "string"); func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", NULL, 1080); $string255 = func_mysqli_stmt_bind_make_string(255); @@ -284,7 +265,7 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, 'string'); if (mysqli_get_server_version($link) >= 50600) - func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", "13:31:34.123456", 1770, "13:31:34"); + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME(6)", "13:31:34.123456", 1770); $stmt = mysqli_stmt_init($link); if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1000, 'z')")) diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt index d2ae94c5f94b5..f49c2079f72e3 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt @@ -37,14 +37,12 @@ mysqli $id = null; if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } for ($id = 1; $id < 4; $id++) { if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } } @@ -54,38 +52,27 @@ mysqli if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } - $result = mysqli_stmt_result_metadata($stmt); - if (!$res = mysqli_stmt_get_result($stmt)) { printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } $num = 0; - $fields = mysqli_fetch_fields($result); while ($row = mysqli_fetch_assoc($res)) { - $bind_res = &$row['label']; - if (!gettype($bind_res) == 'unicode') { - if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { - printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", - $offset + 10, $num, - gettype($bind_value), $bind_value, $type_hint, - gettype($bind_res), $bind_res); - mysqli_free_result($res); - mysqli_stmt_close($stmt); - return false; - } + if ($row['label'] !== $bind_value && (!$type_hint || ($type_hint !== gettype($row['label'])))) { + printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", + $offset + 10, $num, + gettype($bind_value), $bind_value, $type_hint, + gettype($row['label']), $row['label']); + return false; } $num++; } @@ -93,13 +80,9 @@ mysqli if ($num != 3) { printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); - mysqli_free_result($res); - mysqli_stmt_close($stmt); return false; } - mysqli_free_result($res); - mysqli_stmt_close($stmt); return true; } @@ -154,28 +137,22 @@ mysqli func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); func_mysqli_stmt_get_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); - func_mysqli_stmt_get_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); + func_mysqli_stmt_get_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880, "integer"); - func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT", -9237.21, 600); func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT", NULL, 620); - func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT UNSIGNED", 18467.5, 640); func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); - // Yes, we need the temporary variable. The PHP casting will foul us otherwise. - $tmp = strval('-99999999.99'); - func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 680); func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); - $tmp = strval('99999999.99'); - func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99 , 720); func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); - $tmp = strval('-99999999.99'); - func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", '-99999999.99', 760, "string"); func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); - $tmp = strval('99999999.99'); - func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", '99999999.99', 800, "string"); func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); - // don't care about date() strict TZ warnings... func_mysqli_stmt_get_result($link, $engine, "s", "DATE", @date('Y-m-d'), 840); func_mysqli_stmt_get_result($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 860); func_mysqli_stmt_get_result($link, $engine, "s", "DATE", NULL, 880); @@ -191,8 +168,8 @@ mysqli func_mysqli_stmt_get_result($link, $engine, "s", "TIME", NULL, 1020); $tmp = intval(@date('Y')); - func_mysqli_stmt_get_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); - func_mysqli_stmt_get_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); + func_mysqli_stmt_get_result($link, $engine, "s", "YEAR", $tmp, 1040, "string"); // YEAR is a string with implicit display width of 4 + func_mysqli_stmt_get_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "string"); func_mysqli_stmt_get_result($link, $engine, "s", "YEAR", NULL, 1080); $string255 = func_mysqli_stmt_bind_make_string(255); From a1b1a6c925577200e74fbf42a09f2b5d045e112b Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 18:14:30 +0200 Subject: [PATCH 067/280] [skip ci] Remove dead code --- ext/intl/resourcebundle/resourcebundle_iterator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.c b/ext/intl/resourcebundle/resourcebundle_iterator.c index 8e405f0a5868e..c79269e475070 100644 --- a/ext/intl/resourcebundle/resourcebundle_iterator.c +++ b/ext/intl/resourcebundle/resourcebundle_iterator.c @@ -42,7 +42,6 @@ static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator ) resourcebundle_extract_value( &iterator->current, rb ); } else { - // zend_throw_exception( spl_ce_OutOfRangeException, "Running past end of ResourceBundle", 0); ZVAL_UNDEF(&iterator->current); } } From 6050a99cb822169763f997fddb41a9b93f65eaf3 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 18:39:31 +0200 Subject: [PATCH 068/280] Autotools: Sync CS in pdo_odbc (#15466) - Obsolete backticks replaced with $(...) - Few redundant double quotes around variables removed - AS_VAR_IF used - indentation synced --- ext/pdo_odbc/config.m4 | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/pdo_odbc/config.m4 b/ext/pdo_odbc/config.m4 index 794743d362f2d..af3668f5adf57 100644 --- a/ext/pdo_odbc/config.m4 +++ b/ext/pdo_odbc/config.m4 @@ -32,8 +32,8 @@ if test "$PHP_PDO_ODBC" != "no"; then AC_MSG_CHECKING([for selected PDO ODBC flavour]) - pdo_odbc_flavour="`echo $PHP_PDO_ODBC | cut -d, -f1`" - pdo_odbc_dir="`echo $PHP_PDO_ODBC | cut -d, -f2`" + pdo_odbc_flavour="$(echo $PHP_PDO_ODBC | cut -d, -f1)" + pdo_odbc_dir="$(echo $PHP_PDO_ODBC | cut -d, -f2)" if test "$pdo_odbc_dir" = "$PHP_PDO_ODBC" ; then pdo_odbc_dir= @@ -41,17 +41,17 @@ if test "$PHP_PDO_ODBC" != "no"; then AS_CASE([$pdo_odbc_flavour], [ibm-db2], [ - pdo_odbc_def_libdir=/home/db2inst1/sqllib/lib - pdo_odbc_def_incdir=/home/db2inst1/sqllib/include - pdo_odbc_def_lib=db2 + pdo_odbc_def_libdir=/home/db2inst1/sqllib/lib + pdo_odbc_def_incdir=/home/db2inst1/sqllib/include + pdo_odbc_def_lib=db2 ], [iODBC|iodbc], [pdo_odbc_pkgconfig_module=libiodbc], [unixODBC|unixodbc], [pdo_odbc_pkgconfig_module=odbc], [generic], [ - pdo_odbc_def_lib="`echo $PHP_PDO_ODBC | cut -d, -f3`" - pdo_odbc_def_ldflags="`echo $PHP_PDO_ODBC | cut -d, -f4`" - pdo_odbc_def_cflags="`echo $PHP_PDO_ODBC | cut -d, -f5`" - pdo_odbc_flavour="generic-$pdo_odbc_def_lib" + pdo_odbc_def_lib="$(echo $PHP_PDO_ODBC | cut -d, -f3)" + pdo_odbc_def_ldflags="$(echo $PHP_PDO_ODBC | cut -d, -f4)" + pdo_odbc_def_cflags="$(echo $PHP_PDO_ODBC | cut -d, -f5)" + pdo_odbc_flavour="generic-$pdo_odbc_def_lib" ], [AC_MSG_ERROR([Unknown ODBC flavour $pdo_odbc_flavour]PDO_ODBC_HELP_TEXT)]) @@ -59,13 +59,13 @@ if test "$PHP_PDO_ODBC" != "no"; then AC_MSG_RESULT([$pdo_odbc_flavour using pkg-config]) PKG_CHECK_MODULES([PDO_ODBC], [$pdo_odbc_pkgconfig_module]) else - if test -n "$pdo_odbc_dir"; then + AS_VAR_IF([pdo_odbc_dir],, [ + PDO_ODBC_INCDIR=$pdo_odbc_def_incdir + PDO_ODBC_LIBDIR=$pdo_odbc_def_libdir + ], [ PDO_ODBC_INCDIR="$pdo_odbc_dir/include" PDO_ODBC_LIBDIR="$pdo_odbc_dir/$PHP_LIBDIR" - else - PDO_ODBC_INCDIR="$pdo_odbc_def_incdir" - PDO_ODBC_LIBDIR="$pdo_odbc_def_libdir" - fi + ]) AC_MSG_RESULT([$pdo_odbc_flavour libs $PDO_ODBC_LIBDIR, From 82c4db615475ffa4fbf782b23fd9fcce2cd24985 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 18:39:49 +0200 Subject: [PATCH 069/280] Autotools: Remove PHP_LIBDIR adjustment in pdo_dblib (#15463) This is redundant in current state of the build system as --with-libdir option sets the location and by default it is set to "lib". It is also done by phpize. --- ext/pdo_dblib/config.m4 | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/pdo_dblib/config.m4 b/ext/pdo_dblib/config.m4 index 1b68a9913b362..4cfea501c3e37 100644 --- a/ext/pdo_dblib/config.m4 +++ b/ext/pdo_dblib/config.m4 @@ -22,8 +22,6 @@ if test "$PHP_PDO_DBLIB" != "no"; then AC_MSG_ERROR([Directory $PHP_PDO_DBLIB is not a FreeTDS installation directory]) fi - AS_VAR_IF([PHP_LIBDIR],, [PHP_LIBDIR=lib]) - if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then AC_MSG_ERROR([[Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so]]]) fi From 41709ac89f0fe6c6f4ff123bb6fc61481db0fb1a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 17 Aug 2024 21:11:28 +0200 Subject: [PATCH 070/280] Update ext/mbstring and ext/snmp dependencies (#15469) The mbstring extension requires the pcre extension and snmp extension requires the spl extension. --- ext/mbstring/config.m4 | 1 + ext/mbstring/config.w32 | 1 + ext/snmp/config.m4 | 1 + ext/snmp/config.w32 | 1 + 4 files changed, 4 insertions(+) diff --git a/ext/mbstring/config.m4 b/ext/mbstring/config.m4 index 890287e3ddd78..b526db0b200c0 100644 --- a/ext/mbstring/config.m4 +++ b/ext/mbstring/config.m4 @@ -178,4 +178,5 @@ if test "$PHP_MBSTRING" != "no"; then dnl libmbfl is required PHP_MBSTRING_SETUP_LIBMBFL PHP_MBSTRING_EXTENSION + PHP_ADD_EXTENSION_DEP(mbstring, pcre) fi diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index 37c01b84fd1e2..070d3d73137ac 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -7,6 +7,7 @@ if (PHP_MBSTRING != "no") { if (CHECK_HEADER_ADD_INCLUDE("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED); + ADD_EXTENSION_DEP('mbstring', 'pcre'); STDOUT.WriteLine("Using bundled libmbfl..."); diff --git a/ext/snmp/config.m4 b/ext/snmp/config.m4 index 79abace8de888..22cab40adf3be 100644 --- a/ext/snmp/config.m4 +++ b/ext/snmp/config.m4 @@ -87,5 +87,6 @@ if test "$PHP_SNMP" != "no"; then LIBS=$LIBS_SAVE PHP_NEW_EXTENSION([snmp], [snmp.c], [$ext_shared]) + PHP_ADD_EXTENSION_DEP(snmp, spl) PHP_SUBST([SNMP_SHARED_LIBADD]) fi diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index 07b9872883eab..a2facb6946d67 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -7,6 +7,7 @@ if (PHP_SNMP != "no") { SETUP_OPENSSL("snmp", PHP_SNMP) >= 2) { if (CHECK_LIB("netsnmp.lib", "snmp", PHP_SNMP)) { EXTENSION('snmp', 'snmp.c'); + ADD_EXTENSION_DEP('snmp', 'spl'); AC_DEFINE('HAVE_SNMP', 1, "Define to 1 if the PHP extension 'snmp' is available."); } else { WARNING("snmp not enabled; libraries and headers not found"); From d472866f3346bce3889a0dee14bbf1b99b3ac8b3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 17 Aug 2024 23:28:24 +0200 Subject: [PATCH 071/280] Drop erroneous CLEAN section It doesn't belong to this test case, and may actually interfere with HTMLDocument_Windows1251.phpt[1]. [1] --- .../modern/html/encoding/HTMLDocument_fallback_encoding.phpt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt index fda707577b5f5..124bd2e79a35a 100644 --- a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt +++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt @@ -9,10 +9,6 @@ $dom = Dom\HTMLDocument::createFromFile(__DIR__ . "/fallback_encoding.html"); var_dump($dom->inputEncoding); echo $dom->saveHtml(); -?> ---CLEAN-- - --EXPECT-- string(5) "UTF-8" From 7e5171d1f671dc19251fa8241842eb2fb4f8d7b8 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sun, 18 Aug 2024 00:12:23 +0200 Subject: [PATCH 072/280] Clean up mysqli tests (#15473) --- ext/mysqli/tests/065.phpt | 2 -- ext/mysqli/tests/071.phpt | 1 - ext/mysqli/tests/bug45289.phpt | 2 +- ext/mysqli/tests/bug55283.phpt | 2 -- ext/mysqli/tests/bug62885.phpt | 1 - ext/mysqli/tests/bug66124.phpt | 1 - ext/mysqli/tests/bug72489.phpt | 2 -- ext/mysqli/tests/bug76386.phpt | 2 +- ...mysqli_fetch_all_data_types_variation.phpt | 2 -- ext/mysqli/tests/gh14255.phpt | 4 ++-- ext/mysqli/tests/gh9841.phpt | 4 ++-- ext/mysqli/tests/mysqli_affected_rows.phpt | 3 +-- .../tests/mysqli_begin_transaction.phpt | 4 ++-- ext/mysqli/tests/mysqli_change_user_new.phpt | 3 --- ext/mysqli/tests/mysqli_change_user_old.phpt | 3 --- ext/mysqli/tests/mysqli_change_user_oo.phpt | 3 --- .../tests/mysqli_change_user_rollback.phpt | 2 +- ...ysqli_class_mysqli_properties_no_conn.phpt | 4 ++-- .../mysqli_class_mysqli_result_interface.phpt | 12 +++++----- .../mysqli_class_mysqli_stmt_interface.phpt | 4 ++-- ext/mysqli/tests/mysqli_connect.phpt | 4 +--- ext/mysqli/tests/mysqli_connect_attr.phpt | 3 --- ext/mysqli/tests/mysqli_connect_errno.phpt | 1 - ext/mysqli/tests/mysqli_connect_error.phpt | 3 +-- ext/mysqli/tests/mysqli_connect_oo.phpt | 5 ----- .../tests/mysqli_connect_oo_defaults.phpt | 3 --- ext/mysqli/tests/mysqli_constants.phpt | 3 +-- .../tests/mysqli_debug_control_string.phpt | 2 +- .../mysqli_debug_mysqlnd_control_string.phpt | 12 +++++----- .../tests/mysqli_debug_mysqlnd_only.phpt | 10 ++++----- .../tests/mysqli_dump_debug_info_oo.phpt | 3 --- ext/mysqli/tests/mysqli_errno_oo.phpt | 3 --- ext/mysqli/tests/mysqli_error_oo.phpt | 3 --- ext/mysqli/tests/mysqli_execute_query.phpt | 2 +- ext/mysqli/tests/mysqli_explain_metadata.phpt | 6 ++--- ext/mysqli/tests/mysqli_fetch_all_oo.phpt | 6 ++--- ext/mysqli/tests/mysqli_fetch_array.phpt | 6 ++--- .../tests/mysqli_fetch_array_many_rows.phpt | 3 +-- ext/mysqli/tests/mysqli_fetch_array_oo.phpt | 6 ++--- ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt | 1 - .../tests/mysqli_fetch_assoc_no_alias.phpt | 8 +++---- .../mysqli_fetch_assoc_no_alias_utf8.phpt | 12 +++++----- .../tests/mysqli_fetch_field_flags.phpt | 4 ++-- ext/mysqli/tests/mysqli_fetch_lengths.phpt | 3 +-- ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt | 2 +- ext/mysqli/tests/mysqli_fetch_object.phpt | 2 +- ext/mysqli/tests/mysqli_get_charset.phpt | 6 +---- ext/mysqli/tests/mysqli_get_client_stats.phpt | 22 ++++++++----------- .../mysqli_get_client_stats_skipped.phpt | 2 +- ext/mysqli/tests/mysqli_get_warnings.phpt | 20 ++++------------- ext/mysqli/tests/mysqli_info.phpt | 13 +++++------ ext/mysqli/tests/mysqli_insert_id.phpt | 13 +++++------ .../tests/mysqli_insert_packet_overflow.phpt | 14 +----------- ext/mysqli/tests/mysqli_kill.phpt | 6 ++--- ext/mysqli/tests/mysqli_more_results.phpt | 2 +- ext/mysqli/tests/mysqli_multi_query.phpt | 10 ++++----- .../tests/mysqli_mysqlnd_read_timeout.phpt | 2 +- ext/mysqli/tests/mysqli_no_reconnect.phpt | 4 ++-- ext/mysqli/tests/mysqli_num_fields.phpt | 4 ++-- ext/mysqli/tests/mysqli_num_rows.phpt | 6 ++--- ..._pam_sha256_public_key_option_invalid.phpt | 3 ++- ext/mysqli/tests/mysqli_pconn_max_links.phpt | 8 ++++--- ext/mysqli/tests/mysqli_phpinfo.phpt | 2 +- ext/mysqli/tests/mysqli_ping.phpt | 2 +- .../mysqli_poll_mixing_insert_select.phpt | 14 ++++++------ ext/mysqli/tests/mysqli_poll_reference.phpt | 12 +++++----- .../tests/mysqli_prepare_no_object.phpt | 8 +++---- ext/mysqli/tests/mysqli_query.phpt | 2 +- ext/mysqli/tests/mysqli_query_iterators.phpt | 3 ++- .../tests/mysqli_query_stored_proc.phpt | 6 ++--- ext/mysqli/tests/mysqli_query_unicode.phpt | 2 +- ...mysqli_real_connect_compression_error.phpt | 4 ++-- ext/mysqli/tests/mysqli_reap_async_query.phpt | 4 ---- .../tests/mysqli_reap_async_query_error.phpt | 2 +- .../tests/mysqli_release_savepoint.phpt | 6 ++--- ext/mysqli/tests/mysqli_report.phpt | 10 +++------ .../tests/mysqli_result_invalid_mode.phpt | 1 - ext/mysqli/tests/mysqli_savepoint.phpt | 2 +- ext/mysqli/tests/mysqli_select_db.phpt | 6 ++--- ext/mysqli/tests/mysqli_set_charset.phpt | 1 - ext/mysqli/tests/mysqli_stat.phpt | 2 +- ext/mysqli/tests/mysqli_stmt_attr_get.phpt | 18 +++++++-------- ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 21 +++--------------- ext/mysqli/tests/mysqli_stmt_bind_param.phpt | 4 ++-- ...mysqli_stmt_bind_param_call_user_func.phpt | 1 - ext/mysqli/tests/mysqli_stmt_bind_result.phpt | 3 ++- ext/mysqli/tests/mysqli_stmt_close.phpt | 9 +++----- ext/mysqli/tests/mysqli_stmt_data_seek.phpt | 9 +++----- .../mysqli_stmt_execute_stored_proc_out.phpt | 2 +- ...ysqli_stmt_fetch_fields_win32_unicode.phpt | 4 ++-- ext/mysqli/tests/mysqli_stmt_free_result.phpt | 9 +++----- ext/mysqli/tests/mysqli_stmt_get_result2.phpt | 2 +- ext/mysqli/tests/mysqli_stmt_multires.phpt | 1 - .../tests/mysqli_stmt_result_metadata.phpt | 6 ++--- .../tests/mysqli_stmt_send_long_data.phpt | 2 +- ...mt_send_long_data_packet_size_mysqlnd.phpt | 2 -- ext/mysqli/tests/mysqli_store_result.phpt | 2 +- .../tests/mysqli_store_result_buffered_c.phpt | 2 +- ext/mysqli/tests/mysqli_use_result.phpt | 2 +- ext/mysqli/tests/mysqli_warning_count.phpt | 2 +- .../tests/mysqli_warning_unclonable.phpt | 2 +- ext/mysqli/tests/test_setup/test_helpers.inc | 2 +- 102 files changed, 192 insertions(+), 314 deletions(-) diff --git a/ext/mysqli/tests/065.phpt b/ext/mysqli/tests/065.phpt index 0a6ca356a2052..3e06fafc568ca 100644 --- a/ext/mysqli/tests/065.phpt +++ b/ext/mysqli/tests/065.phpt @@ -16,8 +16,6 @@ require_once 'skipifconnectfailure.inc'; printf("[002] Cannot set SQL-Mode, [%d] %s\n", mysqli_errno($mysql), mysqli_error($mysql)); $esc_str = chr(0xbf) . chr(0x5c); - $len = $charset = array(); - $tmp = null; if ($mysql->set_charset("latin1")) { /* 5C should be escaped */ diff --git a/ext/mysqli/tests/071.phpt b/ext/mysqli/tests/071.phpt index c5b569a664b0a..8fb150feca264 100644 --- a/ext/mysqli/tests/071.phpt +++ b/ext/mysqli/tests/071.phpt @@ -11,7 +11,6 @@ require_once 'skipifconnectfailure.inc'; require_once 'connect.inc'; $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - $version = $mysql->server_version; var_dump($mysql->query('DO 1')); diff --git a/ext/mysqli/tests/bug45289.phpt b/ext/mysqli/tests/bug45289.phpt index 87256659f74c2..d1591bd9b4035 100644 --- a/ext/mysqli/tests/bug45289.phpt +++ b/ext/mysqli/tests/bug45289.phpt @@ -24,7 +24,7 @@ require_once 'skipifconnectfailure.inc'; if (!$stmt->bind_param('i', $id) || !$stmt->execute()) printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); - if ($res = $link->store_result()) { + if ($link->store_result()) { printf("[004] Can store result!\n"); } else { printf("[004] [%d] %s\n", $link->errno, $link->error); diff --git a/ext/mysqli/tests/bug55283.phpt b/ext/mysqli/tests/bug55283.phpt index 4517e26cc3031..f5473c7c49599 100644 --- a/ext/mysqli/tests/bug55283.phpt +++ b/ext/mysqli/tests/bug55283.phpt @@ -43,8 +43,6 @@ $link->close(); --FILE-- getMessage() . \PHP_EOL; } -$test2 = array(); $test2 = array(); try { $test1 = mysqli_poll($test2, $test3, $tablica, 0); diff --git a/ext/mysqli/tests/bug66124.phpt b/ext/mysqli/tests/bug66124.phpt index 521c17e8fb999..d63f04e63cfd4 100644 --- a/ext/mysqli/tests/bug66124.phpt +++ b/ext/mysqli/tests/bug66124.phpt @@ -16,7 +16,6 @@ $table_create = "CREATE TABLE `test` ( $table_insert = "INSERT INTO `test` SET `id`=?"; $table_select = "SELECT * FROM `test`"; -$table_delete = "DELETE FROM `test`"; $id = '1311200011005001566'; diff --git a/ext/mysqli/tests/bug72489.phpt b/ext/mysqli/tests/bug72489.phpt index e1ed342d44407..0c10bcd19cc48 100644 --- a/ext/mysqli/tests/bug72489.phpt +++ b/ext/mysqli/tests/bug72489.phpt @@ -45,8 +45,6 @@ while ($stmt->fetch()) { echo "Finished 1\n"; -$newArray = array(); - echo "Finished 2\n"; ?> diff --git a/ext/mysqli/tests/bug76386.phpt b/ext/mysqli/tests/bug76386.phpt index 8c4a7a7710b9b..5ff4bb403100b 100644 --- a/ext/mysqli/tests/bug76386.phpt +++ b/ext/mysqli/tests/bug76386.phpt @@ -67,7 +67,7 @@ $link->query('INSERT INTO t_test VALUES ();'); $stmt = $link->prepare('SELECT * FROM t_test;'); if ($stmt) { $stmt->execute(); - $tid = $t = $t2 = $t3 = $t4 = null; + $tid = $t = $t2 = $t4 = null; $stmt->bind_result($tid, $t, $t2, $t4, $t6); while ($stmt->fetch()) { var_dump($t, $t2, $t4, $t6); diff --git a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt index a7383ec48dc16..69fc427001fd0 100644 --- a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt +++ b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt @@ -44,8 +44,6 @@ function func_mysqli_fetch_all( $tmp = mysqli_fetch_all($result, MYSQLI_BOTH); $row = $tmp[0]; - $fields = mysqli_fetch_fields($result); - if ($regexp_comparison) { if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, diff --git a/ext/mysqli/tests/gh14255.phpt b/ext/mysqli/tests/gh14255.phpt index 375eda0c5b52c..bdf63e36dfb24 100644 --- a/ext/mysqli/tests/gh14255.phpt +++ b/ext/mysqli/tests/gh14255.phpt @@ -16,13 +16,13 @@ mysqli_report(MYSQLI_REPORT_STRICT|MYSQLI_REPORT_ERROR); $mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $ca = $mysqli->query('SELECT 1 '); -$c = $ca->fetch_assoc(); +$ca->fetch_assoc(); try { $mysqli->query('SELECT non_existent_column'); } catch (Exception $e) { echo "Caught exception"."\n"; } -$c = $ca->fetch_assoc(); +$ca->fetch_assoc(); print "done!"; ?> diff --git a/ext/mysqli/tests/gh9841.phpt b/ext/mysqli/tests/gh9841.phpt index 28d720aa6e909..1e8683379e581 100644 --- a/ext/mysqli/tests/gh9841.phpt +++ b/ext/mysqli/tests/gh9841.phpt @@ -33,7 +33,7 @@ $mysqli->real_query("SELECT ( UNION ALL SELECT 2 ) FROM dual"); -$result = new mysqli_result($mysqli); +new mysqli_result($mysqli); // now make sure the errors are thrown when not using silent mode mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); @@ -65,7 +65,7 @@ $mysqli->real_query("SELECT ( SELECT 2 ) FROM dual"); try { - $result = new mysqli_result($mysqli); + new mysqli_result($mysqli); } catch (mysqli_sql_exception $e) { echo $e->getMessage()."\n"; } diff --git a/ext/mysqli/tests/mysqli_affected_rows.phpt b/ext/mysqli/tests/mysqli_affected_rows.phpt index 2547720b31462..3a56884d148b2 100644 --- a/ext/mysqli/tests/mysqli_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows.phpt @@ -78,8 +78,7 @@ mysqli if (1 !== ($tmp = mysqli_affected_rows($link))) printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); - $charsets = array('utf8'); - foreach ($charsets as $k => $charset) { + foreach (['utf8'] as $charset) { if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $charset)))) continue; mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_begin_transaction.phpt b/ext/mysqli/tests/mysqli_begin_transaction.phpt index 7a7d7e36fba4e..5dbd9dbc49548 100644 --- a/ext/mysqli/tests/mysqli_begin_transaction.phpt +++ b/ext/mysqli/tests/mysqli_begin_transaction.phpt @@ -31,7 +31,7 @@ if (!have_innodb($link)) /* overrule autocommit */ if (true !== ($tmp = mysqli_begin_transaction($link))) - printf("[011] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[011] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -72,7 +72,7 @@ if (!have_innodb($link)) } else if (!mysqli_commit($link)) { printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } else { - $res = mysqli_query($link, "SELECT id FROM test WHERE id = 2"); + mysqli_query($link, "SELECT id FROM test WHERE id = 2"); } } diff --git a/ext/mysqli/tests/mysqli_change_user_new.phpt b/ext/mysqli/tests/mysqli_change_user_new.phpt index d6a9a3bd137c4..e52a91e984de2 100644 --- a/ext/mysqli/tests/mysqli_change_user_new.phpt +++ b/ext/mysqli/tests/mysqli_change_user_new.phpt @@ -20,9 +20,6 @@ if (mysqli_get_server_version($link) >= 10_00_00) = 50600 && mysqli_get_server_version($link = 50600) change_user($user . '_unknown_really', $passwd . 'non_empty', $db))) diff --git a/ext/mysqli/tests/mysqli_change_user_rollback.phpt b/ext/mysqli/tests/mysqli_change_user_rollback.phpt index bcef28cd1d51c..2185a3083d6f7 100644 --- a/ext/mysqli/tests/mysqli_change_user_rollback.phpt +++ b/ext/mysqli/tests/mysqli_change_user_rollback.phpt @@ -30,7 +30,7 @@ if (!have_innodb($link)) $num = $row['_num']; assert($num > 0); - if (!$res = mysqli_query($link, 'DELETE FROM test')) + if (false === mysqli_query($link, 'DELETE FROM test')) printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) diff --git a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt index 46ccbf61a9da3..0c0b012d8702c 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt @@ -15,7 +15,7 @@ require_once 'skipifconnectfailure.inc'; printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($mysqli))); sort($variables); - foreach ($variables as $k => $var) { + foreach ($variables as $var) { try { printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); } catch (Error $exception) { @@ -25,7 +25,7 @@ require_once 'skipifconnectfailure.inc'; printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($mysqli)); - foreach ($variables as $k => $var) { + foreach ($variables as $var) { try { printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); } catch (Error $exception) { diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt index 4e23de5cab541..5b79f7a197d9a 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -69,12 +69,12 @@ require_once 'skipifconnectfailure.inc'; printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($mysqli_result))); sort($variables); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($mysqli_result)); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nMagic, magic properties:\n"); @@ -121,9 +121,9 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_query($link, "SELECT id FROM test ORDER BY id")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $res = new mysqli_result($link); - $res = new mysqli_result($link, MYSQLI_STORE_RESULT); - $res = new mysqli_result($link, MYSQLI_USE_RESULT); + new mysqli_result($link); + new mysqli_result($link, MYSQLI_STORE_RESULT); + new mysqli_result($link, MYSQLI_USE_RESULT); $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); do { @@ -132,7 +132,7 @@ require_once 'skipifconnectfailure.inc'; if ($TEST_EXPERIMENTAL) { ob_start(); - $res = new mysqli_result($link, $mode); + new mysqli_result($link, $mode); $content = ob_get_contents(); ob_end_clean(); if (!stristr($content, 'Invalid value for resultmode')) diff --git a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt index 09d08de7d2957..cc7e36727639d 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt @@ -68,12 +68,12 @@ mysqli printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($stmt))); sort($variables); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($stmt)); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nMagic, magic properties:\n"); diff --git a/ext/mysqli/tests/mysqli_connect.phpt b/ext/mysqli/tests/mysqli_connect.phpt index cf276d6886f67..ad903c9e1e5dd 100644 --- a/ext/mysqli/tests/mysqli_connect.phpt +++ b/ext/mysqli/tests/mysqli_connect.phpt @@ -10,15 +10,13 @@ require_once 'skipifconnectfailure.inc'; $consts) { +foreach ($constants as $consts) { foreach ($consts as $name => $value) { if (stristr($name, 'mysqli')) { $name = strtoupper($name); diff --git a/ext/mysqli/tests/mysqli_debug_control_string.phpt b/ext/mysqli/tests/mysqli_debug_control_string.phpt index b745ed2ebce8b..a589155c2a98e 100644 --- a/ext/mysqli/tests/mysqli_debug_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_control_string.phpt @@ -31,7 +31,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) return false; } - if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + if (false === mysqli_query($link, 'SELECT * FROM test')) { printf("[%03d][control string '%s'] [%d] %s.\n", $offset + 2, $control_string, diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt index e46f4aed19845..b6876e31f1a8e 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt @@ -40,7 +40,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) mysqli_error($link)); return false; } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -97,7 +97,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // -t,[N] - maximum nesting level $trace = try_control_string($link, 't,1:n:O,' . $trace_file, $trace_file, 70); $lines = explode("\n", $trace); - foreach ($lines as $k => $line) { + foreach ($lines as $line) { $line = trim($line); if (!preg_match("@^(\d+):+@ismU", $line, $matches)) { printf("[075] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($line, 0, 80)); @@ -113,7 +113,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // omitting t $trace = try_control_string($link, 'n:O,' . $trace_file, $trace_file, 80); $lines = explode("\n", $trace); - foreach ($lines as $k => $line) { + foreach ($lines as $line) { $line = trim($line); if (preg_match("@^[|\s]*>[\w]+@ism", $line, $matches)) { printf("[085] Looks like a function call, but there should be none in the trace file, first characters from trace are '%s'\n", @@ -124,7 +124,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // -f[,functions] - Limit debugger list to specified functions. Empty list -> all functions $lines_all_funcs = explode("\n", try_control_string($link, 't:O,' . $trace_file, $trace_file, 90)); $functions_all_funcs = array(); - foreach ($lines_all_funcs as $k => $line) { + foreach ($lines_all_funcs as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_all_funcs[$matches[1]] = $matches[1]; @@ -133,7 +133,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", try_control_string($link, 't:f:O,' . $trace_file, $trace_file, 100)); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -169,7 +169,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", try_control_string($link, $control_string, $trace_file, 110)); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index ccee53b02cf92..5327042127c3e 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -39,7 +39,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) mysqli_error($link)); return false; } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -73,7 +73,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", $trace); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -81,7 +81,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) } $found = 0; - foreach ($memory_funcs as $k => $name) + foreach ($memory_funcs as $name) if (isset($functions_trace[$name])) $found++; @@ -97,7 +97,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", $trace); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -105,7 +105,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) } $found = 0; - foreach ($memory_funcs as $k => $name) + foreach ($memory_funcs as $name) if (isset($functions_trace[$name])) $found++; diff --git a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt index 40c53827a752a..fba8032823f55 100644 --- a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt +++ b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt @@ -10,9 +10,6 @@ require_once 'skipifconnectfailure.inc'; errno)) printf("[001] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_error_oo.phpt b/ext/mysqli/tests/mysqli_error_oo.phpt index 2e8473bb53ed0..4f1a971043f91 100644 --- a/ext/mysqli/tests/mysqli_error_oo.phpt +++ b/ext/mysqli/tests/mysqli_error_oo.phpt @@ -10,9 +10,6 @@ require_once 'skipifconnectfailure.inc'; error)) printf("[001] Expecting empty string, got %s/'%s'\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_execute_query.phpt b/ext/mysqli/tests/mysqli_execute_query.phpt index dafb37116c2f3..5730d827a4069 100644 --- a/ext/mysqli/tests/mysqli_execute_query.phpt +++ b/ext/mysqli/tests/mysqli_execute_query.phpt @@ -36,7 +36,7 @@ if (!($tmp = $link->execute_query("SELECT ? AS a, ? AS b, ? AS c", [42, "foo", n assert($tmp->fetch_assoc() === ['a' => '42', 'b' => 'foo', 'c' => null]); // prepare error -if (!($tmp = $link->execute_query("some random gibberish", [1, "foo"]))) { +if (false === $link->execute_query("some random gibberish", [1, "foo"])) { printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt index a5ddf5462a511..36067365ff67b 100644 --- a/ext/mysqli/tests/mysqli_explain_metadata.phpt +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -26,7 +26,7 @@ require_once 'skipifconnectfailure.inc'; $field_names[$name] = gettype($value); } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) $num_rows++; if (($tmp = mysqli_num_rows($res)) !== $num_rows) { @@ -43,12 +43,12 @@ require_once 'skipifconnectfailure.inc'; $num_fields, gettype($tmp), $tmp); } - foreach ($fields as $k => $field) { + foreach ($fields as $field) { $field->max_length = 0;// change it or we will get diff error if (isset($field_names[$field->name])) { unset($field_names[$field->name]); } else { - printf("[006] Unexpected field '%s', dumping info\n"); + printf("[006] Unexpected field '%s', dumping info\n", $field->name); var_dump($field); } } diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index cfe8f8464be2d..8cd3984d70376 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -86,14 +86,14 @@ require_once 'skipifconnectfailure.inc'; return false; } - if (!$link->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + if (!$link->query(sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { // don't bail, engine might not support the datatype return false; } if (is_null($php_value)) { if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { - printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error); + printf("[%04d] [%d] %s - %s\n", $offset + 1, $link->errno, $link->error, $sql); return false; } } else { @@ -104,7 +104,7 @@ require_once 'skipifconnectfailure.inc'; } } else { if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { - printf("[%04di] [%d] %s\n", $offset + 1, $link->errno, $link->error); + printf("[%04di] [%d] %s - %s\n", $offset + 1, $link->errno, $link->error, $sql); return false; } } diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt index 2ec58913fb552..6b3fe79a582b7 100644 --- a/ext/mysqli/tests/mysqli_fetch_array.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array.phpt @@ -31,7 +31,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { - printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link)); + printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } print "[011]\n"; var_dump(mysqli_fetch_array($res, MYSQLI_BOTH)); @@ -39,7 +39,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { printf("[012] Cannot run query, [%d] %s\n", - mysqli_errno($link), $mysqli_error($link)); + mysqli_errno($link), mysqli_error($link)); exit(1); } @@ -61,7 +61,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); - function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL, $binary_type = false) { + function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt index 4650475e73337..cb11d2793035a 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt @@ -12,7 +12,6 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; // do as much as we can do in 5 seconds - $start = microtime(true); for ($id = 100, $start = microtime(true); (microtime(true) - $start) < 5; $id++) { if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, '%s')", $id, mysqli_real_escape_string($link, chr(65 + ($id % 26)))))) { @@ -52,7 +51,7 @@ require_once 'skipifconnectfailure.inc'; } if ($row[0] !== $row['id']) { printf("[005] Unexpected result row[0] = '%s', row[id] = '%s', [%d] %s\n", - $row[0], $row[id], mysqli_errno($link), mysqli_error($link)); + $row[0], $row['id'], mysqli_errno($link), mysqli_error($link)); break; } diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt index 8639b7419b129..225ac6711bd2c 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -70,14 +70,14 @@ require_once 'skipifconnectfailure.inc'; return false; } - if (!$mysqli->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + if (!$mysqli->query(sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { // don't bail, engine might not support the datatype return false; } if (is_null($php_value)) { if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { - printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + printf("[%04d] [%d] %s - %s\n", $offset + 1, $mysqli->errno, $mysqli->error, $sql); return false; } } else { @@ -88,7 +88,7 @@ require_once 'skipifconnectfailure.inc'; } } else { if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { - printf("[%04di] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + printf("[%04di] [%d] %s - %s\n", $offset + 1, $mysqli->errno, $mysqli->error, $sql); return false; } } diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index 76b6e6fb1bc30..9f3197b903c4b 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -39,7 +39,6 @@ if (mysqli_get_server_version($link) < 50003) $max_value = 1; else $max_value = pow(2, $bits) - 1; - $tests = 0; if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id BIGINT, bit_value BIT(%d) NOT NULL, bit_null BIT(%d) DEFAULT NULL) ENGINE="%s"', $bits, $bits, $engine))) printf("[002 - %d] [%d] %s\n",$bits, mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt index 418a22a223e29..a5da83a9039b8 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt @@ -39,7 +39,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); /* Now do it with unbuffered queries */ - if (!$res = mysqli_real_query($link, "SELECT 1, 2")) { + if (false === mysqli_real_query($link, "SELECT 1, 2")) { printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (!$res = mysqli_use_result($link)) { @@ -49,7 +49,7 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_fetch_assoc($res)); mysqli_free_result($res); - if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2")) { + if (false === mysqli_real_query($link, "SELECT 1 AS a, 2")) { printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (!$res = mysqli_use_result($link)) { @@ -59,7 +59,7 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_fetch_assoc($res)); mysqli_free_result($res); - if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2, 2 as '2'")) { + if (false === mysqli_real_query($link, "SELECT 1 AS a, 2, 2 as '2'")) { printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (!$res = mysqli_use_result($link)) { @@ -69,7 +69,7 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_fetch_assoc($res)); mysqli_free_result($res); - if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2 as '2', 2")) { + if (false === mysqli_real_query($link, "SELECT 1 AS a, 2 as '2', 2")) { printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (!$res = mysqli_use_result($link)) { diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt index 1d7e38d6c10eb..8ab3443dde142 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt @@ -42,7 +42,7 @@ mysqli } /* some cyrillic (utf8) comes here */ - if (!$res = mysqli_query($link, "SET NAMES UTF8")) { + if (false === mysqli_query($link, "SET NAMES UTF8")) { printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } @@ -53,16 +53,16 @@ mysqli var_dump(mysqli_fetch_assoc($res)); mysqli_free_result($res); - if (!$res = mysqli_query($link, "CREATE TABLE автори_на_mysqlnd (id integer not null auto_increment primary key, име varchar(20) character set ucs2, фамилия varchar(20) character set utf8)")) { + if (false === mysqli_query($link, "CREATE TABLE автори_на_mysqlnd (id integer not null auto_increment primary key, име varchar(20) character set ucs2, фамилия varchar(20) character set utf8)")) { printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Андрей', 'Христов'), ('Георг', 'Рихтер'), ('Улф','Вендел')")) { + if (false === mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Андрей', 'Христов'), ('Георг', 'Рихтер'), ('Улф','Вендел')")) { printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Andrey', 'Hristov'), ('Georg', 'Richter'), ('Ulf','Wendel')")) { + if (false === mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('Andrey', 'Hristov'), ('Georg', 'Richter'), ('Ulf','Wendel')")) { printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('安德烈', 'Hristov'), ('格奥尔', 'Richter'), ('乌尔夫','Wendel')")) { + if (false === mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилия) VALUES ('安德烈', 'Hristov'), ('格奥尔', 'Richter'), ('乌尔夫','Wendel')")) { printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } @@ -75,7 +75,7 @@ mysqli } mysqli_free_result($res); - if (!$res = mysqli_query($link, "DROP TABLE автори_на_mysqlnd")) { + if (false === mysqli_query($link, "DROP TABLE автори_на_mysqlnd")) { printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt index 53eb3e6916947..935defa484d2c 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -187,7 +187,7 @@ mysqli_close($link); $column_def = array('col1 CHAR(1)', 'col2 CHAR(2)','INDEX idx_col1_col2(col1, col2)'); $expected_flags = array('col1' => 'MULTIPLE_KEY PART_KEY', 'col2' => 'PART_KEY'); $create = 'CREATE TABLE test(id INT, '; - foreach ($column_def as $k => $v) { + foreach ($column_def as $v) { $create .= sprintf('%s, ', $v); } $create = sprintf('%s)', substr($create, 0, -2)); @@ -198,7 +198,7 @@ mysqli_close($link); mysqli_errno($link), mysqli_error($link)); } // id column - skip it - $field = mysqli_fetch_field($res); + mysqli_fetch_field($res); while ($field = mysqli_fetch_field($res)) { if (!isset($expected_flags[$field->name])) { printf("[010] Found unexpected field '%s'\n", $field->name); diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt index 8a31ae25af3eb..39d7cb861d290 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt @@ -9,13 +9,12 @@ require_once 'skipifconnectfailure.inc'; --FILE-- lengths); - while ($row = $res->fetch_assoc()) + while ($res->fetch_assoc()) var_dump($res->lengths); var_dump($res->lengths); diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt index e6ab9245152fa..28e945db52f68 100644 --- a/ext/mysqli/tests/mysqli_fetch_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -122,7 +122,7 @@ require_once 'skipifconnectfailure.inc'; var_dump($obj = new mysqli_fetch_object_private_constructor(1, 2)); This does not fail. */ - $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b')); + mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b')); mysqli_free_result($res); try { diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index 0bc49bab8abc0..14f655f8b0b23 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -24,13 +24,9 @@ require_once 'skipifconnectfailure.inc'; if (!$res = mysqli_query($link, $sql = sprintf("SHOW CHARACTER SET LIKE '%s'", $character_set_connection))) printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_fetch_assoc($res); - if (empty($tmp)) + if (!mysqli_fetch_assoc($res)) printf("[010] Cannot fetch Maxlen and/or Comment, test will fail: $sql\n"); - $maxlen = (isset($tmp['Maxlen'])) ? $tmp['Maxlen'] : ''; - $comment = (isset($tmp['Description'])) ? $tmp['Description'] : ''; - if (!$res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $collation_connection))) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); $tmp = mysqli_fetch_assoc($res); diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt index 90823854d41ff..17900c5ad6090 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -85,7 +85,7 @@ mysqli.allow_local_infile=1 var_dump($info); - if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (false === my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); exit(1); @@ -243,7 +243,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -270,7 +270,7 @@ mysqli.allow_local_infile=1 ++$test_counter, mysqli_errno($link), mysqli_error($link)); for ($i = 0; $i < $num_rows - 1; $i++) - $row = mysqli_fetch_assoc($res); + mysqli_fetch_assoc($res); $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows - 1); $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows - 1); @@ -551,7 +551,7 @@ mysqli.allow_local_infile=1 mysqli_errno($link), mysqli_error($link)); $rows = 0; - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) $rows++; if (0 == $rows) @@ -617,7 +617,6 @@ mysqli.allow_local_infile=1 ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'DROP INDEX'); } - $info = $new_info; // RENAME TABLE if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test")) @@ -640,7 +639,6 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'RENAME TABLE'); } - $info = $new_info; if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test")) printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter, @@ -675,7 +673,6 @@ mysqli.allow_local_infile=1 printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE'); - $info = $new_info; if (!mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats_")) printf("[%03d] CREATE DATABASE failed, [%d] %s\n", ++$test_counter, @@ -693,7 +690,6 @@ mysqli.allow_local_infile=1 printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP DATABASE'); - $info = $new_info; } // CREATE SERVER, ALTER SERVER, DROP SERVER @@ -812,7 +808,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DELETE'); $info = $new_info; - if (!$res = mysqli_query($link, "TRUNCATE TABLE test")) + if (false === mysqli_query($link, "TRUNCATE TABLE test")) printf("[%03d] TRUNCATE failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -854,7 +850,7 @@ mysqli.allow_local_infile=1 printf("[%03d] Cannot insert new records, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + if (false === mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[%03d] Cannot SELECT with mysqli_real_query(), [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -862,7 +858,7 @@ mysqli.allow_local_infile=1 printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) @@ -871,7 +867,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, (string)($info['unbuffered_sets'] + 1), $test_counter, 'mysqli_use_result()'); $info = $new_info; - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + if (false === mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[%03d] Cannot SELECT with mysqli_real_query() II, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -879,7 +875,7 @@ mysqli.allow_local_infile=1 printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) diff --git a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt index aaf4098859132..a302e0bbf9998 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt @@ -29,7 +29,7 @@ require_once 'skipifconnectfailure.inc'; /* fetch all rows but the last one */ for ($i = 0; $i < $num_rows - 1; $i++) - $row = mysqli_fetch_assoc($res); + mysqli_fetch_assoc($res); /* enforce implicit cleaning of the wire and skipping the last row */ mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt index 08831200648d5..55db12d966a92 100644 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_get_warnings.phpt @@ -12,24 +12,12 @@ if (!$TEST_EXPERIMENTAL) next())) @@ -129,7 +117,7 @@ if (!$TEST_EXPERIMENTAL) if (3 != $i) printf("[034] Expecting three warnings, got %d warnings\n", $i); - $stmt = mysqli_stmt_init(); + $stmt = mysqli_stmt_init($mysqli); $warning = new mysqli_warning($stmt); if (false !== ($tmp = $warning->next())) printf("[035] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt index ce1d055075397..6b4c5be41a7d4 100644 --- a/ext/mysqli/tests/mysqli_info.phpt +++ b/ext/mysqli/tests/mysqli_info.phpt @@ -11,43 +11,42 @@ mysqli.allow_local_infile=1 --FILE-- = 100")) + if (false === mysqli_query($link, "UPDATE test SET label = 'b' WHERE id >= 100")) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) printf("[012] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "SELECT 1")) + if (false === mysqli_query($link, "SELECT 1")) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp)) printf("[014] Expecting null, got %s/%s\n", gettype($tmp), $tmp); - mysqli_free_result($res); // NOTE: no LOAD DATA INFILE test if ($dir = sys_get_temp_dir()) { diff --git a/ext/mysqli/tests/mysqli_insert_id.phpt b/ext/mysqli/tests/mysqli_insert_id.phpt index 7a2add8eb31fd..484bfc4b4d90c 100644 --- a/ext/mysqli/tests/mysqli_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_insert_id.phpt @@ -13,25 +13,24 @@ require_once 'skipifconnectfailure.inc'; if (0 !== ($tmp = mysqli_insert_id($link))) printf("[003] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { + if (false === mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (0 !== ($tmp = mysqli_insert_id($link))) printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - mysqli_free_result($res); // no auto_increment column - if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) { + if (false === mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) { printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (0 !== ($tmp = mysqli_insert_id($link))) printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) { + if (false === mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) { printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) { + if (false === mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) { printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (($last_id = mysqli_insert_id($link)) <= 0) @@ -101,13 +100,13 @@ require_once 'skipifconnectfailure.inc'; mysqli_query($link, "UNLOCK TABLE test"); } - if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) { + if (false === mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) { printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (1000 !== ($tmp = mysqli_insert_id($link))) printf("[021] Expecting int/1000, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) { + if (false === mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) { printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (1000 >= ($tmp = mysqli_insert_id($link))) diff --git a/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt index d8cdd633121ec..feb890a869e4f 100644 --- a/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt +++ b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt @@ -4,19 +4,7 @@ INSERT and packet overflow mysqli --SKIPIF-- --INI-- memory_limit=256M diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index 19e34caa19f40..0ed58d2ad04aa 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -19,12 +19,10 @@ require_once 'skipifconnectfailure.inc'; if (!$thread_id = mysqli_thread_id($link)) printf("[004] Cannot determine thread id, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_kill($link, $thread_id); - if (!is_bool($tmp)) - printf("[005] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + mysqli_kill($link, $thread_id); if ($res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) - pintf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); var_dump($error = mysqli_error($link)); if (!is_string($error) || ('' === $error)) diff --git a/ext/mysqli/tests/mysqli_more_results.phpt b/ext/mysqli/tests/mysqli_more_results.phpt index 5c1f453cb9b0f..4cf99b801eb4c 100644 --- a/ext/mysqli/tests/mysqli_more_results.phpt +++ b/ext/mysqli/tests/mysqli_more_results.phpt @@ -39,7 +39,7 @@ require_once 'skipifconnectfailure.inc'; // NOTE: if you use mysqli_use_result() with mysqli_more_results() or any other info function, // you must fetch all rows before you can loop to the next result set! // See also the MySQL Reference Manual: mysql_use_result() - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); if (mysqli_more_results($link)) diff --git a/ext/mysqli/tests/mysqli_multi_query.phpt b/ext/mysqli/tests/mysqli_multi_query.phpt index 618ffe2085e3a..69950aec4c04e 100644 --- a/ext/mysqli/tests/mysqli_multi_query.phpt +++ b/ext/mysqli/tests/mysqli_multi_query.phpt @@ -19,7 +19,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; do { $res = mysqli_store_result($link); - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); $i++; @@ -33,7 +33,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); printf("%d/%d\n", $i, mysqli_insert_id($link)); @@ -46,7 +46,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) $i++; mysqli_free_result($res); } @@ -77,7 +77,7 @@ require_once 'skipifconnectfailure.inc'; printf("[015 - %d] [%d] %s\n", $res_num, mysqli_errno($link), mysqli_error($link)); if (count($lengths) != 2) - printf("[016 - %d] Expecting 2 column lengths got %d [%d] %s\n", $res_num, count($lengths)); + printf("[016 - %d] Expecting 2 column lengths got %d\n", $res_num, count($lengths)); foreach ($lengths as $k => $length) if ($length <= 0) @@ -87,7 +87,7 @@ require_once 'skipifconnectfailure.inc'; } if ($num_rows != 1) - printf("[018 - %d] Expecting 1 row, got %d rows\n", $num_rows); + printf("[018 - %d] Expecting 1 row, got %d rows\n", $res_num, $num_rows); $res_num++; diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt index 59a8719cbbe6b..11049dfa09ecb 100644 --- a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -18,7 +18,7 @@ mysqlnd.net_read_timeout=1 printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); } - if (!$res = mysqli_query($link, "SELECT SLEEP(5)")) + if (false === mysqli_query($link, "SELECT SLEEP(5)")) printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_no_reconnect.phpt b/ext/mysqli/tests/mysqli_no_reconnect.phpt index d74f57557b229..929cb1dcd0c23 100644 --- a/ext/mysqli/tests/mysqli_no_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_no_reconnect.phpt @@ -67,7 +67,7 @@ require_once 'skipifconnectfailure.inc'; if (false !== @mysqli_ping($link)) printf("[010] Reconnect should not have happened"); - if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + if (@mysqli_query($link, "SELECT DATABASE() as _dbname")) printf("[011] Executing a query should not be possible, connection should be closed, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -111,7 +111,7 @@ require_once 'skipifconnectfailure.inc'; if (false !== ($tmp = @mysqli_ping($link))) printf("[016] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); - if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + if (@mysqli_query($link, "SELECT DATABASE() as _dbname")) printf("[017] Running a query should not be possible, connection should be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_num_fields.phpt b/ext/mysqli/tests/mysqli_num_fields.phpt index 3022a89115249..cd24d90085c12 100644 --- a/ext/mysqli/tests/mysqli_num_fields.phpt +++ b/ext/mysqli/tests/mysqli_num_fields.phpt @@ -10,7 +10,7 @@ require_once 'skipifconnectfailure.inc'; query("SELECT id FROM test WHERE id = 1")) + if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) { printf("[%03d + 003] [%d] %s\n", $offset, $link->errno, $link->error); return false; + } if (!$row = mysqli_fetch_assoc($res)) { printf("[%03d + 004] [%d] %s\n", $offset, $link->errno, $link->error); diff --git a/ext/mysqli/tests/mysqli_pconn_max_links.phpt b/ext/mysqli/tests/mysqli_pconn_max_links.phpt index 4cf28f6819e0b..88b89228e1116 100644 --- a/ext/mysqli/tests/mysqli_pconn_max_links.phpt +++ b/ext/mysqli/tests/mysqli_pconn_max_links.phpt @@ -29,7 +29,7 @@ mysqli die("skip GRANT failed"); } - if (!($link_pcontest = @my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { + if (!@my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket)) { mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); mysqli_query($link, 'DROP USER pcontest@localhost'); @@ -56,7 +56,7 @@ mysqli.rollback_on_cached_plink=1 !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { printf("[000] Init failed, [%d] %s\n", - mysqli_errno($plink), mysqli_error($plink)); + mysqli_errno($link), mysqli_error($link)); } try { @@ -129,9 +129,10 @@ mysqli.rollback_on_cached_plink=1 var_dump(mysqli_get_links_stats()); // this fails and we have 0 (<= $num_plinks) connections + // Do not remove the variable assignment as it is important that we have 2 active connections if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) printf("[010] Can connect using the old password, [%d] %s\n", - mysqli_connect_errno($link), mysqli_connect_error($link)); + mysqli_connect_errno(), mysqli_connect_error()); echo "After second pconnect:"; var_dump(mysqli_get_links_stats()); @@ -168,6 +169,7 @@ mysqli.rollback_on_cached_plink=1 mysqli_free_result($res); var_dump($row); + // Do not remove the variable assignment as it is important that we have 2 active connections if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) { printf("[015] Can open more persistent connections than allowed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); diff --git a/ext/mysqli/tests/mysqli_phpinfo.phpt b/ext/mysqli/tests/mysqli_phpinfo.phpt index d4a464e99f169..6df4e82dfd543 100644 --- a/ext/mysqli/tests/mysqli_phpinfo.phpt +++ b/ext/mysqli/tests/mysqli_phpinfo.phpt @@ -46,7 +46,7 @@ require_once 'skipifconnectfailure.inc'; 'mysqli.allow_local_infile', 'mysqli.local_infile_directory', 'mysqli.allow_persistent', 'mysqli.max_persistent' ); - foreach ($expected as $k => $entry) + foreach ($expected as $entry) if (!stristr($phpinfo, $entry)) printf("[010] Could not find entry for '%s'\n", $entry); diff --git a/ext/mysqli/tests/mysqli_ping.phpt b/ext/mysqli/tests/mysqli_ping.phpt index ef1a3e055969e..626f2330dcb38 100644 --- a/ext/mysqli/tests/mysqli_ping.phpt +++ b/ext/mysqli/tests/mysqli_ping.phpt @@ -18,7 +18,7 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_ping($link)); // provoke an error to check if mysqli_ping resets it - $res = mysqli_query($link, 'SELECT * FROM unknown_table'); + mysqli_query($link, 'SELECT * FROM unknown_table'); if (!($errno = mysqli_errno($link))) printf("[003] Statement should have caused an error\n"); diff --git a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt index 30325aa044f2b..f95bc99276e24 100644 --- a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt +++ b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt @@ -44,11 +44,11 @@ require_once 'skipifconnectfailure.inc'; mysqli_close($link); $links = array(); - for ($i = 0; $i < count($queries); $i++) { + foreach ($queries as $query) { $link = get_connection(); - if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + if (true !== ($tmp = mysqli_query($link, $query, MYSQLI_ASYNC | MYSQLI_USE_RESULT))) printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); // WARNING KLUDGE NOTE @@ -57,7 +57,7 @@ require_once 'skipifconnectfailure.inc'; usleep(20000); $links[mysqli_thread_id($link)] = array( - 'query' => $queries[$i], + 'query' => $query, 'link' => $link, 'processed' => false, ); @@ -66,7 +66,7 @@ require_once 'skipifconnectfailure.inc'; $saved_errors = array(); do { $poll_links = $poll_errors = $poll_reject = array(); - foreach ($links as $thread_id => $link) { + foreach ($links as $link) { if (!$link['processed']) { $poll_links[] = $link['link']; $poll_errors[] = $link['link']; @@ -93,7 +93,7 @@ require_once 'skipifconnectfailure.inc'; if (is_object($res = mysqli_reap_async_query($link))) { // result set object - while ($row = mysqli_fetch_assoc($res)) { + while (mysqli_fetch_assoc($res)) { // eat up all results ; } @@ -120,9 +120,9 @@ require_once 'skipifconnectfailure.inc'; } if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) - printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + printf("[005] Expecting true got %s/%s\n", gettype($res), var_export($res, true)); if (!$row = mysqli_fetch_row($res)) - printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + printf("[006] Expecting true got %s/%s\n", gettype($row), var_export($row, true)); mysqli_free_result($res); } diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt index 8fcb9b2fbbac4..93cdc77be4005 100644 --- a/ext/mysqli/tests/mysqli_poll_reference.phpt +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -42,7 +42,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! // The behaviour is in line with stream_select(). Be warned, be careful. $links = $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } @@ -73,7 +73,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! $links = $errors = array($mysqli1, $mysqli2); $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } foreach ($links as $link) { @@ -103,7 +103,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! $links = array($mysqli1, $mysqli2); $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } foreach ($links as $link) { @@ -133,7 +133,7 @@ if (mysqli_get_server_version($link) < 50012) break; } $links = $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } // WARNING: Due to the reference issue none of these should ever fire! @@ -176,7 +176,7 @@ if (mysqli_get_server_version($link) < 50012) } $links = $errors = $reject = $all; ob_start(); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { $tmp = ob_get_contents(); ob_end_clean(); if ($tmp != '') { @@ -193,7 +193,7 @@ if (mysqli_get_server_version($link) < 50012) } } while ($processed < 2); - $ready = mysqli_poll($links, $errors, $reject, 0, 50000); + mysqli_poll($links, $errors, $reject, 0, 50000); mysqli_close($mysqli1); mysqli_close($mysqli2); diff --git a/ext/mysqli/tests/mysqli_prepare_no_object.phpt b/ext/mysqli/tests/mysqli_prepare_no_object.phpt index c488cbe50591f..7ef3728535fe5 100644 --- a/ext/mysqli/tests/mysqli_prepare_no_object.phpt +++ b/ext/mysqli/tests/mysqli_prepare_no_object.phpt @@ -11,11 +11,11 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; if (false !== ($tmp = mysqli_prepare($link, false))) - printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("a) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (false !== ($tmp = mysqli_prepare($link, ''))) - printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("b) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); @@ -23,11 +23,11 @@ require_once 'skipifconnectfailure.inc'; $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); if (false !== ($tmp = $mysqli->prepare(false))) - printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); if (false !== ($tmp = $mysqli->prepare(''))) - printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); print "done!"; diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index adb416708fc06..640dbacaaf2c4 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -45,7 +45,7 @@ require_once 'skipifconnectfailure.inc'; // let's try to play with stored procedures mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); if (mysqli_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { - $res = mysqli_query($link, 'CALL p(@version)'); + mysqli_query($link, 'CALL p(@version)'); $res = mysqli_query($link, 'SELECT @version AS p_version'); $tmp = mysqli_fetch_assoc($res); diff --git a/ext/mysqli/tests/mysqli_query_iterators.phpt b/ext/mysqli/tests/mysqli_query_iterators.phpt index ea48fa864db99..91acc529f90cf 100644 --- a/ext/mysqli/tests/mysqli_query_iterators.phpt +++ b/ext/mysqli/tests/mysqli_query_iterators.phpt @@ -25,7 +25,8 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); try { foreach ($res as $row) { - $row; + echo "Iterating over a closed result set should not work\n"; + var_dump($row); } } catch (Error $exception) { echo $exception->getMessage() . "\n"; diff --git a/ext/mysqli/tests/mysqli_query_stored_proc.phpt b/ext/mysqli/tests/mysqli_query_stored_proc.phpt index dbd22fbb38f43..e9590e4a5540b 100644 --- a/ext/mysqli/tests/mysqli_query_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_query_stored_proc.phpt @@ -107,8 +107,7 @@ END;')) { if (!$res = mysqli_query($link, 'SELECT @version as _vers')) printf("[014] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!$row = mysqli_fetch_assoc($res) || - $row['_vers'] == 'unknown') + if (!($row = mysqli_fetch_assoc($res)) || $row['_vers'] == 'unknown') printf("[015] Results seem wrong, got %s, [%d] %s\n", $row['_vers'], mysqli_errno($link), mysqli_error($link)); @@ -135,8 +134,7 @@ END;')) { if (!$res = mysqli_query($link, 'SELECT @version as _vers')) printf("[021] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!$row = mysqli_fetch_assoc($res) || - $row['_vers'] == 'myversion') + if (!($row = mysqli_fetch_assoc($res)) || $row['_vers'] !== 'myversion') printf("[022] Results seem wrong, got %s, [%d] %s\n", $row['_vers'], mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_query_unicode.phpt b/ext/mysqli/tests/mysqli_query_unicode.phpt index c8c9e052de945..0e4a1095cf8dc 100644 --- a/ext/mysqli/tests/mysqli_query_unicode.phpt +++ b/ext/mysqli/tests/mysqli_query_unicode.phpt @@ -40,7 +40,7 @@ mysqli_close($link); // let's try to play with stored procedures mysqli_query($link, 'DROP PROCEDURE IF EXISTS процедурка'); if (mysqli_query($link, 'CREATE PROCEDURE процедурка(OUT версия VARCHAR(25)) BEGIN SELECT VERSION() INTO версия; END;')) { - $res = mysqli_query($link, 'CALL процедурка(@version)'); + mysqli_query($link, 'CALL процедурка(@version)'); $res = mysqli_query($link, 'SELECT @version AS п_версия'); $tmp = mysqli_fetch_assoc($res); diff --git a/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt b/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt index 7a452d3a23cf2..ad595366c3176 100644 --- a/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt +++ b/ext/mysqli/tests/mysqli_real_connect_compression_error.phpt @@ -24,7 +24,7 @@ $data_size = 16777174; // Insert with compression disabled: $mysqli = mysqli_init(); -$result = my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket); +my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket); $mysqli->query("DROP TABLE IF EXISTS test"); $mysqli->query("CREATE TABLE test (`blob` LONGBLOB NOT NULL) ENGINE=MyISAM"); @@ -37,7 +37,7 @@ $mysqli->close(); // Insert with compression enabled: $mysqli = mysqli_init(); -$result = my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS); +my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS); $data = str_repeat("x", $data_size); $mysqli->query("INSERT INTO $db.test(`blob`) VALUE ('$data')"); diff --git a/ext/mysqli/tests/mysqli_reap_async_query.phpt b/ext/mysqli/tests/mysqli_reap_async_query.phpt index 19f907bd4a36c..fae4f91a1d9c5 100644 --- a/ext/mysqli/tests/mysqli_reap_async_query.phpt +++ b/ext/mysqli/tests/mysqli_reap_async_query.phpt @@ -18,10 +18,6 @@ require_once 'skipifconnectfailure.inc'; return $link; } - if (!$link = get_connection()) - printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - - function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) { if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 50 * 1000))) diff --git a/ext/mysqli/tests/mysqli_reap_async_query_error.phpt b/ext/mysqli/tests/mysqli_reap_async_query_error.phpt index e7de2b6c9fe92..f7cbfbd363ed5 100644 --- a/ext/mysqli/tests/mysqli_reap_async_query_error.phpt +++ b/ext/mysqli/tests/mysqli_reap_async_query_error.phpt @@ -19,7 +19,7 @@ mysqli::poll($reads, $errors, $rejects, 1); $link = $reads[0]; try { - $rs = $link->reap_async_query(); + $link->reap_async_query(); } catch (mysqli_sql_exception $exception) { echo $exception->getMessage() . "\n"; } diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index 8c896af7657af..f1d7fba992d39 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -36,7 +36,7 @@ if (!have_innodb($link)) /* note that there is no savepoint my... */ if (false !== ($tmp = mysqli_release_savepoint($link, 'my'))) - printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[010] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -46,13 +46,13 @@ if (!have_innodb($link)) printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); if (true !== ($tmp = mysqli_savepoint($link, 'my'))) - printf("[013] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[013] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); $res = mysqli_query($link, "SELECT * FROM test"); var_dump($res->fetch_assoc()); if (true !== ($tmp = mysqli_release_savepoint($link, 'my'))) - printf("[014] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[014] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); print "done!"; ?> diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index afde537aee4d4..19b70a0f2b468 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -55,7 +55,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); while(mysqli_more_results($link)) { mysqli_next_result($link); - $res = mysqli_store_result($link); + mysqli_store_result($link); } mysqli_next_result($link); @@ -85,7 +85,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); while(mysqli_more_results($link)) { mysqli_next_result($link); - $res = mysqli_store_result($link); + mysqli_store_result($link); } mysqli_next_result($link); @@ -211,8 +211,6 @@ require_once 'skipifconnectfailure.inc'; TODO: */ - $log_slow_queries = false; - $log_queries_not_using_indexes = false; mysqli_report(MYSQLI_REPORT_OFF); mysqli_report(MYSQLI_REPORT_INDEX); @@ -227,7 +225,7 @@ require_once 'skipifconnectfailure.inc'; if (!$row = mysqli_fetch_assoc($res)) printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $log_slow_query = ('ON' == $row['Value']); + $log_slow_queries = ('ON' == $row['Value']); if (mysqli_get_server_version($link) >= 50111) { // this might cause a warning - no index used @@ -301,8 +299,6 @@ require_once 'skipifconnectfailure.inc'; !mysqli_query($link, 'DELETE FROM test WHERE id > 50', MYSQLI_USE_RESULT)) printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_thread_id($link); - mysqli_close($link); print "done!"; ?> diff --git a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt index f0799120742b1..1b9c8601ba7ca 100644 --- a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt +++ b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt @@ -15,7 +15,6 @@ require_once 'skipifconnectfailure.inc'; exit(1); } - $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); $invalidModes = [-1, 152]; foreach ($invalidModes as $mode) { try { diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index 810a0842498eb..0de39d7d71546 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -36,7 +36,7 @@ if (!have_innodb($link)) /* overrule autocommit */ if (true !== ($tmp = mysqli_savepoint($link, 'my'))) - printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[010] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_select_db.phpt b/ext/mysqli/tests/mysqli_select_db.phpt index 33c55c12409c7..a0c38ebbb676c 100644 --- a/ext/mysqli/tests/mysqli_select_db.phpt +++ b/ext/mysqli/tests/mysqli_select_db.phpt @@ -45,7 +45,7 @@ require_once 'skipifconnectfailure.inc'; } if (!$link->select_db($db)) - printf("[012] Failed to set '%s' as current DB; [%d] %s\n", $link->errno, $link->error); + printf("[012] Failed to set '%s' as current DB; [%d] %s\n", $db, $link->errno, $link->error); if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -81,9 +81,9 @@ require_once 'skipifconnectfailure.inc'; if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) - printf("[018] [%d] %s\n"); + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $row = $res->fetch_assoc(); + $res->fetch_assoc(); $res->free(); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 4dff9668b5315..4a873f65eb439 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -17,7 +17,6 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR mysqli_close($link); } else { die(sprintf("skip Requires character set latin1 or latin2\n")); - mysqli_close($link); } ?> --FILE-- diff --git a/ext/mysqli/tests/mysqli_stat.phpt b/ext/mysqli/tests/mysqli_stat.phpt index d58aa0863d87e..4417cb265b809 100644 --- a/ext/mysqli/tests/mysqli_stat.phpt +++ b/ext/mysqli/tests/mysqli_stat.phpt @@ -17,7 +17,7 @@ require_once 'skipifconnectfailure.inc'; if ((!is_string($tmp = mysqli_stat($link))) || ('' === $tmp)) printf("[004] Expecting non empty string, got %s/'%s', [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysql_error($link)); + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index 942711faa141c..f7de1e04c604c 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -11,9 +11,9 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; $valid_attr = array( - "max_length" => MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, - "cursor_type" => MYSQLI_STMT_ATTR_CURSOR_TYPE, - "prefetch_rows" => MYSQLI_STMT_ATTR_PREFETCH_ROWS, + MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, + MYSQLI_STMT_ATTR_CURSOR_TYPE, + MYSQLI_STMT_ATTR_PREFETCH_ROWS, ); $stmt = mysqli_stmt_init($link); @@ -25,17 +25,17 @@ require_once 'skipifconnectfailure.inc'; echo $e->getMessage() . \PHP_EOL; } - foreach ($valid_attr as $k => $attr) { - /* This can't happen anymore as it only returns int */ - if (false === ($tmp = mysqli_stmt_attr_get($stmt, $attr))) { - printf("[006] Expecting any type, but not boolean/false, got %s/%s for attribute %s/%s\n", - gettype($tmp), $tmp, $k, $attr); + foreach ($valid_attr as $attr) { + try { + mysqli_stmt_attr_get($stmt, $attr); + } catch (Throwable $exception) { + echo $exception->getMessage() . "\n"; } } $stmt->close(); - foreach ($valid_attr as $k => $attr) { + foreach ($valid_attr as $attr) { try { mysqli_stmt_attr_get($stmt, $attr); } catch (Throwable $exception) { diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 304046919a1ab..070d4a389bca3 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -10,15 +10,6 @@ require_once 'skipifconnectfailure.inc'; store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[007] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } @@ -71,9 +60,7 @@ require_once 'skipifconnectfailure.inc'; $stmt->store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[008] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } @@ -91,9 +78,7 @@ require_once 'skipifconnectfailure.inc'; $stmt->store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[009] max_length should not be set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt index 180de7cc43f26..c4b0c21f25867 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -382,14 +382,14 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) printf("[2010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - foreach ($value_list as $k => $values) { + foreach ($value_list as $values) { if (!mysqli_stmt_bind_param($stmt, 'is', $values['id'], $values['label'])) { printf("[2011] bind_param() failed for id = %d, [%d] %s\n", $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); continue; } if (!$stmt->execute()) - printf("[2012] [%d] execute() failed for id = %d, [%d] %s\n", + printf("[2012] execute() failed for id = %d, [%d] %s\n", $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (!$res = mysqli_query($link, sprintf("SELECT label FROM test WHERE id = %d", $values['id']))) diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt index 40296ad63d2d4..844d2974af00c 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt @@ -309,7 +309,6 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) printf("[050] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - $types = 'i'; $id = 1; $params = array( 0 => $stmt, diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index 5a210f3d2e356..d4d61380ff2ea 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -275,7 +275,7 @@ require_once 'skipifconnectfailure.inc'; try { mysqli_stmt_bind_result($stmt, $id); } catch (\ArgumentCountError $e) { - $e->getMessage() . \PHP_EOL; + echo $e->getMessage() . \PHP_EOL; } mysqli_stmt_close($stmt); @@ -293,4 +293,5 @@ Number of bind variables doesn't match number of fields in prepared statement Number of bind variables doesn't match number of fields in prepared statement int(1) %s(1) "a" +Number of bind variables doesn't match number of fields in prepared statement done! diff --git a/ext/mysqli/tests/mysqli_stmt_close.phpt b/ext/mysqli/tests/mysqli_stmt_close.phpt index d031077009a09..89d278060161c 100644 --- a/ext/mysqli/tests/mysqli_stmt_close.phpt +++ b/ext/mysqli/tests/mysqli_stmt_close.phpt @@ -23,8 +23,7 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); try { mysqli_stmt_close($stmt); @@ -48,8 +47,7 @@ require_once 'skipifconnectfailure.inc'; $link->query('KILL '.mysqli_thread_id($link)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); mysqli_close($link); @@ -69,8 +67,7 @@ require_once 'skipifconnectfailure.inc'; $link->query('KILL '.mysqli_thread_id($link)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[017] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); print "done!"; ?> diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index 21f8286cac087..a36daebc7951f 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -33,24 +33,21 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_store_result($stmt)) printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 2))) - printf("[009] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, 2); if (!mysqli_stmt_fetch($stmt)) printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); var_dump($id); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 0))) - printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, 0); if (!mysqli_stmt_fetch($stmt)) printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); var_dump($id); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, mysqli_stmt_num_rows($stmt) + 100))) - printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, mysqli_stmt_num_rows($stmt) + 100); if (mysqli_stmt_fetch($stmt)) printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt index bdfc9c348ae28..03c070dad482f 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt @@ -52,7 +52,7 @@ if (mysqli_get_server_version($link) < 50503) { if (!mysqli_stmt_close($stmt)) printf("[012] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!$res = $link->query("SELECT 1")) + if (false === $link->query("SELECT 1")) printf("[013] [%d] %s\n", $link->errno, $link->error); } else { diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt index 48e2e6f8dec62..90348833e57f1 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt @@ -17,7 +17,7 @@ require_once 'skipifconnectfailure.inc'; !mysqli_stmt_execute($stmt) || !($result = mysqli_stmt_result_metadata($stmt)) || !mysqli_stmt_bind_result($stmt, $id, $bind_res) || - !($fields = mysqli_fetch_fields($result))) { + [] === mysqli_fetch_fields($result)) { printf("FAIL 1\n"); } while (mysqli_stmt_fetch($stmt)) { @@ -34,7 +34,7 @@ require_once 'skipifconnectfailure.inc'; printf("FAIL 2\n"); } print "OK: 1\n"; - if (!($fields = mysqli_fetch_fields($result))) + if ([] === mysqli_fetch_fields($result)) printf("Aua 3\n"); print "OK: 2\n"; while (mysqli_stmt_fetch($stmt)) { diff --git a/ext/mysqli/tests/mysqli_stmt_free_result.phpt b/ext/mysqli/tests/mysqli_stmt_free_result.phpt index e049e84104776..d512a23ee037b 100644 --- a/ext/mysqli/tests/mysqli_stmt_free_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_free_result.phpt @@ -28,14 +28,12 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); if (!mysqli_stmt_execute($stmt)) printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); if (false !== ($tmp = mysqli_stmt_store_result($stmt))) printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); @@ -54,8 +52,7 @@ require_once 'skipifconnectfailure.inc'; if (true !== ($tmp = mysqli_stmt_store_result($stmt))) printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); mysqli_stmt_close($stmt); diff --git a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt index a5352af94db8f..5178d2b609752 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt @@ -102,7 +102,7 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_bind_result($stmt, $id, $label)) printf("[020] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - $row = mysqli_fetch_assoc($res); + mysqli_fetch_assoc($res); if (NULL !== $id || NULL !== $label) printf("[021] Bound variables should not have been set\n"); mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_stmt_multires.phpt b/ext/mysqli/tests/mysqli_stmt_multires.phpt index 0352a464e86fa..94538cbc5d8d8 100644 --- a/ext/mysqli/tests/mysqli_stmt_multires.phpt +++ b/ext/mysqli/tests/mysqli_stmt_multires.phpt @@ -10,7 +10,6 @@ require_once 'skipifconnectfailure.inc'; query('DROP PROCEDURE IF EXISTS p123')) { printf("[001] [%d] %s\n", $link->error, $link->errno); } diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt index a29da62893fb3..8d73967777a60 100644 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt @@ -23,7 +23,7 @@ require_once 'skipifconnectfailure.inc'; printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (!is_object(($res = mysqli_stmt_result_metadata($stmt)))) - printf("[006] Expecting object, got %s/%s\n", gettype($tmp), $tmp); + printf("[006] Expecting object, got %s/%s\n", gettype($res), $res); if (2 !== ($tmp = mysqli_num_fields($res))) printf("[007] Expecting int/2, got %s/%s, [%d] %s\n", @@ -45,9 +45,7 @@ require_once 'skipifconnectfailure.inc'; var_dump($field0_fetch); - if (!is_array($tmp = mysqli_fetch_fields($res))) - printf("[011] Expecting array, got %s/%s, [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_fields($res); if (empty($tmp[0]) || empty($tmp[1]) || $tmp[0] != $field0_direct) { printf("[012] mysqli_fetch_fields() return value is suspicious\n"); diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt index cc4a927270914..dbf8dddb88e41 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt @@ -64,7 +64,7 @@ require_once 'skipifconnectfailure.inc'; assert(strlen($blob) <= $max_allowed_packet); try { - $tmp = mysqli_stmt_send_long_data($stmt, -1, $blob); + mysqli_stmt_send_long_data($stmt, -1, $blob); } catch (\ValueError $e) { echo $e->getMessage() . \PHP_EOL; } diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt index 5c7ffd9c6da46..79cf0aa794507 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt @@ -40,8 +40,6 @@ require_once 'skipifconnectfailure.inc'; // let's ignore upper limits for LONGBLOB (2^32) ... // maximum packet size up to which we test is 10M - $tmp = ''; - $blob = ''; $tmp = str_repeat('a', 1024); $limit = min(floor($max_allowed_packet / 1024 / 2), 10240); diff --git a/ext/mysqli/tests/mysqli_store_result.phpt b/ext/mysqli/tests/mysqli_store_result.phpt index f3d743916b7ca..2a35320a63aed 100644 --- a/ext/mysqli/tests/mysqli_store_result.phpt +++ b/ext/mysqli/tests/mysqli_store_result.phpt @@ -10,7 +10,7 @@ require_once 'skipifconnectfailure.inc'; Date: Sun, 18 Aug 2024 17:57:27 +0900 Subject: [PATCH 073/280] ext/bcmath: Optimize `bcdiv` processing (#14660) Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Co-authored-by: Gina Peter Banyard --- ext/bcmath/libbcmath/src/bcmath.h | 2 +- ext/bcmath/libbcmath/src/div.c | 582 +++++++++++++++++++++--------- 2 files changed, 410 insertions(+), 174 deletions(-) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 3ca5db6d408b1..75a17604f379f 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -146,7 +146,7 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale); *(result) = mul_ex; \ } while (0) -bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale); +bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, size_t scale); bool bc_modulo(bc_num num1, bc_num num2, bc_num *resul, size_t scale); diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 5d3f0439cc0b7..14477f35fb391 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -31,219 +31,455 @@ #include "bcmath.h" #include "private.h" +#include "convert.h" #include #include #include #include "zend_alloc.h" +static const BC_VECTOR POW_10_LUT[9] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 +}; -/* Some utility routines for the divide: First a one digit multiply. - NUM (with SIZE digits) is multiplied by DIGIT and the result is - placed into RESULT. It is written so that NUM and RESULT can be - the same pointers. */ - -static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char *result) +/* + * This function should be used when the divisor is not split into multiple chunks, i.e. when the size of the array is one. + * This is because the algorithm can be simplified. + * This function is therefore an optimized version of bc_standard_div(). + */ +static inline void bc_fast_div( + BC_VECTOR *numerator_vectors, size_t numerator_arr_size, BC_VECTOR divisor_vector, BC_VECTOR *quot_vectors, size_t quot_arr_size) { - size_t carry, value; - unsigned char *nptr, *rptr; + size_t numerator_top_index = numerator_arr_size - 1; + size_t quot_top_index = quot_arr_size - 1; + for (size_t i = 0; i < quot_arr_size - 1; i++) { + if (numerator_vectors[numerator_top_index - i] < divisor_vector) { + quot_vectors[quot_top_index - i] = 0; + /* numerator_vectors[numerator_top_index - i] < divisor_vector, so there will be no overflow. */ + numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM; + continue; + } + quot_vectors[quot_top_index - i] = numerator_vectors[numerator_top_index - i] / divisor_vector; + numerator_vectors[numerator_top_index - i] -= divisor_vector * quot_vectors[quot_top_index - i]; + numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM; + numerator_vectors[numerator_top_index - i] = 0; + } + /* last */ + quot_vectors[0] = numerator_vectors[0] / divisor_vector; +} - if (digit == 0) { - memset(result, 0, size); - } else { - if (digit == 1) { - memcpy(result, num, size); - } else { - /* Initialize */ - nptr = (unsigned char *) (num + size - 1); - rptr = (unsigned char *) (result + size - 1); - carry = 0; - - while (size-- > 0) { - value = *nptr-- * digit + carry; - *rptr-- = value % BASE; - carry = value / BASE; - } +/* + * Used when the divisor is split into 2 or more chunks. + * This use the restoring division algorithm. + * https://en.wikipedia.org/wiki/Division_algorithm#Restoring_division + */ +static inline void bc_standard_div( + BC_VECTOR *numerator_vectors, size_t numerator_arr_size, + BC_VECTOR *divisor_vectors, size_t divisor_arr_size, size_t divisor_len, + BC_VECTOR *quot_vectors, size_t quot_arr_size +) { + size_t numerator_top_index = numerator_arr_size - 1; + size_t divisor_top_index = divisor_arr_size - 1; + size_t quot_top_index = quot_arr_size - 1; + + BC_VECTOR div_carry = 0; + + /* + * Errors might occur between the true quotient and the temporary quotient calculated using only the high order digits. + * For example, the true quotient of 240 / 121 is 1. + * However, if it is calculated using only the high-order digits (24 / 12), we would get 2. + * We refer to this value of 2 as the temporary quotient. + * We also define E to be error between the true quotient and the temporary quotient, + * which in this case, is 1. + * + * Another example: Calculating 999_0000_0000 / 1000_9999 with base 10000. + * The true quotient is 9980, but if it is calculated using only the high-order digits (999 / 1000), we would get 0 + * If the temporary quotient is 0, we need to carry the digits to the next division, which is 999_0000 / 1000. + * The new temporary quotient we get is 9990, with error E = 10. + * + * Because we use the restoring division we need to perform E restorations, which can be significant if E is large. + * + * Therefore, for the error E to be at most 1 we adjust the number of high-order digits used to calculate the temporary quotient as follows: + * - Include BC_VECTOR_SIZE + 1 digits of the divisor used in the calculation of the temporary quotient. + The missing digits are filled in from the next array element. + * - Adjust the number of digits in the numerator similarly to what was done for the divisor. + * + * e.g. + * numerator = 123456780000 + * divisor = 123456789 + * base = 10000 + * numerator_arr = [0, 5678, 1234] + * divisor_arr = [6789, 2345, 1] + * numerator_top = 1234 + * divisor_top = 1 + * divisor_top_tmp = 12345 (+4 digits) + * numerator_top_tmp = 12345678 (+4 digits) + * tmp_quot = numerator_top_tmp / divisor_top_tmp = 1000 + * tmp_rem = -9000 + * tmp_quot is too large, so tmp_quot--, tmp_rem += divisor (restoring) + * quot = 999 + * rem = 123447789 + * + * Details: + * Suppose that when calculating the temporary quotient, only the high-order elements of the BC_VECTOR array are used. + * At this time, numerator and divisor can be considered to be decomposed as follows. (Here, B = 10^b, any b ∈ ℕ, any k ∈ ℕ) + * numerator = numerator_high * B^k + numerator_low + * divisor = divisor_high * B^k + divisor_low + * + * The error E can be expressed by the following formula. + * + * E = (numerator_high * B^k) / (divisor_high * B^k) - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low) + * <=> E = numerator_high / divisor_high - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low) + * <=> E = (numerator_high * (divisor_high * B^k + divisor_low) - (numerator_high * B^k + numerator_low) * divisor_high) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * + * Find the error MAX_E when the error E is maximum (0 <= E <= MAX_E). + * First, numerator_high, which only exists in the numerator, uses its maximum value. + * Considering carry-back, numerator_high can be expressed as follows. + * numerator_high = divisor_high * B + * Also, numerator_low is only present in the numerator, but since this is a subtraction, use the smallest possible value here, 0. + * numerator_low = 0 + * + * MAX_E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * + * divisor_low uses the maximum value. + * divisor_low = B^k - 1 + * MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1)) + * + * divisor_high uses the minimum value, but want to see how the number of digits affects the error, so represent + * the minimum value as: + * divisor_high = 10^x (any x ∈ ℕ) + * Since B = 10^b, the formula becomes: + * MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1)) + * <=> MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1)) + * + * Now let's make an approximation. Remove -1 from the numerator. Approximate the numerator to be + * large and the denominator to be small, such that MAX_E is less than this expression. + * Also, the denominator "(10^b)^k - 1" is never a negative value, so delete it. + * + * MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1)) + * MAX_E < (10^x * 10^b * (10^b)^k) / (10^x * 10^x * (10^b)^k) + * <=> MAX_E < 10^b / 10^x + * <=> MAX_E < 10^(b - x) + * + * Therefore, found that if the number of digits in base B and divisor_high are equal, the error will be less + * than 1 regardless of the number of digits in the value of k. + * + * Here, B is BC_VECTOR_BOUNDARY_NUM, so adjust the number of digits in high part of divisor to be BC_VECTOR_SIZE + 1. + */ + /* the number of usable digits, thus divisor_len % BC_VECTOR_SIZE == 0 implies we have BC_VECTOR_SIZE usable digits */ + size_t divisor_top_digits = divisor_len % BC_VECTOR_SIZE; + if (divisor_top_digits == 0) { + divisor_top_digits = BC_VECTOR_SIZE; + } + + size_t high_part_shift = POW_10_LUT[BC_VECTOR_SIZE - divisor_top_digits + 1]; + size_t low_part_shift = POW_10_LUT[divisor_top_digits - 1]; + BC_VECTOR divisor_high_part = divisor_vectors[divisor_top_index] * high_part_shift + divisor_vectors[divisor_top_index - 1] / low_part_shift; + for (size_t i = 0; i < quot_arr_size; i++) { + BC_VECTOR numerator_high_part = numerator_vectors[numerator_top_index - i] * high_part_shift + numerator_vectors[numerator_top_index - i - 1] / low_part_shift; + + /* + * Determine the temporary quotient. + * The maximum value of numerator_high is divisor_high * B in the previous example, so here numerator_high_part is + * divisor_high_part * BC_VECTOR_BOUNDARY_NUM. + * The number of digits in divisor_high_part is BC_VECTOR_SIZE + 1, so even if divisor_high_part is at its maximum value, + * it will never overflow here. + */ + numerator_high_part += div_carry * BC_VECTOR_BOUNDARY_NUM * high_part_shift; + + /* numerator_high_part < divisor_high_part => quotient == 0 */ + if (numerator_high_part < divisor_high_part) { + quot_vectors[quot_top_index - i] = 0; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; + continue; + } + + BC_VECTOR quot_guess = numerator_high_part / divisor_high_part; + + /* For sub, add the remainder to the high-order digit */ + numerator_vectors[numerator_top_index - i] += div_carry * BC_VECTOR_BOUNDARY_NUM; + + /* + * It is impossible for the temporary quotient to underestimate the true quotient. + * Therefore a temporary quotient of 0 implies the true quotient is also 0. + */ + if (quot_guess == 0) { + quot_vectors[quot_top_index - i] = 0; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; + continue; + } - if (carry != 0) { - *rptr = carry; + /* sub */ + BC_VECTOR sub; + BC_VECTOR borrow = 0; + BC_VECTOR *numerator_calc_bottom = numerator_vectors + numerator_arr_size - divisor_arr_size - i; + size_t j; + for (j = 0; j < divisor_arr_size - 1; j++) { + sub = divisor_vectors[j] * quot_guess + borrow; + BC_VECTOR sub_low = sub % BC_VECTOR_BOUNDARY_NUM; + borrow = sub / BC_VECTOR_BOUNDARY_NUM; + + if (numerator_calc_bottom[j] >= sub_low) { + numerator_calc_bottom[j] -= sub_low; + } else { + numerator_calc_bottom[j] += BC_VECTOR_BOUNDARY_NUM - sub_low; + borrow++; + } + } + /* last digit sub */ + sub = divisor_vectors[j] * quot_guess + borrow; + bool neg_remainder = numerator_calc_bottom[j] < sub; + numerator_calc_bottom[j] -= sub; + + /* If the temporary quotient is too large, add back divisor */ + BC_VECTOR carry = 0; + if (neg_remainder) { + quot_guess--; + for (j = 0; j < divisor_arr_size - 1; j++) { + numerator_calc_bottom[j] += divisor_vectors[j] + carry; + carry = numerator_calc_bottom[j] / BC_VECTOR_BOUNDARY_NUM; + numerator_calc_bottom[j] %= BC_VECTOR_BOUNDARY_NUM; } + /* last add */ + numerator_calc_bottom[j] += divisor_vectors[j] + carry; } + + quot_vectors[quot_top_index - i] = quot_guess; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; } } +static void bc_do_div( + const char *numerator, size_t numerator_readable_len, size_t numerator_bottom_extension, + const char *divisor, size_t divisor_len, bc_num *quot, size_t quot_len +) { + size_t divisor_arr_size = (divisor_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE; + size_t numerator_arr_size = (numerator_readable_len + numerator_bottom_extension + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE; + size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1; + size_t quot_real_arr_size = MIN(quot_arr_size, (quot_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE); + + BC_VECTOR *numerator_vectors = safe_emalloc(numerator_arr_size + divisor_arr_size + quot_arr_size, sizeof(BC_VECTOR), 0); + BC_VECTOR *divisor_vectors = numerator_vectors + numerator_arr_size; + BC_VECTOR *quot_vectors = divisor_vectors + divisor_arr_size; + + /* Fill with zeros and convert as many vector elements as needed */ + size_t numerator_vector_count = 0; + while (numerator_bottom_extension >= BC_VECTOR_SIZE) { + numerator_vectors[numerator_vector_count] = 0; + numerator_bottom_extension -= BC_VECTOR_SIZE; + numerator_vector_count++; + } -/* The full division routine. This computes N1 / N2. It returns - true if the division is ok and the result is in QUOT. The number of - digits after the decimal point is SCALE. It returns false if division - by zero is tried. The algorithm is found in Knuth Vol 2. p237. */ -bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale) -{ - bc_num qval; - unsigned char *num1, *num2; - unsigned char *ptr1, *ptr2, *n2ptr, *qptr; - int scale1, val; - unsigned int len1, len2, scale2, qdigits, extra, count; - unsigned int qdig, qguess, borrow, carry; - unsigned char *mval; - unsigned int norm; - bool zero; - - /* Test for divide by zero. */ - if (bc_is_zero(n2)) { - return false; + size_t numerator_bottom_read_len = BC_VECTOR_SIZE - numerator_bottom_extension; + + size_t base; + size_t numerator_read = 0; + if (numerator_bottom_read_len < BC_VECTOR_SIZE) { + numerator_read = MIN(numerator_bottom_read_len, numerator_readable_len); + base = POW_10_LUT[numerator_bottom_extension]; + numerator_vectors[numerator_vector_count] = 0; + for (size_t i = 0; i < numerator_read; i++) { + numerator_vectors[numerator_vector_count] += *numerator * base; + base *= BASE; + numerator--; + } + numerator_vector_count++; } - /* Test for divide by 1. If it is we must truncate. */ - if (n2->n_scale == 0 && n2->n_len == 1 && *n2->n_value == 1) { - qval = bc_new_num (n1->n_len, scale); - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - memcpy(qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale, scale)); - bc_free_num (quot); - *quot = qval; + /* Bulk convert numerator and divisor to vectors */ + if (numerator_readable_len > numerator_read) { + bc_convert_to_vector(numerator_vectors + numerator_vector_count, numerator, numerator_readable_len - numerator_read); } + bc_convert_to_vector(divisor_vectors, divisor, divisor_len); - /* Set up the divide. Move the decimal point on n1 by n2's scale. - Remember, zeros on the end of num2 are wasted effort for dividing. */ - scale2 = n2->n_scale; - n2ptr = (unsigned char *) n2->n_value + n2->n_len + scale2 - 1; - while ((scale2 > 0) && (*n2ptr == 0)) { - scale2--; - n2ptr--; + /* Do the division */ + if (divisor_arr_size == 1) { + bc_fast_div(numerator_vectors, numerator_arr_size, divisor_vectors[0], quot_vectors, quot_arr_size); + } else { + bc_standard_div(numerator_vectors, numerator_arr_size, divisor_vectors, divisor_arr_size, divisor_len, quot_vectors, quot_arr_size); } - len1 = n1->n_len + scale2; - scale1 = n1->n_scale - scale2; - extra = MAX(scale - scale1, 0); + /* Convert to bc_num */ + char *qptr = (*quot)->n_value; + char *qend = qptr + quot_len - 1; + + size_t i; + for (i = 0; i < quot_real_arr_size - 1; i++) { +#if BC_VECTOR_SIZE == 4 + bc_write_bcd_representation(quot_vectors[i], qend - 3); + qend -= 4; +#else + bc_write_bcd_representation(quot_vectors[i] / 10000, qend - 7); + bc_write_bcd_representation(quot_vectors[i] % 10000, qend - 3); + qend -= 8; +#endif + } - num1 = (unsigned char *) safe_emalloc(1, n1->n_len + n1->n_scale, extra + 2); - memset(num1, 0, n1->n_len + n1->n_scale + extra + 2); - memcpy(num1 + 1, n1->n_value, n1->n_len + n1->n_scale); + while (qend >= qptr) { + *qend-- = quot_vectors[i] % BASE; + quot_vectors[i] /= BASE; + } - len2 = n2->n_len + scale2; - num2 = (unsigned char *) safe_emalloc(1, len2, 1); - memcpy(num2, n2->n_value, len2); - *(num2 + len2) = 0; - n2ptr = num2; - while (*n2ptr == 0) { - n2ptr++; - len2--; + efree(numerator_vectors); +} + +bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) +{ + /* divide by zero */ + if (bc_is_zero(divisor)) { + return false; } - /* Calculate the number of quotient digits. */ - if (len2 > len1 + scale) { - qdigits = scale + 1; - zero = true; - } else { - zero = false; - if (len2 > len1) { - /* One for the zero integer part. */ - qdigits = scale + 1; - } else { - qdigits = len1 - len2 + scale + 1; - } + bc_free_num(quot); + + /* If numerator is zero, the quotient is always zero. */ + if (bc_is_zero(numerator)) { + *quot = bc_copy_num(BCG(_zero_)); + return true; } - /* Allocate and zero the storage for the quotient. */ - qval = bc_new_num (qdigits - scale, scale); + /* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */ + if (_bc_do_compare(divisor, BCG(_one_), scale, false) == BCMATH_EQUAL) { + size_t quot_scale = MIN(numerator->n_scale, scale); + *quot = bc_new_num_nonzeroed(numerator->n_len, quot_scale); + char *qptr = (*quot)->n_value; + memcpy(qptr, numerator->n_value, numerator->n_len + quot_scale); + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + _bc_rm_leading_zeros(*quot); + return true; + } - /* Allocate storage for the temporary storage mval. */ - mval = (unsigned char *) safe_emalloc(1, len2, 1); + char *numeratorptr = numerator->n_value; + char *numeratorend = numeratorptr + numerator->n_len + numerator->n_scale - 1; + size_t numerator_len = numerator->n_len; + size_t numerator_scale = numerator->n_scale; + + char *divisorptr = divisor->n_value; + char *divisorend = divisorptr + divisor->n_len + divisor->n_scale - 1; + size_t divisor_len = divisor->n_len; + size_t divisor_scale = divisor->n_scale; + size_t divisor_int_right_zeros = 0; + + /* remove divisor trailing zeros */ + while (*divisorend == 0 && divisor_scale > 0) { + divisorend--; + divisor_scale--; + } + while (*divisorend == 0) { + divisorend--; + divisor_int_right_zeros++; + } - /* Now for the full divide algorithm. */ - if (!zero) { - /* Normalize */ - norm = 10 / ((int) *n2ptr + 1); - if (norm != 1) { - _one_mult(num1, len1 + scale1 + extra + 1, norm, num1); - _one_mult(n2ptr, len2, norm, n2ptr); - } + if (*numeratorptr == 0 && numerator_len == 1) { + numeratorptr++; + numerator_len = 0; + } - /* Initialize divide loop. */ - qdig = 0; - if (len2 > len1) { - qptr = (unsigned char *) qval->n_value + len2 - len1; - } else { - qptr = (unsigned char *) qval->n_value; - } + size_t numerator_top_extension = 0; + size_t numerator_bottom_extension = 0; + if (divisor_scale > 0) { + /* + * e.g. divisor_scale = 4 + * divisor = .0002, to be 2 or divisor = 200.001, to be 200001 + * numerator = .03, to be 300 or numerator = .000003, to be .03 + * numerator may become longer than the original data length due to the addition of + * trailing zeros in the integer part. + */ + numerator_len += divisor_scale; + numerator_bottom_extension = numerator_scale < divisor_scale ? divisor_scale - numerator_scale : 0; + numerator_scale = numerator_scale > divisor_scale ? numerator_scale - divisor_scale : 0; + divisor_len += divisor_scale; + divisor_scale = 0; + } else if (divisor_int_right_zeros > 0) { + /* + * e.g. divisor_int_right_zeros = 4 + * divisor = 2000, to be 2 + * numerator = 30, to be .03 or numerator = 30000, to be 30 + * Also, numerator may become longer than the original data length due to the addition of + * leading zeros in the fractional part. + */ + numerator_top_extension = numerator_len < divisor_int_right_zeros ? divisor_int_right_zeros - numerator_len : 0; + numerator_len = numerator_len > divisor_int_right_zeros ? numerator_len - divisor_int_right_zeros : 0; + numerator_scale += divisor_int_right_zeros; + divisor_len -= divisor_int_right_zeros; + divisor_scale = 0; + } - /* Loop */ - while (qdig <= len1 + scale - len2) { - /* Calculate the quotient digit guess. */ - if (*n2ptr == num1[qdig]) { - qguess = 9; - } else { - qguess = (num1[qdig] * 10 + num1[qdig + 1]) / *n2ptr; - } + /* remove numerator leading zeros */ + while (*numeratorptr == 0 && numerator_len > 0) { + numeratorptr++; + numerator_len--; + } + /* remove divisor leading zeros */ + while (*divisorptr == 0) { + divisorptr++; + divisor_len--; + } - /* Test qguess. */ - if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) { - qguess--; - /* And again. */ - if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) { - qguess--; - } - } + /* Considering the scale specification, the quotient is always 0 if this condition is met */ + if (divisor_len > numerator_len + scale) { + *quot = bc_copy_num(BCG(_zero_)); + return true; + } - /* Multiply and subtract. */ - borrow = 0; - if (qguess != 0) { - *mval = 0; - _one_mult(n2ptr, len2, qguess, mval + 1); - ptr1 = (unsigned char *) num1 + qdig + len2; - ptr2 = (unsigned char *) mval + len2; - for (count = 0; count < len2 + 1; count++) { - val = (int) *ptr1 - (int) *ptr2-- - borrow; - if (val < 0) { - val += 10; - borrow = 1; - } else { - borrow = 0; - } - *ptr1-- = val; - } - } + /* set scale to numerator */ + if (numerator_scale > scale) { + size_t scale_diff = numerator_scale - scale; + if (numerator_bottom_extension > scale_diff) { + numerator_bottom_extension -= scale_diff; + } else { + numerator_bottom_extension = 0; + numeratorend -= scale_diff - numerator_bottom_extension; + } + } else { + numerator_bottom_extension += scale - numerator_scale; + } + numerator_scale = scale; - /* Test for negative result. */ - if (borrow == 1) { - qguess--; - ptr1 = (unsigned char *) num1 + qdig + len2; - ptr2 = (unsigned char *) n2ptr + len2 - 1; - carry = 0; - for (count = 0; count < len2; count++) { - val = (int) *ptr1 + (int) *ptr2-- + carry; - if (val > 9) { - val -= 10; - carry = 1; - } else { - carry = 0; - } - *ptr1-- = val; - } - if (carry == 1) { - *ptr1 = (*ptr1 + 1) % 10; - } - } + /* Length of numerator data that can be read */ + size_t numerator_readable_len = numeratorend - numeratorptr + 1; + + /* If divisor is 1 here, return the result of adjusting the decimal point position of numerator. */ + if (divisor_len == 1 && *divisorptr == 1) { + if (numerator_len == 0) { + numerator_len = 1; + numerator_top_extension++; + } + size_t quot_scale = numerator_scale > numerator_bottom_extension ? numerator_scale - numerator_bottom_extension : 0; + numerator_bottom_extension = numerator_scale < numerator_bottom_extension ? numerator_bottom_extension - numerator_scale : 0; - /* We now know the quotient digit. */ - *qptr++ = qguess; - qdig++; + *quot = bc_new_num_nonzeroed(numerator_len, quot_scale); + char *qptr = (*quot)->n_value; + for (size_t i = 0; i < numerator_top_extension; i++) { + *qptr++ = 0; } + memcpy(qptr, numeratorptr, numerator_readable_len); + qptr += numerator_readable_len; + for (size_t i = 0; i < numerator_bottom_extension; i++) { + *qptr++ = 0; + } + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + return true; } - /* Clean up and return the number. */ - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - if (bc_is_zero(qval)) { - qval->n_sign = PLUS; + size_t quot_full_len; + if (divisor_len > numerator_len) { + *quot = bc_new_num_nonzeroed(1, scale); + quot_full_len = 1 + scale; + } else { + *quot = bc_new_num_nonzeroed(numerator_len - divisor_len + 1, scale); + quot_full_len = numerator_len - divisor_len + 1 + scale; } - _bc_rm_leading_zeros(qval); - bc_free_num(quot); - *quot = qval; - /* Clean up temporary storage. */ - efree(mval); - efree(num1); - efree(num2); + /* do divide */ + bc_do_div(numeratorend, numerator_readable_len, numerator_bottom_extension, divisorend, divisor_len, quot, quot_full_len); + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + _bc_rm_leading_zeros(*quot); - /* Everything is OK. */ return true; } From 7fa2dbf924b5ef67d78e3cdfdace3ffdd3648366 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 18 Aug 2024 11:07:03 +0200 Subject: [PATCH 074/280] Drop support for MYSQL_TEST_EXPERIMENTAL (GH-15467) This environment variable serves to hide (parts of) tests from general execution, and as the test failures show when that environment variable is set, apparently it serves to hide (parts of) test from being executed at all, thus causing test rot. To avoid this in the future, we drop `MYSQL_TEST_EXPERIMENTAL`, and fix the failing tests, except for mysqli_get_warnings.phpt, which appears to be broken beyond repair, and whose most important tests are already covered by other test cases. Co-authored-by: Kamil Tekiela --- ext/mysqli/tests/connect.inc | 3 - .../mysqli_class_mysqli_result_interface.phpt | 10 +- ext/mysqli/tests/mysqli_get_warnings.phpt | 141 ------------------ .../tests/mysqli_warning_unclonable.phpt | 16 +- ext/mysqli/tests/test_setup/test_helpers.inc | 2 - 5 files changed, 13 insertions(+), 159 deletions(-) delete mode 100644 ext/mysqli/tests/mysqli_get_warnings.phpt diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index 3a7d578e97713..9aee7126b3eb3 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -20,9 +20,6 @@ ini_set('mysqli.default_socket', $socket); } - /* Development setting: test experimental features and/or feature requests that never worked before? */ - $TEST_EXPERIMENTAL = 1 == getenv("MYSQL_TEST_EXPERIMENTAL"); - function get_environment_connection_flags(): int { static $connect_flags = null; if ($connect_flags === null) { diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt index 5b79f7a197d9a..1a2a6c9718dc0 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -130,13 +130,10 @@ require_once 'skipifconnectfailure.inc'; $mode = mt_rand(-1000, 1000); } while (in_array($mode, $valid)); - if ($TEST_EXPERIMENTAL) { - ob_start(); + try { new mysqli_result($link, $mode); - $content = ob_get_contents(); - ob_end_clean(); - if (!stristr($content, 'Invalid value for resultmode')) - printf("[009] Expecting warning because of invalid resultmode\n"); + } catch (ValueError $ex) { + echo $ex->getMessage(), "\n"; } print "done!"; @@ -169,4 +166,5 @@ mysqli_result->unknown = '' Constructor: mysqli_result object is already closed +mysqli_result::__construct(): Argument #2 ($result_mode) must be either MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT done! diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt deleted file mode 100644 index 55db12d966a92..0000000000000 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ /dev/null @@ -1,141 +0,0 @@ ---TEST-- -mysqli_get_warnings() - TODO ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---FILE-- -message)) || ('' == $warning->message)) /* NULL or not there at all */ - printf("[011] Expecting string/not empty, got %s/%s\n", gettype($warning->message), $warning->message); - - if ((!is_string($warning->sqlstate)) || ('' == $warning->sqlstate)) /* NULL or not there at all */ - printf("[012] Expecting string/not empty, got %s/%s\n", gettype($warning->sqlstate), $warning->sqlstate); - - if ((!is_int($warning->errno)) || (0 == $warning->errno)) /* NULL or not there at all */ - printf("[013] Expecting int/not 0, got %s/%s\n", gettype($warning->errno), $warning->errno); - - if (false !== ($tmp = $warning->next())) - printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - - if (!mysqli_query($link, "INSERT INTO test (id) VALUES (1000000), (1000001)")) - printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (($tmp = mysqli_warning_count($link)) !== 2) - printf("[016] Expecting 2 warnings, got %d warnings", $tmp); - - if (!is_object($warning = mysqli_get_warnings($link)) || 'mysqli_warning' != get_class($warning)) { - printf("[017] Expecting object/mysqli_warning, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_export($tmp, true) : $tmp)); - } - - if (true !== ($tmp = $warning->next())) - printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - - if (false !== ($tmp = $warning->next())) - printf("[020] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - mysqli_close($link); - - - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - if (!$mysqli->query("DROP TABLE IF EXISTS t1")) - printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) - printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - $warning = new mysqli_warning($mysqli); - - if (!is_string($warning->message) || ('' == $warning->message)) - printf("[025] Expecting string, got %s/%s", gettype($warning->message), $warning->message); - - if (!$mysqli->query("DROP TABLE t1")) - printf("[026] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - /* Yes, I really want to check if the object property is empty */ - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - $warning = new mysqli_warning($mysqli); - if (false !== ($tmp = $warning->next())) - printf("[028] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - if ('' != ($tmp = $warning->message)) - printf("[029] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); - - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - if (!$mysqli->query("DROP TABLE IF EXISTS t1")) - printf("[031] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) - printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - /* out of range, three warnings */ - if (!$mysqli->query("INSERT IGNORE INTO t1(a) VALUES (65536), (65536), (65536)")) - printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - $warning = new mysqli_warning($mysqli); - $i = 1; - while ($warning->next() && ('' != ($tmp = $warning->message))) { - $i++; - } - if (3 != $i) - printf("[034] Expecting three warnings, got %d warnings\n", $i); - - $stmt = mysqli_stmt_init($mysqli); - $warning = new mysqli_warning($stmt); - if (false !== ($tmp = $warning->next())) - printf("[035] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - print "done!"; -?> - ---EXPECT-- -done! diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt index 7e404563f5df7..a9da213616144 100644 --- a/ext/mysqli/tests/mysqli_warning_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -5,8 +5,6 @@ mysqli --SKIPIF-- --FILE-- --EXPECTF-- -Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d +Fatal error: Uncaught Error: Trying to clone an uncloneable object of class mysqli_warning in %s:%d +Stack trace:%A diff --git a/ext/mysqli/tests/test_setup/test_helpers.inc b/ext/mysqli/tests/test_setup/test_helpers.inc index 7c75034006864..5e6833a3253b9 100644 --- a/ext/mysqli/tests/test_setup/test_helpers.inc +++ b/ext/mysqli/tests/test_setup/test_helpers.inc @@ -142,6 +142,4 @@ function setup_table_with_data_on_default_connection(string $table): mysqli { return $link; } -/* Development setting: test experimental features and/or feature requests that never worked before? */ -//$TEST_EXPERIMENTAL = 1 == getenv("MYSQL_TEST_EXPERIMENTAL"); //$engine = getenv("MYSQL_TEST_ENGINE") ?: "InnoDB"; From f16cb1866ab510f809ecf1ff1667f033e73ad0ff Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 18 Aug 2024 12:20:09 +0200 Subject: [PATCH 075/280] Fix ZEND_FASTCALL definition wrt. x64 Windows clang builds (GH-15425) As is, MSVC uses `__vectorcall`, but clang uses `__cdecl`. This obviously is bad for interoperability (and causes link issues), and is likely worse for FFI which offers some limited (but likely sufficient for our purposes) support for `__vectorcall` on Windows. Since clang claims to support `__vectorcall` as of 3.6.0, and we bumped the requirements to clang 4.0.0 already, there shouldn't be any issues. --- Zend/zend_portability.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 5290d7aae4fe3..5be8d7e4f5ced 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -306,7 +306,7 @@ char *alloca(); # define ZEND_FASTCALL __attribute__((fastcall)) #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700 # define ZEND_FASTCALL __fastcall -#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__) +#elif defined(_MSC_VER) && _MSC_VER >= 1800 # define ZEND_FASTCALL __vectorcall #else # define ZEND_FASTCALL From 4a77ce20228bf39ba3f7fda425c7b52ba00851aa Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 18 Aug 2024 12:43:41 +0200 Subject: [PATCH 076/280] Remove unnecessary Windows specific time formatting (GH-15474) `gettimeofday()` is supported by PHP on Windows for ages; and generally `localtime()` is supported on Windows for a long time. As such, there is no need for the Windows specific formatting code. However, the general Windows caveat regarding `time_t` applies, namely that it is usually `__time64_t`, unless `_USE_32BIT_TIME_T` is declared, what we do for 32bit architectures, in which case it is `__time32_t`. Now, `struct timeval` is imported from WinSock2.h, where the members are declared as long (i.e. 32bit on both x86 and x64). That means passing a pointer to `tv_sec` to `localtime()` likely fails on x64, or at least doesn't yield the desired result. Therefore, we assign `tv_sec` to an appropriate `time_t` variable, and also make sure that the `time_buffer` is zero-terminated even if the `localtime()` call still fails. --- ext/mysqlnd/mysqlnd_debug.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index 6a33a16892436..ff80c620bee14 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -76,22 +76,11 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * self, } if (flags & MYSQLND_DEBUG_DUMP_TIME) { /* The following from FF's DBUG library, which is in the public domain */ -#ifdef PHP_WIN32 - /* FIXME This doesn't give microseconds as in Unix case, and the resolution is - in system ticks, 10 ms intervals. See my_getsystime.c for high res */ - SYSTEMTIME loc_t; - GetLocalTime(&loc_t); - snprintf(time_buffer, sizeof(time_buffer) - 1, - /* "%04d-%02d-%02d " */ - "%02d:%02d:%02d.%06d ", - /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/ - loc_t.wHour, loc_t.wMinute, loc_t.wSecond, loc_t.wMilliseconds); - time_buffer[sizeof(time_buffer) - 1 ] = '\0'; -#else struct timeval tv; struct tm *tm_p; if (gettimeofday(&tv, NULL) != -1) { - if ((tm_p= localtime((const time_t *)&tv.tv_sec))) { + const time_t sec = tv.tv_sec; + if ((tm_p = localtime((const time_t *)&sec))) { snprintf(time_buffer, sizeof(time_buffer) - 1, /* "%04d-%02d-%02d " */ "%02d:%02d:%02d.%06d ", @@ -99,9 +88,10 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * self, tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, (int) (tv.tv_usec)); time_buffer[sizeof(time_buffer) - 1 ] = '\0'; + } else { + time_buffer[0] = '\0'; } } -#endif } if (flags & MYSQLND_DEBUG_DUMP_FILE) { snprintf(file_buffer, sizeof(file_buffer) - 1, "%14s: ", file); @@ -173,22 +163,11 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *self, } if (flags & MYSQLND_DEBUG_DUMP_TIME) { /* The following from FF's DBUG library, which is in the public domain */ -#ifdef PHP_WIN32 - /* FIXME This doesn't give microseconds as in Unix case, and the resolution is - in system ticks, 10 ms intervals. See my_getsystime.c for high res */ - SYSTEMTIME loc_t; - GetLocalTime(&loc_t); - snprintf(time_buffer, sizeof(time_buffer) - 1, - /* "%04d-%02d-%02d " */ - "%02d:%02d:%02d.%06d ", - /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/ - loc_t.wHour, loc_t.wMinute, loc_t.wSecond, loc_t.wMilliseconds); - time_buffer[sizeof(time_buffer) - 1 ] = '\0'; -#else struct timeval tv; struct tm *tm_p; if (gettimeofday(&tv, NULL) != -1) { - if ((tm_p= localtime((const time_t *)&tv.tv_sec))) { + const time_t sec = tv.tv_sec; + if ((tm_p = localtime((const time_t *)&sec))) { snprintf(time_buffer, sizeof(time_buffer) - 1, /* "%04d-%02d-%02d " */ "%02d:%02d:%02d.%06d ", @@ -196,9 +175,10 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *self, tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, (int) (tv.tv_usec)); time_buffer[sizeof(time_buffer) - 1 ] = '\0'; + } else { + time_buffer[0] = '\0'; } } -#endif } if (flags & MYSQLND_DEBUG_DUMP_FILE) { snprintf(file_buffer, sizeof(file_buffer) - 1, "%14s: ", file); From dffe25bd1958fed2c0a9ff6550b529ff4098cc9b Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 18 Aug 2024 13:30:03 +0200 Subject: [PATCH 077/280] Autotools: Move AWK finder to PHP_INIT_BUILD_SYSTEM (#15478) This calls the PHP_PROG_AWK from a single place for php-src build and phpize. --- build/php.m4 | 2 ++ configure.ac | 1 - scripts/phpize.m4 | 3 --- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build/php.m4 b/build/php.m4 index 3d1b6b1f2516f..012b8753f6fd9 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -130,6 +130,8 @@ T_MD=$($php_shtool echo -n -e %B) T_ME=$($php_shtool echo -n -e %b) > Makefile.objects > Makefile.fragments +dnl Required programs. +PHP_PROG_AWK dnl Run at the end of the configuration, before creating the config.status. AC_CONFIG_COMMANDS_PRE( [dnl Directory for storing shared objects of extensions. diff --git a/configure.ac b/configure.ac index 0abaf4a4f185b..f54b93fdf4052 100644 --- a/configure.ac +++ b/configure.ac @@ -152,7 +152,6 @@ dnl Check for -R, etc. switch. PHP_RUNPATH_SWITCH dnl Checks for some support/generator progs. -PHP_PROG_AWK PHP_PROG_BISON([3.0.0]) PHP_PROG_RE2C([1.0.3], [--no-generation-date]) PHP_PROG_PHP() diff --git a/scripts/phpize.m4 b/scripts/phpize.m4 index 22f4477e7bc27..4bfe79dc4575f 100644 --- a/scripts/phpize.m4 +++ b/scripts/phpize.m4 @@ -136,9 +136,6 @@ AS_VAR_IF([PHP_DEBUG], [yes], [ dnl Always shared. PHP_BUILD_SHARED -dnl Required programs. -PHP_PROG_AWK - PHP_HELP_SEPARATOR([Extension:]) PHP_CONFIGURE_PART([Configuring extension]) From 7a9120e5f3fc378a0f0b4cff81d3cae38599be81 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 18 Aug 2024 13:41:09 +0200 Subject: [PATCH 078/280] Avoid multiple connects in SKIPIF sections (GH-15470) Besides checking for the ability to connect to the MySQL server, some tests require additional checks (e.g. to be able to check for the server's version) as skip condition. There is no need, though, to connect twice; instead we introduce `mysqli_connect_or_skip()` in test_helpers.inc, which `die()`s with an appropriate error message, if the connection can't be established, or returns the connection link otherwise. Co-authored-by: Kamil Tekiela --- ext/mysqli/tests/045.phpt | 6 ++---- ext/mysqli/tests/gh9590.phpt | 7 ++----- ext/mysqli/tests/mysqli_begin_transaction.phpt | 8 ++------ ext/mysqli/tests/mysqli_change_user_old.phpt | 8 ++------ ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt | 5 ++--- ext/mysqli/tests/mysqli_query_unicode.phpt | 5 ----- ext/mysqli/tests/mysqli_real_escape_string_big5.phpt | 10 ++-------- .../tests/mysqli_real_escape_string_eucjpms.phpt | 10 ++-------- ext/mysqli/tests/mysqli_real_escape_string_euckr.phpt | 10 ++-------- ext/mysqli/tests/mysqli_real_escape_string_gb2312.phpt | 10 ++-------- ext/mysqli/tests/mysqli_real_escape_string_gbk.phpt | 10 ++-------- ext/mysqli/tests/mysqli_real_escape_string_sjis.phpt | 9 ++------- ext/mysqli/tests/test_setup/test_helpers.inc | 5 ++++- 13 files changed, 26 insertions(+), 77 deletions(-) diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index ec70cb9877fbf..8284812a7991f 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -4,10 +4,8 @@ mysqli_stmt_bind_result (SHOW) mysqli --SKIPIF-- errno, $link->error)); ?> diff --git a/ext/mysqli/tests/mysqli_change_user_old.phpt b/ext/mysqli/tests/mysqli_change_user_old.phpt index fd418220ae80d..980bc533c4c06 100644 --- a/ext/mysqli/tests/mysqli_change_user_old.phpt +++ b/ext/mysqli/tests/mysqli_change_user_old.phpt @@ -4,12 +4,8 @@ mysqli_change_user(), MySQL < 5.6 mysqli --SKIPIF-- = 50600 && mysqli_get_server_version($link) < 10_00_00) die("SKIP For MySQL < 5.6.0"); ?> diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index 9f3197b903c4b..ff1cbb7a5bc90 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -4,9 +4,8 @@ mysqli_fetch_assoc() - BIT mysqli --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- Date: Sun, 18 Aug 2024 13:53:35 +0200 Subject: [PATCH 079/280] Don't skip tests which are supposed to fail; mark them as xfail (#15472) Especially regarding buggy server behavior, we should not skip those tests, because it is unlikely that fixes to the server's behavior will even be noticed. Instead we mark these tests as xfail, so we get a warning if the test succeeds, and can act appropriately. --- ext/mysqli/tests/mysqli_change_user_get_lock.phpt | 3 ++- ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt | 3 ++- ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt | 3 ++- ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt index 3026cb369b317..a4442edb5279a 100644 --- a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt +++ b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt @@ -5,8 +5,9 @@ mysqli --SKIPIF-- +--XFAIL-- +The server is still buggy --INI-- max_execution_time=240 --FILE-- diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt index 36f5ec0329ca3..6d0789b90b45d 100644 --- a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -5,8 +5,9 @@ mysqli --SKIPIF-- +--XFAIL-- +The server is still buggy --FILE-- +--XFAIL-- +prefetch isn't supported at the moment --FILE-- +--XFAIL-- +http://bugs.mysql.com/bug.php?id=42490 --FILE-- Date: Sun, 18 Aug 2024 16:47:57 +0200 Subject: [PATCH 080/280] Add date extension to dependencies (#15475) This is at this point only meta-data information for extensions to depend also on date extension. This is a configure phase dependency for consistency. --- ext/intl/config.m4 | 2 ++ ext/intl/config.w32 | 1 + ext/opcache/config.m4 | 1 + ext/opcache/config.w32 | 1 + ext/session/config.m4 | 1 + ext/session/config.w32 | 1 + ext/soap/config.m4 | 1 + ext/soap/config.w32 | 1 + 8 files changed, 9 insertions(+) diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 97e93d11e72cc..543108ba27eb1 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -127,4 +127,6 @@ if test "$PHP_INTL" != "no"; then $ext_builddir/transliterator $ext_builddir/uchar ])) + + PHP_ADD_EXTENSION_DEP(intl, date) fi diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index dec7180e62174..8de0e1eff0fc9 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -8,6 +8,7 @@ if (PHP_INTL != "no") { // always build as shared - zend_strtod.c/ICU type conflict EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true, "/I \"" + configure_module_dirname + "\" /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('intl', 'date'); ADD_SOURCES(configure_module_dirname + "/collator", "\ collator_attr.c \ collator_class.c \ diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 3700a6ba063fc..44e82d07bdfa0 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -343,6 +343,7 @@ int main(void) { [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, [yes]) + PHP_ADD_EXTENSION_DEP(opcache, date) PHP_ADD_EXTENSION_DEP(opcache, pcre) if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index 0d498ab776891..d0af7258ac66f 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -18,6 +18,7 @@ if (PHP_OPCACHE != "no") { zend_shared_alloc.c \ shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('opcache', 'date'); ADD_EXTENSION_DEP('opcache', 'hash'); ADD_EXTENSION_DEP('opcache', 'pcre'); diff --git a/ext/session/config.m4 b/ext/session/config.m4 index 1171f912832a2..36cfdf10972ab 100644 --- a/ext/session/config.m4 +++ b/ext/session/config.m4 @@ -19,6 +19,7 @@ if test "$PHP_SESSION" != "no"; then [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + PHP_ADD_EXTENSION_DEP(session, date) dnl https://bugs.php.net/53141 PHP_ADD_EXTENSION_DEP(session, spl, true) diff --git a/ext/session/config.w32 b/ext/session/config.w32 index bd5065b599db0..825bc8b61d291 100644 --- a/ext/session/config.w32 +++ b/ext/session/config.w32 @@ -4,6 +4,7 @@ ARG_ENABLE("session", "session support", "yes"); if (PHP_SESSION == "yes") { EXTENSION("session", "mod_user_class.c session.c mod_files.c mod_mm.c mod_user.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('session', 'date'); // https://bugs.php.net/53141 ADD_EXTENSION_DEP('session', 'spl', true); AC_DEFINE("HAVE_PHP_SESSION", 1, "Define to 1 if the PHP extension 'session' is available."); diff --git a/ext/soap/config.m4 b/ext/soap/config.m4 index d4eda59cec5ef..1b25e5101edec 100644 --- a/ext/soap/config.m4 +++ b/ext/soap/config.m4 @@ -20,6 +20,7 @@ if test "$PHP_SOAP" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_SUBST([SOAP_SHARED_LIBADD]) ]) + PHP_ADD_EXTENSION_DEP(soap, date) PHP_ADD_EXTENSION_DEP(soap, hash) PHP_ADD_EXTENSION_DEP(soap, libxml) PHP_ADD_EXTENSION_DEP(soap, session, true) diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index ca052f912db83..583f6a2b2e0d1 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -10,6 +10,7 @@ if (PHP_SOAP != "no") { ) { EXTENSION('soap', 'soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c', null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_SOAP', 1, "Define to 1 if the PHP extension 'soap' is available."); + ADD_EXTENSION_DEP('soap', 'date'); ADD_EXTENSION_DEP('soap', 'hash'); ADD_EXTENSION_DEP('soap', 'session', true); From d713e3619e2f114da2b9b19ee066b5ecf2830337 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 18 Aug 2024 06:19:36 +0100 Subject: [PATCH 081/280] ext/sockets: adding SO_BINDTOIFINDEX. similar to SO_BINDTODEVICE but works with interface ids instead. close GH-15479 --- NEWS | 4 ++++ UPGRADING | 1 + ext/sockets/sockets.stub.php | 7 +++++++ ext/sockets/sockets_arginfo.h | 5 ++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index dfea4ff1a3c8b..cc863fac11928 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,10 @@ PHP NEWS - Hash: . Fix GH-15384 (Build fails on Alpine / Musl for amd64). (timwolla) +- Sockets: + . Added SO_BINDTOIFINDEX to bind a socket to an interface index. + (David Carlier) + - Standard: . php_uname() now throws ValueErrors on invalid inputs. (Girgias) diff --git a/UPGRADING b/UPGRADING index 6a56342a85e98..0737da0fb5663 100644 --- a/UPGRADING +++ b/UPGRADING @@ -979,6 +979,7 @@ PHP 8.4 UPGRADE NOTES . IP_PORTRANGE_LOW (FreeBSD/NetBSD/OpenBSD only). . SOCK_NONBLOCK. . SOCK_CLOEXEC. + . SOCK_BINDTOIFINDEX. - Sodium: . SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index a6258bc1f7388..f19672ecd5339 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -295,6 +295,13 @@ */ const SO_BINDTODEVICE = UNKNOWN; #endif +#ifdef SO_BINDTOIFINDEX +/** + * @var int + * @cvalue SO_BINDTOIFINDEX + */ +const SO_BINDTOIFINDEX = UNKNOWN; +#endif #ifdef SO_USER_COOKIE /** * @var int diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index a8dc7adaa8574..348c62d2eb4ae 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: dcdacf23e3445748178066972e101cbe0ebd6ad5 */ + * Stub hash: 08677a3dd11366b55a1c539475adead74109595e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -425,6 +425,9 @@ static void register_sockets_symbols(int module_number) #if defined(SO_BINDTODEVICE) REGISTER_LONG_CONSTANT("SO_BINDTODEVICE", SO_BINDTODEVICE, CONST_PERSISTENT); #endif +#if defined(SO_BINDTOIFINDEX) + REGISTER_LONG_CONSTANT("SO_BINDTOIFINDEX", SO_BINDTOIFINDEX, CONST_PERSISTENT); +#endif #if defined(SO_USER_COOKIE) REGISTER_LONG_CONSTANT("SO_LABEL", SO_LABEL, CONST_PERSISTENT); #endif From 35ae1523d003783cd74b8844742adec8538751bf Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sun, 18 Aug 2024 19:20:04 +0200 Subject: [PATCH 082/280] Remove mysqli_change_user_get_lock.phpt (#15482) --- .../tests/mysqli_change_user_get_lock.phpt | 107 ------------------ .../mysqli_change_user_locks_temporary.phpt | 3 +- 2 files changed, 1 insertion(+), 109 deletions(-) delete mode 100644 ext/mysqli/tests/mysqli_change_user_get_lock.phpt diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt deleted file mode 100644 index a4442edb5279a..0000000000000 --- a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt +++ /dev/null @@ -1,107 +0,0 @@ ---TEST-- -mysqli_change_user() - GET_LOCK() ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---XFAIL-- -The server is still buggy ---INI-- -max_execution_time=240 ---FILE-- - ---CLEAN-- - ---EXPECTF-- -Testing GET_LOCK()... -... lock 'phptest_%d' acquired by thread %d -... calling IS_USED_LOCK() on 'phptest_%d' using thread '%d' -... calling IS_FREE_LOCK() on 'phptest_%d' using thread '%d' -... calling IS_USED_LOCK() on 'phptest_%d' using new connection with thread '%d' -done! diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt index 6d0789b90b45d..f758fa8d16446 100644 --- a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -6,8 +6,6 @@ mysqli ---XFAIL-- -The server is still buggy --FILE-- Date: Sat, 17 Aug 2024 14:04:28 +0200 Subject: [PATCH 083/280] ext/standard: Remove deprecated php_uint32 and php_int32 typedefs Use the standard uint32_t and int32_t types instead. --- UPGRADING.INTERNALS | 3 +++ ext/standard/basic_functions.h | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 448f220ff659a..bd1d5660cf729 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -338,6 +338,9 @@ PHP 8.4 INTERNALS UPGRADE NOTES the caller now. - The php_info_html_esc() function has been removed, use php_escape_html_entities() with ENT_QUOTES directly instead. + - The deprecated php_uint32 and php_int32 typedefs have been removed from + ext/standard/basic_functions.h. Use the standard uint32_t and int32_t + types instead. h. ext/session - Added the php_get_session_status() API to get the session status, which is diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index 45ea1f0a887ba..1985040f70ad2 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -51,10 +51,6 @@ PHPAPI int _php_error_log(int opt_err, const char *message, const char *opt, con PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_len, const char *opt, const char *headers); PHPAPI int php_prefix_varname(zval *result, zend_string *prefix, const char *var_name, size_t var_name_len, bool add_underscore); -/* Deprecated type aliases -- use the standard types instead */ -typedef uint32_t php_uint32; -typedef int32_t php_int32; - typedef struct _php_basic_globals { HashTable *user_shutdown_function_names; HashTable putenv_ht; From 3813ad10dc738344c5395c29d24af2d55b7b435f Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 14:14:03 +0200 Subject: [PATCH 084/280] Remove unused ext/standard/basic_functions.h header inclusions Those were probably included back in the day for the php_uint32 typedef --- ext/hash/php_hash_adler32.h | 2 -- ext/hash/php_hash_gost.h | 2 -- ext/hash/php_hash_haval.h | 1 - ext/hash/php_hash_ripemd.h | 1 - ext/hash/php_hash_sha.h | 1 - ext/hash/php_hash_sha3.h | 2 -- ext/hash/php_hash_snefru.h | 2 -- ext/opcache/zend_file_cache.c | 1 + ext/standard/md5.h | 2 -- ext/standard/sha1.h | 2 -- 10 files changed, 1 insertion(+), 15 deletions(-) diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index 90953573c6908..091fdeb3488e7 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_ADLER32_H #define PHP_HASH_ADLER32_H -#include "ext/standard/basic_functions.h" - typedef struct { uint32_t state; } PHP_ADLER32_CTX; diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 45110dfb7b55b..66992b09b976c 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_GOST_H #define PHP_HASH_GOST_H -#include "ext/standard/basic_functions.h" - /* GOST context */ typedef struct { uint32_t state[16]; diff --git a/ext/hash/php_hash_haval.h b/ext/hash/php_hash_haval.h index 7f1fb6bf0fa72..e3a3a31b36851 100644 --- a/ext/hash/php_hash_haval.h +++ b/ext/hash/php_hash_haval.h @@ -17,7 +17,6 @@ #ifndef PHP_HASH_HAVAL_H #define PHP_HASH_HAVAL_H -#include "ext/standard/basic_functions.h" /* HAVAL context. */ typedef struct { uint32_t state[8]; diff --git a/ext/hash/php_hash_ripemd.h b/ext/hash/php_hash_ripemd.h index da5621acd7b7e..0065450d21bb2 100644 --- a/ext/hash/php_hash_ripemd.h +++ b/ext/hash/php_hash_ripemd.h @@ -16,7 +16,6 @@ #ifndef PHP_HASH_RIPEMD_H #define PHP_HASH_RIPEMD_H -#include "ext/standard/basic_functions.h" /* RIPEMD context. */ typedef struct { diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index 7336a5ba0aa40..d5b04ddd2f479 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -19,7 +19,6 @@ #define PHP_HASH_SHA_H #include "ext/standard/sha1.h" -#include "ext/standard/basic_functions.h" /* SHA224 context. */ typedef struct { diff --git a/ext/hash/php_hash_sha3.h b/ext/hash/php_hash_sha3.h index b574087f60f4f..8381a8943b4d9 100644 --- a/ext/hash/php_hash_sha3.h +++ b/ext/hash/php_hash_sha3.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_SHA3_H #define PHP_HASH_SHA3_H -#include "php.h" - typedef struct { #ifdef HAVE_SLOW_HASH3 unsigned char state[200]; // 5 * 5 * sizeof(uint64) diff --git a/ext/hash/php_hash_snefru.h b/ext/hash/php_hash_snefru.h index 217eb8727ef4a..df90e8e469686 100644 --- a/ext/hash/php_hash_snefru.h +++ b/ext/hash/php_hash_snefru.h @@ -21,8 +21,6 @@ * AKA "Xerox Secure Hash Function" */ -#include "ext/standard/basic_functions.h" - /* SNEFRU context */ typedef struct { uint32_t state[16]; diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index c09e39579a474..736d644516a04 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -29,6 +29,7 @@ #ifdef ZEND_WIN32 #include "ext/standard/md5.h" #endif +#include "ext/standard/php_filestat.h" #include "ZendAccelerator.h" #include "zend_file_cache.h" diff --git a/ext/standard/md5.h b/ext/standard/md5.h index 0003a934be62d..c488b5c534e36 100644 --- a/ext/standard/md5.h +++ b/ext/standard/md5.h @@ -21,8 +21,6 @@ PHPAPI void make_digest(char *md5str, const unsigned char *digest); PHPAPI void make_digest_ex(char *md5str, const unsigned char *digest, int len); -#include "ext/standard/basic_functions.h" - /* * This is an OpenSSL-compatible implementation of the RSA Data Security, * Inc. MD5 Message-Digest Algorithm (RFC 1321). diff --git a/ext/standard/sha1.h b/ext/standard/sha1.h index afec81272ca40..046d6db2cc475 100644 --- a/ext/standard/sha1.h +++ b/ext/standard/sha1.h @@ -17,8 +17,6 @@ #ifndef SHA1_H #define SHA1_H -#include "ext/standard/basic_functions.h" - /* SHA1 context. */ typedef struct { uint32_t state[5]; /* state (ABCD) */ From c6e1e307a358d2b121cb828739242c694194a871 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 18 Aug 2024 18:21:25 +0100 Subject: [PATCH 085/280] ext/standard: Throw a RequestParseBodyException instead of InvalidArgumentException (#15468) Especially as this exception is thrown when there isn't an issue with an argument --- ext/standard/http.c | 3 +-- .../http/request_parse_body/unsupported_content_type.phpt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/standard/http.c b/ext/standard/http.c index 7a4a58755d894..5f796a4a4026b 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -19,7 +19,6 @@ #include "url.h" #include "SAPI.h" #include "zend_exceptions.h" -#include "ext/spl/spl_exceptions.h" #include "basic_functions.h" static void php_url_encode_scalar(zval *scalar, smart_str *form_str, @@ -338,7 +337,7 @@ PHP_FUNCTION(request_parse_body) sapi_read_post_data(); if (!SG(request_info).post_entry) { - zend_throw_error(spl_ce_InvalidArgumentException, "Content-Type \"%s\" is not supported", SG(request_info).content_type); + zend_throw_error(zend_ce_request_parse_body_exception, "Content-Type \"%s\" is not supported", SG(request_info).content_type); goto exit; } diff --git a/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt b/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt index bd4e3f4ff2afa..087b11841cabc 100644 --- a/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt +++ b/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt @@ -20,7 +20,7 @@ var_dump($_POST, $_FILES); ?> --EXPECT-- -InvalidArgumentException: Content-Type "application/json" is not supported +RequestParseBodyException: Content-Type "application/json" is not supported array(0) { } array(0) { From 962aba3b124ab012d629b395e73f4d4e323157b4 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 13 Aug 2024 14:14:40 +0200 Subject: [PATCH 086/280] ext/standard/mail.c: Reduce scope of some variable declarations --- ext/standard/mail.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 1fddded70153b..8ed8969fdca52 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -410,12 +410,7 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { /* {{{ php_mail */ PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) { -#ifdef PHP_WIN32 - int tsm_err; - char *tsm_errmsg = NULL; -#endif FILE *sendmail; - int ret; char *sendmail_path = INI_STR("sendmail_path"); char *sendmail_cmd = NULL; char *mail_log = INI_STR("mail.log"); @@ -491,6 +486,9 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co if (!sendmail_path) { #ifdef PHP_WIN32 + int tsm_err; + char *tsm_errmsg = NULL; + /* handle old style win smtp sending */ if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL) == FAILURE) { if (tsm_errmsg) { @@ -556,7 +554,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co fprintf(sendmail, "%s%s", hdr, line_sep); } fprintf(sendmail, "%s%s%s", line_sep, message, line_sep); - ret = pclose(sendmail); + int ret = pclose(sendmail); #if PHP_SIGCHILD if (sig_handler) { From 312c919a2d658f4c520ed6805258989ca735cbc3 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 13 Aug 2024 14:15:32 +0200 Subject: [PATCH 087/280] ext/standard/mail.c: change return type of php_mail() to bool --- ext/standard/mail.c | 22 +++++++++++----------- ext/standard/php_mail.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 8ed8969fdca52..299f20c3a7d80 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -408,7 +408,7 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { /* {{{ php_mail */ -PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) +PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) { FILE *sendmail; char *sendmail_path = INI_STR("sendmail_path"); @@ -459,7 +459,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } if (EG(exception)) { - MAIL_RET(0); + MAIL_RET(false); } char *line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : "\r\n"; @@ -481,7 +481,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co if (hdr && php_mail_detect_multiple_crlf(hdr)) { php_error_docref(NULL, E_WARNING, "Multiple or malformed newlines found in additional_header"); - MAIL_RET(0); + MAIL_RET(false); } if (!sendmail_path) { @@ -497,11 +497,11 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } else { php_error_docref(NULL, E_WARNING, "%s", GetSMErrorText(tsm_err)); } - MAIL_RET(0); + MAIL_RET(false); } - MAIL_RET(1); + MAIL_RET(true); #else - MAIL_RET(0); + MAIL_RET(false); #endif } if (extra_cmd != NULL) { @@ -545,7 +545,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co signal(SIGCHLD, sig_handler); } #endif - MAIL_RET(0); + MAIL_RET(false); } #endif fprintf(sendmail, "To: %s%s", to, line_sep); @@ -574,9 +574,9 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co #endif #endif { - MAIL_RET(0); + MAIL_RET(false); } else { - MAIL_RET(1); + MAIL_RET(true); } } else { php_error_docref(NULL, E_WARNING, "Could not execute mail delivery program '%s'", sendmail_path); @@ -585,10 +585,10 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co signal(SIGCHLD, sig_handler); } #endif - MAIL_RET(0); + MAIL_RET(false); } - MAIL_RET(1); /* never reached */ + MAIL_RET(true); /* never reached */ } /* }}} */ diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 338f7831c6b87..00a55137b7876 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -20,7 +20,7 @@ PHP_MINFO_FUNCTION(mail); PHPAPI zend_string *php_mail_build_headers(HashTable *headers); -PHPAPI extern int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); +PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); #define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ do { \ From a171b20c7c5d6d3782506dd647420d2aba03f8cb Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 13 Aug 2024 00:06:50 +0200 Subject: [PATCH 088/280] ext/standard/mail.c: Move macros out of the header --- ext/standard/mail.c | 22 +++++++++++++++++++++- ext/standard/php_mail.h | 27 --------------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 299f20c3a7d80..caa5d274ecc78 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -181,6 +181,20 @@ static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *v } ZEND_HASH_FOREACH_END(); } +#define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ +do { \ + if (Z_TYPE_P(val) == IS_STRING) { \ + php_mail_build_headers_elem(&s, key, val); \ + } else if (Z_TYPE_P(val) == IS_ARRAY) { \ + if (zend_string_equals_literal_ci(key, target)) { \ + zend_type_error("Header \"%s\" must be of type string, array given", target); \ + break; \ + } \ + php_mail_build_headers_elems(&s, key, val); \ + } else { \ + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ + } \ +} while(0) PHPAPI zend_string *php_mail_build_headers(HashTable *headers) { @@ -219,7 +233,13 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) } else if (zend_string_equals_literal_ci(key, "subject")) { zend_value_error("The additional headers cannot contain the \"Subject\" header"); } else { - PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + if (Z_TYPE_P(val) == IS_STRING) { + php_mail_build_headers_elem(&s, key, val); + } else if (Z_TYPE_P(val) == IS_ARRAY) { + php_mail_build_headers_elems(&s, key, val); + } else { + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); + } } if (EG(exception)) { diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 00a55137b7876..6c39343c7cd98 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -22,33 +22,6 @@ PHP_MINFO_FUNCTION(mail); PHPAPI zend_string *php_mail_build_headers(HashTable *headers); PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); -#define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ -do { \ - if (Z_TYPE_P(val) == IS_STRING) { \ - php_mail_build_headers_elem(&s, key, val); \ - } else if (Z_TYPE_P(val) == IS_ARRAY) { \ - if (zend_string_equals_literal_ci(key, target)) { \ - zend_type_error("Header \"%s\" must be of type string, array given", target); \ - break; \ - } \ - php_mail_build_headers_elems(&s, key, val); \ - } else { \ - zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ - } \ -} while(0) - - -#define PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val) \ -do { \ - if (Z_TYPE_P(val) == IS_STRING) { \ - php_mail_build_headers_elem(&s, key, val); \ - } else if (Z_TYPE_P(val) == IS_ARRAY) { \ - php_mail_build_headers_elems(&s, key, val); \ - } else { \ - zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ - } \ -} while(0) - typedef enum { NO_HEADER_ERROR, CONTAINS_LF_ONLY, From ebfef2505d059853bfc19f6a30f9c3d76ac8df13 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 13 Aug 2024 00:52:05 +0200 Subject: [PATCH 089/280] ext/standard/mail.c: Move php_mail_header_value_error_type enum out of header --- ext/standard/mail.c | 8 ++++++++ ext/standard/php_mail.h | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/standard/mail.c b/ext/standard/mail.c index caa5d274ecc78..35c23a0be76c0 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -56,6 +56,14 @@ extern zend_long php_getuid(void); +typedef enum { + NO_HEADER_ERROR, + CONTAINS_LF_ONLY, + CONTAINS_CR_ONLY, + CONTAINS_CRLF, + CONTAINS_NULL +} php_mail_header_value_error_type; + static php_mail_header_value_error_type php_mail_build_headers_check_field_value(zval *val) { size_t len = 0; diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 6c39343c7cd98..c2e22240c48e9 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -22,12 +22,4 @@ PHP_MINFO_FUNCTION(mail); PHPAPI zend_string *php_mail_build_headers(HashTable *headers); PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); -typedef enum { - NO_HEADER_ERROR, - CONTAINS_LF_ONLY, - CONTAINS_CR_ONLY, - CONTAINS_CRLF, - CONTAINS_NULL -} php_mail_header_value_error_type; - #endif /* PHP_MAIL_H */ From ac3cdf54df5f69c8210e0d9adc1a13af212c04fa Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 19:47:34 +0200 Subject: [PATCH 090/280] [skip ci] Add UPGRADING.INTERNALS entry for EXIT opcode --- UPGRADING.INTERNALS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index bd1d5660cf729..ee8412ccafac0 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -370,6 +370,8 @@ PHP 8.4 INTERNALS UPGRADE NOTES * YIELD and YIELD_FROM do not increment the opline anymore. +* The EXIT opcode has been removed as exit is now implemented as a function. + ======================== 5. SAPI changes ======================== From c316382acb23ea9411132fd4af6eb9836ca71f80 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 19 Aug 2024 13:04:56 +0200 Subject: [PATCH 091/280] Remove MYSQLI_STMT_ATTR_PREFETCH_ROWS constant (#15485) This feature was never implemented, and since the beginning, using this constant with mysqlnd would result in an error. This feature was only available with libmysqlclient which can no longer be used with mysqli. There are no plans to implement it in the future. --- ext/mysqli/mysqli.stub.php | 5 -- ext/mysqli/mysqli_api.c | 14 +---- ext/mysqli/mysqli_arginfo.h | 3 +- ext/mysqli/tests/mysqli_constants.phpt | 4 -- ext/mysqli/tests/mysqli_stmt_attr_get.phpt | 4 +- .../tests/mysqli_stmt_attr_get_prefetch.phpt | 30 ---------- ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 60 +------------------ ext/mysqlnd/mysqlnd_driver.c | 1 - ext/mysqlnd/mysqlnd_enum_n_def.h | 3 +- ext/mysqlnd/mysqlnd_ps.c | 16 ----- ext/mysqlnd/mysqlnd_structs.h | 1 - 11 files changed, 6 insertions(+), 135 deletions(-) delete mode 100644 ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 9c2d57a8b25ab..ef64a1188c561 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -191,11 +191,6 @@ * @cvalue CURSOR_TYPE_SCROLLABLE */ const MYSQLI_CURSOR_TYPE_SCROLLABLE = UNKNOWN; -/** - * @var int - * @cvalue STMT_ATTR_PREFETCH_ROWS - */ -const MYSQLI_STMT_ATTR_PREFETCH_ROWS = UNKNOWN; /* column information */ /** diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 0a153087923e8..2c0dfec5dd439 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1751,18 +1751,9 @@ PHP_FUNCTION(mysqli_stmt_attr_set) mode = mode_in; mode_p = &mode; break; - case STMT_ATTR_PREFETCH_ROWS: - if (mode_in < 1) { - zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS"); - RETURN_THROWS(); - } - mode = mode_in; - mode_p = &mode; - break; default: zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " - "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } @@ -1793,8 +1784,7 @@ PHP_FUNCTION(mysqli_stmt_attr_get) /* Success corresponds to 0 return value and a non-zero value * should only happen if the attr/option is unknown */ zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " - "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 6e347bafcc417..b2391e33d069a 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c904ba3577e74cd390278004de0cf3594eb66f18 */ + * Stub hash: 6ab095be89ce9416df60f2dfaa1bd70732e33136 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1077,7 +1077,6 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_PERSISTENT); diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 8f755400e4b08..41c904e545171 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -137,10 +137,6 @@ $expected_constants = array_merge($expected_constants, array( "MYSQLI_CURSOR_TYPE_SCROLLABLE" => true, )); -$expected_constants = array_merge($expected_constants, array( - "MYSQLI_STMT_ATTR_PREFETCH_ROWS" => true, -)); - $expected_constants['MYSQLI_OPT_SSL_VERIFY_SERVER_CERT'] = true; /* pretty dump test, but that is the best way to mimic mysql.c */ diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index f7de1e04c604c..f68af2aba91a7 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -13,7 +13,6 @@ require_once 'skipifconnectfailure.inc'; $valid_attr = array( MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_CURSOR_TYPE, - MYSQLI_STMT_ATTR_PREFETCH_ROWS, ); $stmt = mysqli_stmt_init($link); @@ -51,8 +50,7 @@ require_once 'skipifconnectfailure.inc'; require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_stmt_attr_get(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE -mysqli_stmt object is already closed +mysqli_stmt_attr_get(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE mysqli_stmt object is already closed mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt deleted file mode 100644 index 5e5a3ddf0d76b..0000000000000 --- a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -mysqli_stmt_attr_get() - prefetch ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---XFAIL-- -prefetch isn't supported at the moment ---FILE-- -close(); - mysqli_close($link); - print "done!"; -?> ---CLEAN-- - ---EXPECT-- -done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 070d4a389bca3..217b785acb4c5 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -160,63 +160,6 @@ require_once 'skipifconnectfailure.inc'; var_dump($results2); } - - // - // MYSQLI_STMT_ATTR_PREFETCH_ROWS - // - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT id, label FROM test"); - // Invalid prefetch value - try { - $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 0); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; - } - - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 1))) - printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->execute(); - $id = $label = NULL; - $stmt->bind_result($id, $label); - $results = array(); - while ($stmt->fetch()) - $results[$id] = $label; - $stmt->close(); - if (empty($results)) - printf("[021] Results should not be empty, subsequent tests will probably fail!\n"); - - /* prefetch is not supported - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT label FROM test"); - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, -1))) - printf("[022] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - $stmt->close(); - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT label FROM test"); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, PHP_INT_MAX))) - printf("[023] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->close(); - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT id, label FROM test"); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 2))) - printf("[024] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->execute(); - $id = $label = NULL; - $stmt->bind_result($id, $label); - $results2 = array(); - while ($stmt->fetch()) - $results2[$id] = $label; - $stmt->close(); - if ($results != $results2) { - printf("[025] Results should not differ. Dumping both result sets.\n"); - var_dump($results); - var_dump($results2); - } - */ - mysqli_close($link); print "done!"; ?> @@ -226,9 +169,8 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- Error: mysqli_stmt object is not fully initialized -mysqli_stmt_attr_set(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE +mysqli_stmt_attr_set(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE mysqli_stmt::attr_set(): Argument #2 ($value) must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH bool(true) mysqli_stmt::attr_set(): Argument #2 ($value) must be one of the MYSQLI_CURSOR_TYPE_* constants for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE -mysqli_stmt::attr_set(): Argument #2 ($value) must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS done! diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index 02065739ccd34..2c1d997177aa8 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -206,7 +206,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA stmt->state = MYSQLND_STMT_INITTED; stmt->execute_cmd_buffer.length = MYSQLND_NET_CMD_BUFFER_MIN_SIZE; stmt->execute_cmd_buffer.buffer = mnd_emalloc(stmt->execute_cmd_buffer.length); - stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS; /* Mark that we reference the connection, thus it won't be diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 27846f077a849..5400bbb7adde5 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -399,8 +399,7 @@ typedef enum param_bind_flags enum mysqlnd_stmt_attr { STMT_ATTR_UPDATE_MAX_LENGTH, - STMT_ATTR_CURSOR_TYPE, - STMT_ATTR_PREFETCH_ROWS + STMT_ATTR_CURSOR_TYPE }; enum myslqnd_cursor_type diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 5b81eb8e211ea..5fad5281947ea 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -1552,18 +1552,6 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s, stmt->flags = ival; break; } - case STMT_ATTR_PREFETCH_ROWS: { - unsigned long ival = *(unsigned long *) value; - if (ival == 0) { - ival = MYSQLND_DEFAULT_PREFETCH_ROWS; - } else if (ival > 1) { - SET_CLIENT_ERROR(stmt->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented"); - DBG_INF("FAIL"); - DBG_RETURN(FAIL); - } - stmt->prefetch_rows = ival; - break; - } default: SET_CLIENT_ERROR(stmt->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented"); DBG_RETURN(FAIL); @@ -1596,10 +1584,6 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_get)(const MYSQLND_STMT * const s, *(unsigned long *) value = stmt->flags; DBG_INF_FMT("value=%lu", *(unsigned long *) value); break; - case STMT_ATTR_PREFETCH_ROWS: - *(unsigned long *) value = stmt->prefetch_rows; - DBG_INF_FMT("value=%lu", *(unsigned long *) value); - break; default: DBG_RETURN(FAIL); } diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index ccf70c3302557..cf99ac706239c 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -1267,7 +1267,6 @@ struct st_mysqlnd_stmt_data MYSQLND_ERROR_INFO error_info_impl; bool update_max_length; - zend_ulong prefetch_rows; bool cursor_exists; mysqlnd_stmt_use_or_store_func default_rset_handler; From 8f1c430954e67335ad86cac79fdc033db4b40bab Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 19 Aug 2024 13:08:14 +0200 Subject: [PATCH 092/280] Drop mysqli_stmt_result_metadata_sqltests.phpt (#15488) The test is unfinished and not needed. The functionality is already tested in other tests. --- .../mysqli_stmt_result_metadata_sqltests.phpt | 228 ------------------ 1 file changed, 228 deletions(-) delete mode 100644 ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt deleted file mode 100644 index cdcd3121b2308..0000000000000 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt +++ /dev/null @@ -1,228 +0,0 @@ ---TEST-- -mysqli_stmt_result_metadata() - non SELECT statements ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---XFAIL-- -http://bugs.mysql.com/bug.php?id=42490 ---FILE-- - mysqli_num_fields($res), - 'fetch_field' => mysqli_fetch_field($res), - 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), - 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), - 'fetch_fields' => count(mysqli_fetch_fields($res)), - 'field_count' => $res->field_count, - 'field_seek-1' => @mysqli_field_seek($res, -1), - 'field_seek0' => mysqli_field_seek($res, 0), - 'field_tell' => mysqli_field_tell($res), - ); - if (is_object($meta['fetch_field'])) { - $meta['fetch_field']->charsetnr = 'ignore'; - $meta['fetch_field']->flags = 'ignore'; - } - if (is_object($meta['fetch_field_direct0'])) { - $meta['fetch_field_direct0']->charsetnr = 'ignore'; - $meta['fetch_field_direct0']->flags = 'ignore'; - } - if (is_object($meta['fetch_field_direct1'])) { - $meta['fetch_field_direct1']->charsetnr = 'ignore'; - $meta['fetch_field_direct1']->flags = 'ignore'; - } - mysqli_free_result($res); - - if ($meta != $expected_lib) { - printf("[%04d - %s] Metadata differs from expected values\n", - $offset + 5, $sql); - var_dump($meta); - var_dump($expected_lib); - return false; - } - } - - if (!mysqli_stmt_execute($stmt)) { - printf("[%04d - %s] [%d] %s\n", - $offset + 6, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - - $res = mysqli_stmt_get_result($stmt); - if (false === $res && !empty($expected_mysqlnd)) { - printf("[%04d - %s] Expecting resultset [%d] %s\n", - $offset + 7, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } else if (empty($expected_mysqlnd) && false !== $res) { - printf("[%04d - %s] Unexpected resultset [%d] %s\n", - $offset + 8, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - - if (!is_object($res)) { - printf("[%04d - %s] [%d] %s\n", - $offset + 9, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - if ('mysqli_result' != get_class($res)) { - printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n", - $offset + 10, $sql, - get_class($res)); - return false; - } - - $meta_res = array( - 'num_fields' => mysqli_num_fields($res), - 'fetch_field' => mysqli_fetch_field($res), - 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), - 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), - 'fetch_fields' => count(mysqli_fetch_fields($res)), - 'field_count' => mysqli_field_count($link), - 'field_seek-1' => @mysqli_field_seek($res, -1), - 'field_seek0' => mysqli_field_seek($res, 0), - 'field_tell' => mysqli_field_tell($res), - ); - if (is_object($meta_res['fetch_field'])) { - $meta_res['fetch_field']->charsetnr = 'ignore'; - $meta_res['fetch_field']->flags = 'ignore'; - } - if (is_object($meta_res['fetch_field_direct0'])) { - $meta_res['fetch_field_direct0']->charsetnr = 'ignore'; - $meta_res['fetch_field_direct0']->flags = 'ignore'; - } - if (is_object($meta_res['fetch_field_direct1'])) { - $meta_res['fetch_field_direct1']->charsetnr = 'ignore'; - $meta_res['fetch_field_direct1']->flags = 'ignore'; - } - mysqli_free_result($res); - if ($check_mysqlnd && $meta_res != $expected_mysqlnd) { - printf("[%04d - %s] Metadata differs from expected\n", - $offset + 11, $sql); - var_dump($meta_res); - var_dump($expected_mysqlnd); - } else { - if ($meta_res['field_count'] < 1) { - printf("[%04d - %s] Metadata seems wrong, no fields?\n", - $offset + 12, $sql); - var_dump($meta_res); - var_dump(mysqli_fetch_assoc($res)); - } - } - - if ($compare && $meta_res != $meta) { - printf("[%04d - %s] Metadata returned by mysqli_stmt_result_metadata() and mysqli_stmt_get_result() differ\n", - $offset + 13, $sql); - var_dump($meta_res); - var_dump($meta); - } - - mysqli_stmt_close($stmt); - return true; - } - - /* Note: very weak testing, we accept almost any result */ - - testStatement(100, $link, 'ANALYZE TABLE test', array(), array(1), false, false); - testStatement(120, $link, 'OPTIMIZE TABLE test', array(), array(1), false, false); - testStatement(140, $link, 'REPAIR TABLE test', array(), array(1), false, false); - - testStatement(160, $link, 'SHOW AUTHORS', array(), array(1), false, false); - testStatement(180, $link, 'SHOW CHARACTER SET', array(), array(1), false, false); - testStatement(200, $link, 'SHOW COLLATION', array(), array(1), false, false); - testStatement(220, $link, 'SHOW CONTRIBUTORS', array(), array(1), false, false); - testStatement(240, $link, 'SHOW CREATE DATABASE ' . $db, array(), array(1), false, false); - testStatement(260, $link, 'SHOW DATABASES', array(), array(1), false, false); - testStatement(280, $link, 'SHOW ENGINE InnoDB STATUS', array(), array(1), false, false); - testStatement(300, $link, 'SHOW ENGINES', array(), array(1), false, false); - testStatement(320, $link, 'SHOW PLUGINS', array(), array(1), false, false); - testStatement(340, $link, 'SHOW PROCESSLIST', array(), array(1), false, false); - testStatement(360, $link, 'SHOW FULL PROCESSLIST', array(), array(1), false, false); - testStatement(380, $link, 'SHOW STATUS', array(), array(1), false, false); - testStatement(400, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); - testStatement(420, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); - testStatement(440, $link, 'SHOW TABLES', array(), array(1), false, false); - testStatement(460, $link, 'SHOW OPEN TABLES', array(), array(1), false, false); - testStatement(460, $link, 'SHOW VARIABLES', array(), array(1), false, false); - - $field0 = new stdClass(); - $field0->name = 'id'; - $field0->orgname = 'id'; - $field0->table = 'test'; - $field0->orgtable = 'test'; - $field0->def = ''; - $field0->max_length = 0; - $field0->length = 11; - $field0->charsetnr = 'ignore'; - $field0->flags = 'ignore'; - $field0->type = MYSQLI_TYPE_LONG; - $field0->decimals = 0; - $meta_lib = array( - 'num_fields' => 1, - 'fetch_field' => $field0, - 'fetch_field_direct0' => $field0, - 'fetch_field_direct1' => false, - 'fetch_fields' => 1, - 'field_count' => 1, - 'field_seek-1' => false, - 'field_seek0' => true, - 'field_tell' => 0, - ); - $meta_mysqlnd = $meta_lib; - testStatement(480, $link, 'SELECT id FROM test', $meta_lib, $meta_mysqlnd, true, true); - - testStatement(500, $link, 'CHECKSUM TABLE test', array(), array(1), false, false); - - mysqli_close($link); - print "done!"; -?> ---CLEAN-- - ---EXPECT-- -done! From 4baf6a643ba17d68b2c735b6be31335a49e1d407 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 19 Aug 2024 13:19:49 +0200 Subject: [PATCH 093/280] Fix error message and add UPGRADING entry --- UPGRADING | 2 ++ ext/mysqli/mysqli_api.c | 8 ++++---- ext/mysqli/tests/mysqli_stmt_attr_get.phpt | 2 +- ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/UPGRADING b/UPGRADING index 0737da0fb5663..8a5a903a95901 100644 --- a/UPGRADING +++ b/UPGRADING @@ -874,6 +874,8 @@ PHP 8.4 UPGRADE NOTES - Mysqli: . The unused and undocumented constant MYSQLI_SET_CHARSET_DIR has been removed. + . The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been removed. + The feature is unavailable with mysqlnd. - OpenSSL: . The OpenSSL extension now requires at least OpenSSL 1.1.1. diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 2c0dfec5dd439..24ca8cb2afe1f 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1752,8 +1752,8 @@ PHP_FUNCTION(mysqli_stmt_attr_set) mode_p = &mode; break; default: - zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE"); + zend_argument_value_error(ERROR_ARG_POS(2), "must be either " + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } @@ -1783,8 +1783,8 @@ PHP_FUNCTION(mysqli_stmt_attr_get) if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) { /* Success corresponds to 0 return value and a non-zero value * should only happen if the attr/option is unknown */ - zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE"); + zend_argument_value_error(ERROR_ARG_POS(2), "must be either " + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index f68af2aba91a7..0c6f43e2ee8ba 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -50,7 +50,7 @@ require_once 'skipifconnectfailure.inc'; require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_stmt_attr_get(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE +mysqli_stmt_attr_get(): Argument #2 ($attribute) must be either MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE mysqli_stmt object is already closed mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 217b785acb4c5..58a51af6fd30e 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -169,7 +169,7 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- Error: mysqli_stmt object is not fully initialized -mysqli_stmt_attr_set(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or STMT_ATTR_CURSOR_TYPE +mysqli_stmt_attr_set(): Argument #2 ($attribute) must be either MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE mysqli_stmt::attr_set(): Argument #2 ($value) must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH bool(true) mysqli_stmt::attr_set(): Argument #2 ($value) must be one of the MYSQLI_CURSOR_TYPE_* constants for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE From 6c7ff089206863b82cb0ee23f98841bdccb7808d Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 19 Aug 2024 13:54:40 +0200 Subject: [PATCH 094/280] Drop MYSQLI_CURSOR_TYPE_FOR_UPDATE & MYSQLI_CURSOR_TYPE_SCROLLABLE (#15486) --- UPGRADING | 3 +++ ext/mysqli/mysqli.stub.php | 10 ---------- ext/mysqli/mysqli_api.c | 2 -- ext/mysqli/mysqli_arginfo.h | 4 +--- ext/mysqli/tests/mysqli_constants.phpt | 2 -- ext/mysqli/tests/mysqli_report.phpt | 8 -------- ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 6 ------ ext/mysqlnd/mysqlnd_enum_n_def.h | 2 -- 8 files changed, 4 insertions(+), 33 deletions(-) diff --git a/UPGRADING b/UPGRADING index 8a5a903a95901..6e20a824b089c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -876,6 +876,9 @@ PHP 8.4 UPGRADE NOTES has been removed. . The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been removed. The feature is unavailable with mysqlnd. + . The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE + constants have been removed. This functionality was never implemented, + neither with mysqlnd nor with libmysql. - OpenSSL: . The OpenSSL extension now requires at least OpenSSL 1.1.1. diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index ef64a1188c561..d680678d088c0 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -181,16 +181,6 @@ * @cvalue CURSOR_TYPE_READ_ONLY */ const MYSQLI_CURSOR_TYPE_READ_ONLY = UNKNOWN; -/** - * @var int - * @cvalue CURSOR_TYPE_FOR_UPDATE - */ -const MYSQLI_CURSOR_TYPE_FOR_UPDATE = UNKNOWN; -/** - * @var int - * @cvalue CURSOR_TYPE_SCROLLABLE - */ -const MYSQLI_CURSOR_TYPE_SCROLLABLE = UNKNOWN; /* column information */ /** diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 24ca8cb2afe1f..b71888f630a14 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1740,8 +1740,6 @@ PHP_FUNCTION(mysqli_stmt_attr_set) switch (mode_in) { case CURSOR_TYPE_NO_CURSOR: case CURSOR_TYPE_READ_ONLY: - case CURSOR_TYPE_FOR_UPDATE: - case CURSOR_TYPE_SCROLLABLE: break; default: zend_argument_value_error(ERROR_ARG_POS(3), "must be one of the MYSQLI_CURSOR_TYPE_* constants " diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index b2391e33d069a..11bf8cae5f61e 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6ab095be89ce9416df60f2dfaa1bd70732e33136 */ + * Stub hash: 6a64c5833a4c83d0bd0e63f34d27d2e696c78b66 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1075,8 +1075,6 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_PERSISTENT); diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 41c904e545171..6bddcb5980e6f 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -133,8 +133,6 @@ $expected_constants = array_merge($expected_constants, array( "MYSQLI_STMT_ATTR_CURSOR_TYPE" => true, "MYSQLI_CURSOR_TYPE_NO_CURSOR" => true, "MYSQLI_CURSOR_TYPE_READ_ONLY" => true, - "MYSQLI_CURSOR_TYPE_FOR_UPDATE" => true, - "MYSQLI_CURSOR_TYPE_SCROLLABLE" => true, )); $expected_constants['MYSQLI_OPT_SSL_VERIFY_SERVER_CERT'] = true; diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index 19b70a0f2b468..da400ae4eee46 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -59,9 +59,6 @@ require_once 'skipifconnectfailure.inc'; } mysqli_next_result($link); - $stmt = mysqli_prepare($link, "SELECT 1"); - mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE); - // Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would // not have been set. If that would be the case, the test would be broken. mysqli_report(MYSQLI_REPORT_OFF); @@ -89,9 +86,6 @@ require_once 'skipifconnectfailure.inc'; } mysqli_next_result($link); - $stmt = mysqli_prepare($link, "SELECT 1"); - mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE); - /* Internal macro MYSQL_REPORT_STMT_ERROR */ @@ -330,8 +324,6 @@ Warning: mysqli_next_result(): (%s/%d): You have an error in your SQL syntax; ch Warning: mysqli_store_result(): (%s/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d -Warning: mysqli_stmt_attr_set(): (%s/%d): Not implemented in %s on line %d - Deprecated: Function mysqli_kill() is deprecated since 8.4, use KILL CONNECTION/QUERY SQL statement instead in %s mysqli_kill(): Argument #2 ($process_id) must be greater than 0 diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 58a51af6fd30e..f9cd1bac611a9 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -100,12 +100,6 @@ require_once 'skipifconnectfailure.inc'; echo $e->getMessage() . \PHP_EOL; } - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE))) - printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_SCROLLABLE))) - printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 5400bbb7adde5..1f862141a3d61 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -406,8 +406,6 @@ enum myslqnd_cursor_type { CURSOR_TYPE_NO_CURSOR= 0, CURSOR_TYPE_READ_ONLY= 1, - CURSOR_TYPE_FOR_UPDATE= 2, - CURSOR_TYPE_SCROLLABLE= 4 }; typedef enum mysqlnd_connection_close_type From 144c086c466db717c4afa87462d12e70e9f3dab7 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 19 Aug 2024 14:26:27 +0200 Subject: [PATCH 095/280] Fix a mistake in mysqli test --- ext/mysqli/tests/mysqli_fork.phpt | 3 +-- ext/mysqli/tests/mysqli_warning_unclonable.phpt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index f8ba36edafb4b..f912e993a12ec 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -32,7 +32,6 @@ if (!have_innodb($link)) case 0: /* child */ exit(0); - break; default: /* parent */ @@ -123,8 +122,8 @@ if (!have_innodb($link)) if (!mysqli_query($plink, sprintf($sql, 'stop')) || !mysqli_commit($link)) exit(mysqli_errno($plink)); + exit(0); - break; default: /* parent */ diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt index a9da213616144..49e059c4ba7dd 100644 --- a/ext/mysqli/tests/mysqli_warning_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -15,7 +15,7 @@ require_once 'skipifconnectfailure.inc'; $host, $user, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) - printf("[002] Cannot set SQL-Mode, [%d] %s\n", mysqli_errno($mysql), mysqli_error($mysql)); + printf("[002] Cannot set SQL-Mode, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); From 770616b823b81ad24d7e260e1050a81aa309bbcc Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 19 Aug 2024 14:53:54 +0200 Subject: [PATCH 096/280] Fix param with hooks but no visibility not treated as cpp (GH-15442) Fixes GH-15438 --- NEWS | 2 ++ Zend/tests/property_hooks/gh15438_1.phpt | 20 ++++++++++++++++++++ Zend/tests/property_hooks/gh15438_2.phpt | 20 ++++++++++++++++++++ Zend/zend_compile.c | 21 ++++++++++++--------- 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 Zend/tests/property_hooks/gh15438_1.phpt create mode 100644 Zend/tests/property_hooks/gh15438_2.phpt diff --git a/NEWS b/NEWS index cc863fac11928..e8762fa2419c8 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). (zeriyoshi) + . Fixed bug GH-15438 (Hooks on constructor promoted properties without + visibility are ignored). (ilutov) 15 Aug 2024, PHP 8.4.0beta3 diff --git a/Zend/tests/property_hooks/gh15438_1.phpt b/Zend/tests/property_hooks/gh15438_1.phpt new file mode 100644 index 0000000000000..2d06196f6b742 --- /dev/null +++ b/Zend/tests/property_hooks/gh15438_1.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15438: Promoted properties with hooks but no visibility +--FILE-- + $value * 2; } + ) {} +} + +$c = new C(42); +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + int(84) +} diff --git a/Zend/tests/property_hooks/gh15438_2.phpt b/Zend/tests/property_hooks/gh15438_2.phpt new file mode 100644 index 0000000000000..63175e5ecac70 --- /dev/null +++ b/Zend/tests/property_hooks/gh15438_2.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15438: Untyped promoted, hooked properties with no default value default to null +--FILE-- + $value * 2; } + ) {} +} + +$c = new ReflectionClass(C::class)->newInstanceWithoutConstructor(); +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + NULL +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9e736ea1b37ad..93c557df5a238 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7570,6 +7570,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0; uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); + bool is_promoted = property_flags || hooks_ast; znode var_node, default_node; uint8_t opcode; @@ -7626,14 +7627,14 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 if (attributes_ast) { zend_compile_attributes( &op_array->attributes, attributes_ast, i + 1, ZEND_ATTRIBUTE_TARGET_PARAMETER, - property_flags ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0 + is_promoted ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0 ); } bool forced_allow_nullable = false; if (type_ast) { uint32_t default_type = *default_ast_ptr ? Z_TYPE(default_node.u.constant) : IS_UNDEF; - bool force_nullable = default_type == IS_NULL && !property_flags; + bool force_nullable = default_type == IS_NULL && !is_promoted; op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; arg_info->type = zend_compile_typename_ex(type_ast, force_nullable, &forced_allow_nullable); @@ -7696,14 +7697,14 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 } uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, /* is_tentative */ 0) - | (property_flags ? _ZEND_IS_PROMOTED_BIT : 0); + | (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0); ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags; if (opcode == ZEND_RECV) { opline->op2.num = type_ast ? ZEND_TYPE_FULL_MASK(arg_info->type) : MAY_BE_ANY; } - if (property_flags) { + if (is_promoted) { zend_op_array *op_array = CG(active_op_array); zend_class_entry *scope = op_array->scope; @@ -7790,9 +7791,11 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 for (i = 0; i < list->children; i++) { zend_ast *param_ast = list->child[i]; + zend_ast *hooks_ast = param_ast->child[5]; bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); - if (!flags) { + bool is_promoted = flags || hooks_ast; + if (!is_promoted) { continue; } @@ -8543,6 +8546,10 @@ static void zend_compile_property_hooks( /* Will be removed again, in case of Iterator or IteratorAggregate. */ ce->get_iterator = zend_hooked_object_get_iterator; } + + if (!prop_info->ce->parent_name) { + zend_verify_hooked_property(ce, prop_info, prop_name); + } } static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags, zend_ast *attr_ast) /* {{{ */ @@ -8679,10 +8686,6 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (hooks_ast) { zend_compile_property_hooks(info, name, type_ast, zend_ast_get_list(hooks_ast)); - - if (!ce->parent_name) { - zend_verify_hooked_property(ce, info, name); - } } if (attr_ast) { From 36b19774153d41f978113075e4d3c3321a3beeb2 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 19 Aug 2024 14:58:55 +0200 Subject: [PATCH 097/280] Fix missing compile error when declaring hooked props on readonly classes (GH-15439) Fixes GH-15419 --- NEWS | 2 ++ Zend/tests/property_hooks/gh15419_1.phpt | 12 ++++++++++++ Zend/tests/property_hooks/gh15419_2.phpt | 14 ++++++++++++++ Zend/zend_compile.c | 9 ++++----- 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/property_hooks/gh15419_1.phpt create mode 100644 Zend/tests/property_hooks/gh15419_2.phpt diff --git a/NEWS b/NEWS index e8762fa2419c8..597673c7fe1e3 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS (zeriyoshi) . Fixed bug GH-15438 (Hooks on constructor promoted properties without visibility are ignored). (ilutov) + . Fixed bug GH-15419 (Missing readonly+hook incompatibility check for readonly + classes). (ilutov) 15 Aug 2024, PHP 8.4.0beta3 diff --git a/Zend/tests/property_hooks/gh15419_1.phpt b/Zend/tests/property_hooks/gh15419_1.phpt new file mode 100644 index 0000000000000..41a45154f1fde --- /dev/null +++ b/Zend/tests/property_hooks/gh15419_1.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-15419: Readonly classes may not declare properties with hooks +--FILE-- + $value; } +} + +?> +--EXPECTF-- +Fatal error: Hooked properties cannot be readonly in %s on line %d diff --git a/Zend/tests/property_hooks/gh15419_2.phpt b/Zend/tests/property_hooks/gh15419_2.phpt new file mode 100644 index 0000000000000..dfa6490fdc0cd --- /dev/null +++ b/Zend/tests/property_hooks/gh15419_2.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-15419: Readonly classes may not declare promoted properties with hooks +--FILE-- + $value; }, + ) {} +} + +?> +--EXPECTF-- +Fatal error: Hooked properties cannot be readonly in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 93c557df5a238..06a55ff761d6a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8385,6 +8385,10 @@ static void zend_compile_property_hooks( { zend_class_entry *ce = CG(active_class_entry); + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_error_noreturn(E_COMPILE_ERROR, "Hooked properties cannot be readonly"); + } + if (hooks->children == 0) { zend_error_noreturn(E_COMPILE_ERROR, "Property hook list cannot be empty"); } @@ -8608,11 +8612,6 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } - if (hooks_ast && (flags & ZEND_ACC_READONLY)) { - zend_error_noreturn(E_COMPILE_ERROR, - "Hooked properties cannot be readonly"); - } - if (type_ast) { type = zend_compile_typename(type_ast); From 60f87f29bbabafd04a0af7dcc8d06616a2a0127f Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 19 Aug 2024 15:46:20 +0200 Subject: [PATCH 098/280] Fix various hooked object iterator issues (GH-15394) Fixes GH-15187 --- NEWS | 1 + Zend/tests/property_hooks/foreach.phpt | 5 + Zend/tests/property_hooks/gh15187_1.phpt | 23 ++++ Zend/tests/property_hooks/gh15187_2.phpt | 21 ++++ Zend/tests/property_hooks/gh15187_3.phpt | 43 ++++++++ Zend/zend_compile.h | 2 + Zend/zend_property_hooks.c | 134 ++++++++++++----------- 7 files changed, 165 insertions(+), 64 deletions(-) create mode 100644 Zend/tests/property_hooks/gh15187_1.phpt create mode 100644 Zend/tests/property_hooks/gh15187_2.phpt create mode 100644 Zend/tests/property_hooks/gh15187_3.phpt diff --git a/NEWS b/NEWS index 597673c7fe1e3..54018fcab1f58 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS visibility are ignored). (ilutov) . Fixed bug GH-15419 (Missing readonly+hook incompatibility check for readonly classes). (ilutov) + . Fixed bug GH-15187 (Various hooked object iterator issues). (ilutov) 15 Aug 2024, PHP 8.4.0beta3 diff --git a/Zend/tests/property_hooks/foreach.phpt b/Zend/tests/property_hooks/foreach.phpt index c217bf6ac0e28..c6073b50ed990 100644 --- a/Zend/tests/property_hooks/foreach.phpt +++ b/Zend/tests/property_hooks/foreach.phpt @@ -17,6 +17,11 @@ class ByRef { $this->_virtualByRef = $value; } } + public $virtualSetOnly { + set { + echo __METHOD__, "\n"; + } + } public function __construct() { $this->dynamic = 'dynamic'; } diff --git a/Zend/tests/property_hooks/gh15187_1.phpt b/Zend/tests/property_hooks/gh15187_1.phpt new file mode 100644 index 0000000000000..13b729620517a --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_1.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-15187: Crash in hooked iterators on properties array without dynamic properties +--FILE-- + $value; } +} + +$test = new Test(); +var_dump($test); +foreach ($test as $key => $value) { + var_dump($key, $value); +} + +?> +--EXPECTF-- +object(Test)#%d (1) { + ["prop"]=> + NULL +} +string(4) "prop" +NULL diff --git a/Zend/tests/property_hooks/gh15187_2.phpt b/Zend/tests/property_hooks/gh15187_2.phpt new file mode 100644 index 0000000000000..bf8a14fd8f9d0 --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_2.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-15187: Crash in hooked iterators on properties array without dynamic properties +--FILE-- + $value; } +} + +$test = new Test(); +var_dump($test); +foreach ($test as $key => $value) { + var_dump($key, $value); +} + +?> +--EXPECTF-- +object(Test)#%d (0) { + ["prop"]=> + uninitialized(int) +} diff --git a/Zend/tests/property_hooks/gh15187_3.phpt b/Zend/tests/property_hooks/gh15187_3.phpt new file mode 100644 index 0000000000000..d82e6002f82bf --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_3.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-15187: Hooked iterator typed property ref tracking +--FILE-- + &$v) { + var_dump($v); + if ($k === 'c') { + try { + $v = 'foo'; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + } + if ($k === 'd') { + $v = 'foo'; + } +} + +var_dump($c); + +?> +--EXPECTF-- +int(1) +Cannot assign string to reference held by property C::$c of type int +int(2) +object(C)#%d (2) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(1) + ["d"]=> + &string(3) "foo" +} diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c7e31877b5cd2..69f3ef762ca16 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -438,6 +438,8 @@ typedef struct _zend_property_info { ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) +#define OBJ_PROP_PTR_TO_NUM(obj, prop) \ + (((char*)prop - (char*)obj->properties_table) / sizeof(zval)) typedef struct _zend_class_constant { zval value; /* flags are stored in u2 */ diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index d3ae945f1d81e..684caafc4dd51 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -25,12 +25,14 @@ typedef struct { bool by_ref; bool declared_props_done; zval declared_props; + bool dynamic_props_done; uint32_t dynamic_prop_it; zval current_key; zval current_data; } zend_hooked_object_iterator; static zend_result zho_it_valid(zend_object_iterator *iter); +static void zho_it_move_forward(zend_object_iterator *iter); // FIXME: This should probably be stored on zend_class_entry somewhere (e.g. through num_virtual_props). static uint32_t zho_num_backed_props(zend_object *zobj) @@ -87,13 +89,16 @@ ZEND_API zend_array *zend_hooked_object_build_properties(zend_object *zobj) static bool zho_dynamic_it_init(zend_hooked_object_iterator *hooked_iter) { - zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); - if (!zobj->properties) { - return false; - } if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { return true; } + + zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); + if (!zobj->properties || zho_num_backed_props(zobj) == zobj->properties->nNumUsed) { + hooked_iter->dynamic_props_done = true; + return false; + } + hooked_iter->dynamic_prop_it = zend_hash_iterator_add(zobj->properties, zho_num_backed_props(zobj)); return true; } @@ -102,26 +107,17 @@ static void zho_it_get_current_key(zend_object_iterator *iter, zval *key); static void zho_declared_it_fetch_current(zend_object_iterator *iter) { - ZEND_ASSERT(zho_it_valid(iter) == SUCCESS); - zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - zval_ptr_dtor(&hooked_iter->current_data); - if (EG(exception)) { - return; - } - ZVAL_UNDEF(&hooked_iter->current_data); - zval_ptr_dtor(&hooked_iter->current_key); - ZVAL_UNDEF(&hooked_iter->current_key); zend_object *zobj = Z_OBJ_P(&iter->data); zend_array *properties = Z_ARR(hooked_iter->declared_props); - zval_ptr_dtor_nogc(&hooked_iter->current_key); - zend_hash_get_current_key_zval(properties, &hooked_iter->current_key); - zval *property = zend_hash_get_current_data(properties); if (Z_TYPE_P(property) == IS_PTR) { zend_property_info *prop_info = Z_PTR_P(property); zend_function *get = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + if (!get && (prop_info->flags & ZEND_ACC_VIRTUAL)) { + return; + } if (hooked_iter->by_ref && (get == NULL || !(get->common.fn_flags & ZEND_ACC_RETURN_REFERENCE))) { @@ -129,12 +125,27 @@ static void zho_declared_it_fetch_current(zend_object_iterator *iter) ZSTR_VAL(zobj->ce->name), zend_get_unmangled_property_name(prop_info->name)); return; } - zend_read_property_ex(prop_info->ce, zobj, prop_info->name, /* silent */ true, &hooked_iter->current_data); + zval *value = zend_read_property_ex(prop_info->ce, zobj, prop_info->name, /* silent */ true, &hooked_iter->current_data); + if (value == &EG(uninitialized_zval)) { + return; + } else if (value != &hooked_iter->current_data) { + ZVAL_COPY(&hooked_iter->current_data, value); + } } else { ZVAL_DEINDIRECT(property); - if (hooked_iter->by_ref && Z_TYPE_P(property) != IS_REFERENCE) { - ZEND_ASSERT(Z_TYPE_P(property) != IS_UNDEF); + if (Z_TYPE_P(property) == IS_UNDEF) { + return; + } + if (!hooked_iter->by_ref) { + ZVAL_DEREF(property); + } else if (Z_TYPE_P(property) != IS_REFERENCE) { ZVAL_MAKE_REF(property); + + zend_class_entry *ce = zobj->ce; + zend_property_info *prop_info = ce->properties_info_table[OBJ_PROP_PTR_TO_NUM(zobj, property)]; + if (ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(property), prop_info); + } } ZVAL_COPY(&hooked_iter->current_data, property); } @@ -154,10 +165,8 @@ static void zho_dynamic_it_fetch_current(zend_object_iterator *iter) ZEND_ASSERT(Z_TYPE(bucket->val) != IS_UNDEF); ZVAL_MAKE_REF(&bucket->val); } - zval_ptr_dtor(&hooked_iter->current_data); ZVAL_COPY(&hooked_iter->current_data, &bucket->val); - zval_ptr_dtor_nogc(&hooked_iter->current_key); if (bucket->key) { ZVAL_STR_COPY(&hooked_iter->current_key, bucket->key); } else { @@ -168,13 +177,22 @@ static void zho_dynamic_it_fetch_current(zend_object_iterator *iter) static void zho_it_fetch_current(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + if (Z_TYPE(hooked_iter->current_data) != IS_UNDEF) { + return; + } - if (!hooked_iter->declared_props_done) { - zho_declared_it_fetch_current(iter); - } else if (zho_dynamic_it_init(hooked_iter)) { - zho_dynamic_it_fetch_current(iter); - } else { - ZEND_UNREACHABLE(); + while (true) { + if (!hooked_iter->declared_props_done) { + zho_declared_it_fetch_current(iter); + } else if (!hooked_iter->dynamic_props_done && zho_dynamic_it_init(hooked_iter)) { + zho_dynamic_it_fetch_current(iter); + } else { + break; + } + if (Z_TYPE(hooked_iter->current_data) != IS_UNDEF || EG(exception)) { + break; + } + zho_it_move_forward(iter); } } @@ -185,7 +203,6 @@ static void zho_it_dtor(zend_object_iterator *iter) zval_ptr_dtor(&hooked_iter->declared_props); zval_ptr_dtor_nogc(&hooked_iter->current_key); zval_ptr_dtor(&hooked_iter->current_data); - zval_ptr_dtor(&hooked_iter->current_key); if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { zend_hash_iterator_del(hooked_iter->dynamic_prop_it); } @@ -194,78 +211,66 @@ static void zho_it_dtor(zend_object_iterator *iter) static zend_result zho_it_valid(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - if (!hooked_iter->declared_props_done) { - if (zend_hash_has_more_elements(Z_ARR(hooked_iter->declared_props)) == SUCCESS) { - return SUCCESS; - } - } - - if (zho_dynamic_it_init(hooked_iter)) { - zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); - HashPosition pos = zend_hash_iterator_pos(hooked_iter->dynamic_prop_it, zobj->properties); - return pos < zobj->properties->nNumUsed ? SUCCESS : FAILURE; - } - - return FAILURE; + zho_it_fetch_current(iter); + return Z_TYPE(hooked_iter->current_data) != IS_UNDEF ? SUCCESS : FAILURE; } static zval *zho_it_get_current_data(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + zho_it_fetch_current(iter); return &hooked_iter->current_data; } static void zho_it_get_current_key(zend_object_iterator *iter, zval *key) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + zho_it_fetch_current(iter); ZVAL_COPY(key, &hooked_iter->current_key); } static void zho_it_move_forward(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - zend_array *properties = Z_ARR(hooked_iter->declared_props); + + zval_ptr_dtor(&hooked_iter->current_data); + ZVAL_UNDEF(&hooked_iter->current_data); + zval_ptr_dtor_nogc(&hooked_iter->current_key); + ZVAL_UNDEF(&hooked_iter->current_key); + if (!hooked_iter->declared_props_done) { + zend_array *properties = Z_ARR(hooked_iter->declared_props); zend_hash_move_forward(properties); - if (zend_hash_has_more_elements(properties) == SUCCESS) { - zho_declared_it_fetch_current(iter); - } else { + if (zend_hash_has_more_elements(properties) != SUCCESS) { hooked_iter->declared_props_done = true; - if (zho_dynamic_it_init(hooked_iter)) { - zho_dynamic_it_fetch_current(iter); - } } - } else if (zho_dynamic_it_init(hooked_iter)) { + } else if (!hooked_iter->dynamic_props_done && zho_dynamic_it_init(hooked_iter)) { zend_array *properties = Z_OBJ(iter->data)->properties; HashPosition pos = zend_hash_iterator_pos(hooked_iter->dynamic_prop_it, properties); - Bucket *bucket = properties->arData + pos; - while (true) { - pos++; - bucket++; - if (pos >= properties->nNumUsed) { - break; - } - if (Z_TYPE_INFO_P(&bucket->val) != IS_UNDEF) { - zho_dynamic_it_fetch_current(iter); - break; - } - } + pos++; EG(ht_iterators)[hooked_iter->dynamic_prop_it].pos = pos; + if (pos >= properties->nNumUsed) { + hooked_iter->dynamic_props_done = true; + } } } static void zho_it_rewind(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + + zval_ptr_dtor(&hooked_iter->current_data); + ZVAL_UNDEF(&hooked_iter->current_data); + zval_ptr_dtor_nogc(&hooked_iter->current_key); + ZVAL_UNDEF(&hooked_iter->current_key); + hooked_iter->declared_props_done = false; zend_array *properties = Z_ARR(hooked_iter->declared_props); zend_hash_internal_pointer_reset(properties); + hooked_iter->dynamic_props_done = false; if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { EG(ht_iterators)[hooked_iter->dynamic_prop_it].pos = zho_num_backed_props(Z_OBJ(iter->data)); } - if (zho_it_valid(iter) == SUCCESS) { - zho_it_fetch_current(iter); - } } static HashTable *zho_it_get_gc(zend_object_iterator *iter, zval **table, int *n) @@ -301,6 +306,7 @@ ZEND_API zend_object_iterator *zend_hooked_object_get_iterator(zend_class_entry iterator->declared_props_done = false; zend_array *properties = zho_build_properties_ex(Z_OBJ_P(object), true, false); ZVAL_ARR(&iterator->declared_props, properties); + iterator->dynamic_props_done = false; iterator->dynamic_prop_it = (uint32_t) -1; ZVAL_UNDEF(&iterator->current_key); ZVAL_UNDEF(&iterator->current_data); From b6d7c011b87437f4489cb2258bb2166cdc308a71 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 19 Aug 2024 17:39:31 +0200 Subject: [PATCH 099/280] Fix virtual properties in get_class_vars() (GH-15494) Fixes GH-15456 --- NEWS | 2 ++ Zend/tests/property_hooks/gh15456.phpt | 20 ++++++++++++++++++++ Zend/zend_builtin_functions.c | 3 ++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/property_hooks/gh15456.phpt diff --git a/NEWS b/NEWS index 54018fcab1f58..090a43b11c8fa 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ PHP NEWS . Fixed bug GH-15419 (Missing readonly+hook incompatibility check for readonly classes). (ilutov) . Fixed bug GH-15187 (Various hooked object iterator issues). (ilutov) + . Fixed bug GH-15456 (Crash in get_class_vars() on virtual properties). + (ilutov) 15 Aug 2024, PHP 8.4.0beta3 diff --git a/Zend/tests/property_hooks/gh15456.phpt b/Zend/tests/property_hooks/gh15456.phpt new file mode 100644 index 0000000000000..10a7dbbfb04e0 --- /dev/null +++ b/Zend/tests/property_hooks/gh15456.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15456: Crash in get_class_vars() on virtual properties +--FILE-- + $this->b * 2; } + public $c { get => 42; } +} +var_dump(get_class_vars(C::class)); + +?> +--EXPECT-- +array(2) { + ["a"]=> + int(42) + ["b"]=> + int(42) +} diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 245552d094609..377bc23c46bd2 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -724,7 +724,8 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool s if (((prop_info->flags & ZEND_ACC_PROTECTED) && !zend_check_protected(prop_info->ce, scope)) || ((prop_info->flags & ZEND_ACC_PRIVATE) && - prop_info->ce != scope)) { + prop_info->ce != scope) || + (prop_info->flags & ZEND_ACC_VIRTUAL)) { continue; } prop = NULL; From 40217b2ea4af321a838c35b3ec70d88a961fff7a Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Mon, 19 Aug 2024 22:29:20 +0200 Subject: [PATCH 100/280] Autotools: Move auto_cflags marker to PHP_INIT_BUILD_SYSTEM (#15487) The "hacky" auto_cflags variable is otherwise set only for the Oracle Developer Studio compiler (which is at this point also non-usable) and perhaps might be removed in the future but this is for now moved to the PHP_INIT_BUILD_SYSTEM for consistent settings between the php-src build and phpize. The PHP_INIT_BUILD_SYSTEM is now also called sooner in phpize to match the php-src build. --- build/php.m4 | 10 ++++++++++ configure.ac | 3 --- scripts/phpize.m4 | 4 +--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/build/php.m4 b/build/php.m4 index 012b8753f6fd9..da316944f3e2a 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -128,10 +128,20 @@ AC_DEFUN([PHP_INIT_BUILD_SYSTEM], php_shtool=$srcdir/build/shtool T_MD=$($php_shtool echo -n -e %B) T_ME=$($php_shtool echo -n -e %b) + +dnl Create empty Makefile placeholders. > Makefile.objects > Makefile.fragments + +dnl Mark whether the CFLAGS are set to automatic default value by Autoconf, or +dnl they are manually modified by the environment variable from outside. E.g. +dnl './configure CFLAGS=...'. Set this before the AC_PROG_CC, where Autoconf +dnl adjusts the CFLAGS variable, so the checks can modify CFLAGS. +AS_VAR_IF([CFLAGS],, [auto_cflags=1]) + dnl Required programs. PHP_PROG_AWK + dnl Run at the end of the configuration, before creating the config.status. AC_CONFIG_COMMANDS_PRE( [dnl Directory for storing shared objects of extensions. diff --git a/configure.ac b/configure.ac index f54b93fdf4052..f01cb5379f851 100644 --- a/configure.ac +++ b/configure.ac @@ -100,9 +100,6 @@ dnl ---------------------------------------------------------------------------- PHP_INIT_BUILD_SYSTEM -dnl We want this one before the checks, so the checks can modify CFLAGS. -AS_VAR_IF([CFLAGS],, [auto_cflags=1]) - abs_srcdir=`(cd $srcdir; pwd)` abs_builddir=`pwd` diff --git a/scripts/phpize.m4 b/scripts/phpize.m4 index 4bfe79dc4575f..a4d71b0e33cf3 100644 --- a/scripts/phpize.m4 +++ b/scripts/phpize.m4 @@ -26,7 +26,7 @@ AC_DEFUN([PHP_ALWAYS_SHARED],[ test "[$]$1" = "no" && $1=yes ])dnl -AS_VAR_IF([CFLAGS],, [auto_cflags=1]) +PHP_INIT_BUILD_SYSTEM abs_srcdir=`(cd $srcdir && pwd)` abs_builddir=`pwd` @@ -65,8 +65,6 @@ PHP_EXECUTABLE=`$PHP_CONFIG --php-binary 2>/dev/null` AS_VAR_IF([prefix],, [AC_MSG_ERROR([Cannot find php-config. Please use --with-php-config=PATH])]) -PHP_INIT_BUILD_SYSTEM - AC_MSG_CHECKING([for PHP prefix]) AC_MSG_RESULT([$prefix]) AC_MSG_CHECKING([for PHP includes]) From 775ca03eb8c5f1f3dc3ca528206f7e6b5c0949fd Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 20 Aug 2024 14:18:43 +0200 Subject: [PATCH 101/280] ext/standard/crc32: Use zend_result return type and remove unused header --- ext/standard/crc32.c | 3 +-- ext/standard/crc32.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index d9ccd78feb53b..e99c3ca9f5a02 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -15,7 +15,6 @@ */ #include "php.h" -#include "basic_functions.h" #include "crc32.h" #include "crc32_x86.h" @@ -129,7 +128,7 @@ PHPAPI uint32_t php_crc32_bulk_update(uint32_t crc, const char *p, size_t nr) return crc; } -PHPAPI int php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr) +PHPAPI zend_result php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr) { size_t handled = 0, n; char buf[1024]; diff --git a/ext/standard/crc32.h b/ext/standard/crc32.h index bdf45a4bef511..261acdeb1feca 100644 --- a/ext/standard/crc32.h +++ b/ext/standard/crc32.h @@ -29,7 +29,7 @@ PHPAPI uint32_t php_crc32_bulk_update(uint32_t crc, const char *p, size_t nr); /* Return FAILURE if stream reading fail */ -PHPAPI int php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr); +PHPAPI zend_result php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr); /* generated using the AUTODIN II polynomial * x^32 + x^26 + x^23 + x^22 + x^16 + From 3ed5eee5d3ae03c992fc66c502b73eba9c392edf Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 20 Aug 2024 14:48:52 +0200 Subject: [PATCH 102/280] [skip ci] Fix bug71162.phpt xfail message (GH-15506) The test failure is unlikely to be caused by `SessionHandlerInterface` not being available. --- ext/session/tests/user_session_module/bug71162.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/session/tests/user_session_module/bug71162.phpt b/ext/session/tests/user_session_module/bug71162.phpt index 12199d58d39c7..673e6ac2ecb19 100644 --- a/ext/session/tests/user_session_module/bug71162.phpt +++ b/ext/session/tests/user_session_module/bug71162.phpt @@ -5,7 +5,7 @@ session --INI-- session.use_strict_mode=0 --XFAIL-- -Current session module is designed to write empty session always. In addition, current session module only supports SessionHandlerInterface only from PHP 7.0. +Current session module is designed to write empty session always. --FILE-- Date: Fri, 16 Aug 2024 21:01:56 +0200 Subject: [PATCH 103/280] Fix GH-15432: Heap corruption when querying a vector Since the mysqlnd result set is arena allocated, we must not simply free it, but rather call the appropriate `free_result` method. Co-authored-by: Kamil Tekiela --- NEWS | 4 ++++ ext/mysqli/tests/gh15432.phpt | 24 ++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_result.c | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 ext/mysqli/tests/gh15432.phpt diff --git a/NEWS b/NEWS index d845ea39635f9..c36d0465bea89 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.24 +- MySQLnd: + . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, + Kamil Tekiela) + 29 Aug 2024, PHP 8.2.23 - Core: diff --git a/ext/mysqli/tests/gh15432.phpt b/ext/mysqli/tests/gh15432.phpt new file mode 100644 index 0000000000000..50372a1bbc544 --- /dev/null +++ b/ext/mysqli/tests/gh15432.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug GH-15432 (Heap corruption when querying a vector) +--EXTENSIONS-- +mysqli +--SKIPIF-- +server_version < 90000 || $link->server_version >= 10_00_00) { + die("skip MySQL 9.0.0+ needed"); +} +?> +--FILE-- +query('SELECT STRING_TO_VECTOR("[1.05, -17.8, 32]")')); +?> +--EXPECTF-- +Warning: mysqli::query(): Unknown type 242 sent by the server. Please send a report to the developers in %s on line %d +bool(false) diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index cf091a802bb66..43983279e7705 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -302,7 +302,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s) if (FAIL == (ret = result->m.read_result_metadata(result, conn))) { /* For PS, we leave them in Prepared state */ if (!stmt && conn->current_result) { - mnd_efree(conn->current_result); + conn->current_result->m.free_result(conn->current_result, TRUE); conn->current_result = NULL; } DBG_ERR("Error occurred while reading metadata"); From 96840072fc2f2214fefa73583f28e02c5d300ddc Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 20 Aug 2024 16:00:00 +0200 Subject: [PATCH 104/280] Cater to raised requirement of fbclient 3.0+ for pdo_firebird (GH-15498) We * Document the fbclient 3.0+ version requirement * Windows: check existence of Interface.h Since we now require fbclient (3.0), we can drop support for the Interbase gds32_ms.lib right away. * POSIX: check for minimum required libfbclient version with fb_config * POSIX: check for `fb_get_master_interface()` The existence of `isc_detach_database` is implied by this. * POSIX: remove detection of unsupported or even wrong libraries libgds is for old Interbase which is incompatible with pdo_firebird for may years, and libib_util is a utitity library, not a replacement for libfbclient. Co-authored-by: Peter Kokot --- UPGRADING | 3 ++- ext/pdo_firebird/config.m4 | 16 ++++++---------- ext/pdo_firebird/config.w32 | 11 ++++++----- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/UPGRADING b/UPGRADING index 6e20a824b089c..d9bc98f9b550a 100644 --- a/UPGRADING +++ b/UPGRADING @@ -148,7 +148,8 @@ PHP 8.4 UPGRADE NOTES - PDO_FIREBIRD: . Since some Firebird C++ APIs are used now, this extension requires a C++ - compiler to be built. + compiler to be built. This also implies that the extension has to be built + against fbclient 3.0 or higher. . getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool. - PDO_MYSQL: diff --git a/ext/pdo_firebird/config.m4 b/ext/pdo_firebird/config.m4 index 18db4eda20897..f328dbd03b1b5 100644 --- a/ext/pdo_firebird/config.m4 +++ b/ext/pdo_firebird/config.m4 @@ -13,6 +13,8 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then FB_LIBDIR=$($FB_CONFIG --libs) FB_VERSION=$($FB_CONFIG --version) AC_MSG_RESULT([version $FB_VERSION]) + AS_VERSION_COMPARE([$FB_VERSION], [3.0], + [AC_MSG_ERROR([Firebird required version is at least 3.0])]) PHP_EVAL_LIBLINE([$FB_LIBDIR], [PDO_FIREBIRD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$FB_CFLAGS]) else @@ -26,17 +28,11 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then FIREBIRD_LIBDIR_FLAG=-L$FIREBIRD_LIBDIR ]) - PHP_CHECK_LIBRARY([fbclient], [isc_detach_database], - [FIREBIRD_LIBNAME=fbclient], - [PHP_CHECK_LIBRARY([gds], [isc_detach_database], - [FIREBIRD_LIBNAME=gds], - [PHP_CHECK_LIBRARY([ib_util], [isc_detach_database], - [FIREBIRD_LIBNAME=ib_util], - [AC_MSG_FAILURE([libfbclient, libgds or libib_util not found.])], - [$FIREBIRD_LIBDIR_FLAG])], - [$FIREBIRD_LIBDIR_FLAG])], + PHP_CHECK_LIBRARY([fbclient], [fb_get_master_interface], + [], + [AC_MSG_FAILURE([libfbclient not found.])], [$FIREBIRD_LIBDIR_FLAG]) - PHP_ADD_LIBRARY_WITH_PATH([$FIREBIRD_LIBNAME], + PHP_ADD_LIBRARY_WITH_PATH([fbclient], [$FIREBIRD_LIBDIR], [PDO_FIREBIRD_SHARED_LIBADD]) PHP_ADD_INCLUDE([$FIREBIRD_INCDIR]) diff --git a/ext/pdo_firebird/config.w32 b/ext/pdo_firebird/config.w32 index f7cd342120ff2..003a1a677082a 100644 --- a/ext/pdo_firebird/config.w32 +++ b/ext/pdo_firebird/config.w32 @@ -4,11 +4,12 @@ ARG_WITH("pdo-firebird", "Firebird support for PDO", "no"); if (PHP_PDO_FIREBIRD != "no") { - if ((CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - || CHECK_LIB("gds32_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - ) && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", - PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) - ) { + if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) + && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", + PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) + && CHECK_HEADER_ADD_INCLUDE("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", + PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) + ) { EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c pdo_firebird_utils.cpp"); ADD_FLAG("CFLAGS_PDO_FIREBIRD", "/EHsc"); From b75775ea39b22f7a81f3606a0e8c01c421c26bea Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 20 Aug 2024 16:09:46 +0200 Subject: [PATCH 105/280] Revert "Merge branch 'PHP-8.3'" This reverts commit b363a606a4ae8a7ca86f9338b5bffe4376716ed9, reversing changes made to 3ed5eee5d3ae03c992fc66c502b73eba9c392edf. --- Zend/zend_max_execution_timer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 2ef59bbdaac25..005ce14868a0a 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -27,13 +27,14 @@ # include # endif +#include "zend.h" +#include "zend_globals.h" +#include "zend_portability.h" + #if __has_feature(memory_sanitizer) # include #endif -#include "zend.h" -#include "zend_globals.h" - // Musl Libc defines this macro, glibc does not // According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 # ifndef sigev_notify_thread_id @@ -67,8 +68,8 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ #if __has_feature(memory_sanitizer) /* MSan does not intercept timer_create() */ - __msan_unpoison(&EG(max_execution_timer_timer), - sizeof(EG(max_execution_timer_timer))); + __msan_unpoison(&EG(max_execution_timer_timer), + sizeof(EG(max_execution_timer_timer))); #endif // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 From 6652a340068156c347cec7fb5422283367a242e7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 20 Aug 2024 16:17:19 +0200 Subject: [PATCH 106/280] [skip ci] Fix NEWS --- NEWS | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index c36d0465bea89..05aec1bdc3cea 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.24 +- Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) + - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) @@ -9,8 +13,6 @@ PHP NEWS 29 Aug 2024, PHP 8.2.23 - Core: - . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). - (zeriyoshi) . Fixed bug GH-15020 (Memory leak in Zend/Optimizer/escape_analysis.c). (nielsdos) . Fixed bug GH-15023 (Memory leak in Zend/zend_ini.c). (nielsdos) From 3059adae06d8c96b633a8d8de8d2cd7b70b5e3ae Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 20 Aug 2024 15:24:25 +0100 Subject: [PATCH 107/280] ext/standard: Improve checking of allowed_classes option (#15267) * ext/standard: Add some unserializing tests * ext/standard: Add proper type checking for values of the allowed_classes option array * ext/standard: Check that class names are somewhat sensible for the allowed_classes option array * Indicate type of value * Add test for Stringable objects --- ..._allowed_classes_option_invalid_array.phpt | 61 +++++++++++++++++++ ...ed_classes_option_invalid_class_names.phpt | 48 +++++++++++++++ ...allowed_classes_option_invalid_value.phpt} | 0 ...lowed_classes_option_stringable_value.phpt | 32 ++++++++++ ext/standard/var.c | 31 ++++++---- 5 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt create mode 100644 ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt rename ext/standard/tests/serialize/{unserialize_error_001.phpt => unserialize_allowed_classes_option_invalid_value.phpt} (100%) create mode 100644 ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt new file mode 100644 index 0000000000000..a13334baacaa1 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt @@ -0,0 +1,61 @@ +--TEST-- +Test unserialize() with array allowed_classes and nonsensical values +--FILE-- + [null]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [false]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [true]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [42]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [15.2]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [[]]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [STDERR]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [new stdClass]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, null given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, false given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, true given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, int given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, float given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, array given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, resource given +Error: Object of class stdClass could not be converted to string diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt new file mode 100644 index 0000000000000..74997939817d8 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test unserialize() with array allowed_classes and nonsensical class names +--FILE-- + [""]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["245blerg"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [" whitespace "]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["name\nwith whitespace"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ['$dollars']]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["have\0nul_byte"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, " whitespace " given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "name +with whitespace" given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "$dollars" given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "have" given diff --git a/ext/standard/tests/serialize/unserialize_error_001.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_value.phpt similarity index 100% rename from ext/standard/tests/serialize/unserialize_error_001.phpt rename to ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_value.phpt diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt new file mode 100644 index 0000000000000..5868cf9e923f0 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test unserialize() with Stringable object in allowed_classes +--FILE-- + [$o]])); +?> +--EXPECT-- +array(3) { + [0]=> + object(foo)#3 (1) { + ["x"]=> + string(3) "bar" + } + [1]=> + int(2) + [2]=> + string(1) "3" +} diff --git a/ext/standard/var.c b/ext/standard/var.c index dd2bd86d91ee8..7e51a23e3c029 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1370,25 +1370,34 @@ PHPAPI void php_unserialize_with_options(zval *return_value, const char *buf, co goto cleanup; } - if(classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) { + if (classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) { ALLOC_HASHTABLE(class_hash); zend_hash_init(class_hash, (Z_TYPE_P(classes) == IS_ARRAY)?zend_hash_num_elements(Z_ARRVAL_P(classes)):0, NULL, NULL, 0); } - if(class_hash && Z_TYPE_P(classes) == IS_ARRAY) { + if (class_hash && Z_TYPE_P(classes) == IS_ARRAY) { zval *entry; - zend_string *lcname; ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(classes), entry) { - convert_to_string(entry); - lcname = zend_string_tolower(Z_STR_P(entry)); + ZVAL_DEREF(entry); + if (UNEXPECTED(Z_TYPE_P(entry) != IS_STRING && Z_TYPE_P(entry) != IS_OBJECT)) { + zend_type_error("%s(): Option \"allowed_classes\" must be an array of class names, %s given", + function_name, zend_zval_value_name(entry)); + goto cleanup; + } + zend_string *name = zval_try_get_string(entry); + if (UNEXPECTED(name == NULL)) { + goto cleanup; + } + if (UNEXPECTED(!zend_is_valid_class_name(name))) { + zend_value_error("%s(): Option \"allowed_classes\" must be an array of class names, \"%s\" given", function_name, ZSTR_VAL(name)); + zend_string_release_ex(name, false); + goto cleanup; + } + zend_string *lcname = zend_string_tolower(name); zend_hash_add_empty_element(class_hash, lcname); - zend_string_release_ex(lcname, 0); + zend_string_release_ex(name, false); + zend_string_release_ex(lcname, false); } ZEND_HASH_FOREACH_END(); - - /* Exception during string conversion. */ - if (EG(exception)) { - goto cleanup; - } } php_var_unserialize_set_allowed_classes(var_hash, class_hash); From 588029a989401e0f32445174e8bf6242205ed2a7 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 20 Aug 2024 16:28:01 +0200 Subject: [PATCH 108/280] [skip ci] Update NEWS/UPGRADING for allowed_classes option checks --- NEWS | 5 +++++ UPGRADING | 2 ++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 05ba8a9ba93b9..31c2a4fdda1d0 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,11 @@ PHP NEWS . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) +- Standard: + . The "allowed_classes" option for unserialize() now throws TypeErrors and + ValueErrors if it is not an array of class names. (Girgias) + + 15 Aug 2024, PHP 8.4.0beta3 - Core: diff --git a/UPGRADING b/UPGRADING index d9bc98f9b550a..7778dbbde030e 100644 --- a/UPGRADING +++ b/UPGRADING @@ -202,6 +202,8 @@ PHP 8.4 UPGRADE NOTES byte long or the empty string. This aligns the behaviour to be identical to that of fputcsv() and fgetcsv(). . php_uname() now throws ValueErrors on invalid inputs. + . The "allowed_classes" option for unserialize() now throws TypeErrors and + ValueErrors if it is not an array of class names. - Tidy: . Failures in the constructor now throw exceptions rather than emitting From 89daa8354fd891b272fdcd97b348f7b538363a20 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Sat, 17 Aug 2024 05:20:04 +0900 Subject: [PATCH 109/280] zend_max_execution_timer: fix gcc compatibility (#15447) --- Zend/zend_max_execution_timer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 6ab2c0892c038..6cd2300d3ff43 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -24,13 +24,14 @@ #include #include +#include "zend.h" +#include "zend_globals.h" +#include "zend_portability.h" + #if __has_feature(memory_sanitizer) # include #endif -#include "zend.h" -#include "zend_globals.h" - // Musl Libc defines this macro, glibc does not // According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 # ifndef sigev_notify_thread_id @@ -53,8 +54,8 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ #if __has_feature(memory_sanitizer) /* MSan does not intercept timer_create() */ - __msan_unpoison(&EG(max_execution_timer_timer), - sizeof(EG(max_execution_timer_timer))); + __msan_unpoison(&EG(max_execution_timer_timer), + sizeof(EG(max_execution_timer_timer))); #endif // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 From c9ea4d76af17c016f7c4e8e97e725bf6462b0b47 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 20 Aug 2024 16:34:52 +0200 Subject: [PATCH 110/280] Revert "Merge branch 'PHP-8.3'" This reverts commit a2313cea5a7bc2770363d5b3409242241b33833a, reversing changes made to 588029a989401e0f32445174e8bf6242205ed2a7. --- Zend/zend_max_execution_timer.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 3269bfc1517b7..005ce14868a0a 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -31,10 +31,6 @@ #include "zend_globals.h" #include "zend_portability.h" -#include "zend.h" -#include "zend_globals.h" -#include "zend_portability.h" - #if __has_feature(memory_sanitizer) # include #endif From a1ab846231aeff49c0441a30ebd44463fc7825b1 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Tue, 20 Aug 2024 17:34:52 +0200 Subject: [PATCH 111/280] MySQL 9: Add support for VECTOR type (#15431) --- ext/mysqli/mysqli.stub.php | 5 +++ ext/mysqli/mysqli_arginfo.h | 3 +- ext/mysqli/tests/gh15432.phpt | 50 +++++++++++++++++++++++--- ext/mysqli/tests/mysqli_constants.phpt | 4 +-- ext/mysqlnd/mysqlnd_enum_n_def.h | 2 ++ ext/mysqlnd/mysqlnd_ps_codec.c | 4 +++ ext/mysqlnd/mysqlnd_wireprotocol.c | 2 ++ 7 files changed, 62 insertions(+), 8 deletions(-) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index d680678d088c0..dbed931c93959 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -400,6 +400,11 @@ * @cvalue FIELD_TYPE_GEOMETRY */ const MYSQLI_TYPE_GEOMETRY = UNKNOWN; +/** + * @var int + * @cvalue FIELD_TYPE_VECTOR + */ +const MYSQLI_TYPE_VECTOR = UNKNOWN; #ifdef FIELD_TYPE_JSON /** * @var int diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 11bf8cae5f61e..2a66413c8012a 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6a64c5833a4c83d0bd0e63f34d27d2e696c78b66 */ + * Stub hash: ff768a152d4ee91b184999d351ce39a7d0bfef46 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1118,6 +1118,7 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VECTOR", FIELD_TYPE_VECTOR, CONST_PERSISTENT); #if defined(FIELD_TYPE_JSON) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_JSON", FIELD_TYPE_JSON, CONST_PERSISTENT); #endif diff --git a/ext/mysqli/tests/gh15432.phpt b/ext/mysqli/tests/gh15432.phpt index 50372a1bbc544..5428fb2d14168 100644 --- a/ext/mysqli/tests/gh15432.phpt +++ b/ext/mysqli/tests/gh15432.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug GH-15432 (Heap corruption when querying a vector) +Bug GH-15432 (Heap corruption when querying a vector/PHP crashes when processing a MySQL DB query with a new Vector format introduced in MySQL 9.0) --EXTENSIONS-- mysqli --SKIPIF-- @@ -16,9 +16,49 @@ if ($link->server_version < 90000 || $link->server_version >= 10_00_00) { --FILE-- query('SELECT STRING_TO_VECTOR("[1.05, -17.8, 32]")')); + +$expected = '00000040000040400000a040'; + +mysqli_query($link, "DROP TABLE IF EXISTS test"); +mysqli_query($link, "CREATE TABLE test(vectorfield VECTOR)"); +mysqli_query($link, 'INSERT INTO test VALUES (TO_VECTOR("[2, 3, 5]"))'); + +// Textual protocol +$result = mysqli_query($link, "SELECT vectorfield FROM test")->fetch_column(); +$value = bin2hex($result); +if($value !== $expected) { + printf("[001] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($value), $value); +} + +// Binary protocol +$result = $link->execute_query("SELECT vectorfield FROM test")->fetch_column(); +$value = bin2hex($result); +if($value !== $expected) { + printf("[002] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($value), $value); +} + +// Testing inverse to make sure the value hasn't been changed +$expected = '[2.00000e+00,3.00000e+00,5.00000e+00]'; +$result = $link->execute_query("SELECT VECTOR_TO_STRING(0x". $value .")")->fetch_column(); +if($result !== $expected) { + printf("[002] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($result), $result); +} + +echo "OK"; +?> +--CLEAN-- + ---EXPECTF-- -Warning: mysqli::query(): Unknown type 242 sent by the server. Please send a report to the developers in %s on line %d -bool(false) +--EXPECT-- +OK diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 6bddcb5980e6f..1e51e0c92b096 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -66,6 +66,8 @@ $expected_constants = array( "MYSQLI_TYPE_NEWDATE" => true, "MYSQLI_TYPE_ENUM" => true, "MYSQLI_TYPE_SET" => true, + "MYSQLI_TYPE_VECTOR" => true, + "MYSQLI_TYPE_JSON" => true, "MYSQLI_TYPE_TINY_BLOB" => true, "MYSQLI_TYPE_MEDIUM_BLOB" => true, "MYSQLI_TYPE_LONG_BLOB" => true, @@ -143,8 +145,6 @@ $expected_constants["MYSQLI_DATA_TRUNCATED"] = true; $expected_constants["MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true; $expected_constants["MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true; -$expected_constants["MYSQLI_TYPE_JSON"] = true; - $unexpected_constants = array(); foreach ($constants as $consts) { diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 1f862141a3d61..5739979eccaa1 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -280,6 +280,7 @@ typedef enum mysqlnd_field_types MYSQL_TYPE_NEWDATE = 14, MYSQL_TYPE_VARCHAR = 15, MYSQL_TYPE_BIT = 16, + MYSQL_TYPE_VECTOR=242, MYSQL_TYPE_JSON=245, MYSQL_TYPE_NEWDECIMAL=246, MYSQL_TYPE_ENUM=247, @@ -322,6 +323,7 @@ typedef enum mysqlnd_server_option #define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE #define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM #define FIELD_TYPE_SET MYSQL_TYPE_SET +#define FIELD_TYPE_VECTOR MYSQL_TYPE_VECTOR #define FIELD_TYPE_JSON MYSQL_TYPE_JSON #define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB #define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index ca6c2112cffa5..a9c420dd1473b 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -414,6 +414,10 @@ void _mysqlnd_init_ps_fetch_subsystem(void) mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].func = ps_fetch_string; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].pack_len = MYSQLND_PS_SKIP_RESULT_STR; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].php_type = IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].php_type = IS_STRING; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 7c785a31d730f..3b46fb2c985be 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1468,6 +1468,7 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fi case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_LONG_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; + case MYSQL_TYPE_VECTOR: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_VAR_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_GEOMETRY: statistic = STAT_BINARY_TYPE_FETCHED_GEOMETRY; break; @@ -1553,6 +1554,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fiel case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_LONG_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; + case MYSQL_TYPE_VECTOR: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_VAR_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_GEOMETRY: statistic = STAT_TEXT_TYPE_FETCHED_GEOMETRY; break; From c5ae122b2ffdc43e351de54c3d3f3473c2c1fcf5 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Tue, 20 Aug 2024 17:37:56 +0200 Subject: [PATCH 112/280] Update UPGRADING --- UPGRADING | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UPGRADING b/UPGRADING index 7778dbbde030e..4dbef51a65fda 100644 --- a/UPGRADING +++ b/UPGRADING @@ -882,6 +882,10 @@ PHP 8.4 UPGRADE NOTES . The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE constants have been removed. This functionality was never implemented, neither with mysqlnd nor with libmysql. + . A new constant has been added: MYSQLI_TYPE_VECTOR. + +- Mysqlnd + . Support for the new VECTOR data type from MySQL 9. - OpenSSL: . The OpenSSL extension now requires at least OpenSSL 1.1.1. From 327588abf91fec1caea0b762f1eeb2ca94945891 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 20 Aug 2024 18:44:42 +0200 Subject: [PATCH 113/280] Replace OBJ_PROP_PTR_TO_NUM() with zend_get_property_info_for_slot() I wasn't aware such a function already existed. --- Zend/zend_compile.h | 2 -- Zend/zend_property_hooks.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 69f3ef762ca16..c7e31877b5cd2 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -438,8 +438,6 @@ typedef struct _zend_property_info { ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) -#define OBJ_PROP_PTR_TO_NUM(obj, prop) \ - (((char*)prop - (char*)obj->properties_table) / sizeof(zval)) typedef struct _zend_class_constant { zval value; /* flags are stored in u2 */ diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index 684caafc4dd51..b00a526125c27 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -141,8 +141,7 @@ static void zho_declared_it_fetch_current(zend_object_iterator *iter) } else if (Z_TYPE_P(property) != IS_REFERENCE) { ZVAL_MAKE_REF(property); - zend_class_entry *ce = zobj->ce; - zend_property_info *prop_info = ce->properties_info_table[OBJ_PROP_PTR_TO_NUM(zobj, property)]; + zend_property_info *prop_info = zend_get_property_info_for_slot(zobj, property); if (ZEND_TYPE_IS_SET(prop_info->type)) { ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(property), prop_info); } From 660a860f260f5641e3464002ba28b605ebdad221 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 20 Aug 2024 21:10:50 +0200 Subject: [PATCH 114/280] Fix GH-15501: Windows HAVE_
_H macros defined to 1 or undefined (#15508) Previously the CHECK_HEADER_ADD_INCLUDE function defined the `HAVE_
_H` preprocessor macros to value 0 or 1 whether the `` file was found. This syncs it with Autotools build system where most of these macros are either undefined or defined to 1. In possible edge cases where such macros might be intentionally used like this without being aware that HAVE_HEADER_H can be 0 or 1 on Windows: | #ifdef HAVE_HEADER_H | ... | #endif there is backwards incompatibility for PECL extensions in case the header wouldn't exist on Windows such code wouldn't execute. However, this is considered a bug if such case is present. From the Autotools point of view, the check is correct though and should be used with ifdef/defined() checks. Help text is also synced to Autotools style: `Define to 1 if you have the header file.` --- NEWS | 2 ++ UPGRADING.INTERNALS | 3 +++ ext/com_dotnet/com_dotnet.c | 2 +- ext/com_dotnet/com_extension.c | 8 ++++---- ext/com_dotnet/com_extension.stub.php | 2 +- ext/com_dotnet/com_extension_arginfo.h | 10 +++++----- win32/build/confutils.js | 6 +++--- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 31c2a4fdda1d0..ed499d68b9656 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ PHP NEWS . Fixed bug GH-15187 (Various hooked object iterator issues). (ilutov) . Fixed bug GH-15456 (Crash in get_class_vars() on virtual properties). (ilutov) + . Fixed bug GH-15501 (Windows HAVE_
_H macros defined to 1 or + undefined). (Peter Kokot) - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index ee8412ccafac0..fe4fd258531a5 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -230,6 +230,9 @@ PHP 8.4 INTERNALS UPGRADE NOTES - Added configure option --enable-phpdbg-debug to build phpdbg in debug mode. - The win32/build/libs_version.txt file has been removed. - MSVC builds now use the new preprocessor (/Zc:preprocessor). + - The CHECK_HEADER_ADD_INCLUDE function now consistently defines preprocessor + macros HAVE_
_H either to value 1 or leaves them undefined to match + the Autotools headers checks. ======================== 3. Module changes diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index f52554fb3d87a..3ce2daddaa7b0 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -20,7 +20,7 @@ #include "php.h" -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H # include "php_ini.h" # include "ext/standard/info.h" # include "php_com_dotnet.h" diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c index e6e14a45a9c75..1f18d2a8573ab 100644 --- a/ext/com_dotnet/com_extension.c +++ b/ext/com_dotnet/com_extension.c @@ -195,7 +195,7 @@ PHP_MINIT_FUNCTION(com_dotnet) tmp->create_object = php_com_object_new; tmp->get_iterator = php_com_iter_get; -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H tmp = register_class_dotnet(php_com_variant_class_entry); tmp->default_object_handlers = &php_com_object_handlers; tmp->create_object = php_com_object_new; @@ -216,7 +216,7 @@ PHP_MINIT_FUNCTION(com_dotnet) PHP_MSHUTDOWN_FUNCTION(com_dotnet) { UNREGISTER_INI_ENTRIES(); -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H if (COMG(dotnet_runtime_stuff)) { php_com_dotnet_mshutdown(); } @@ -239,7 +239,7 @@ PHP_RINIT_FUNCTION(com_dotnet) /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(com_dotnet) { -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H if (COMG(dotnet_runtime_stuff)) { php_com_dotnet_rshutdown(); } @@ -257,7 +257,7 @@ PHP_MINFO_FUNCTION(com_dotnet) php_info_print_table_row(2, "COM support", "enabled"); php_info_print_table_row(2, "DCOM support", COMG(allow_dcom) ? "enabled" : "disabled"); -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H php_info_print_table_row(2, ".Net support", "enabled"); #else php_info_print_table_row(2, ".Net support", "not present in this build"); diff --git a/ext/com_dotnet/com_extension.stub.php b/ext/com_dotnet/com_extension.stub.php index 3207871f85c7d..0bbe976279f6a 100644 --- a/ext/com_dotnet/com_extension.stub.php +++ b/ext/com_dotnet/com_extension.stub.php @@ -363,7 +363,7 @@ class com extends variant public function __construct(string $module_name, array|string|null $server_name = null, int $codepage = CP_ACP, string $typelib = "") {} } -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H class dotnet extends variant { public function __construct(string $assembly_name, string $datatype_name, int $codepage = CP_ACP) {} diff --git a/ext/com_dotnet/com_extension_arginfo.h b/ext/com_dotnet/com_extension_arginfo.h index c75fa6df9c877..1f9fd27b6d164 100644 --- a/ext/com_dotnet/com_extension_arginfo.h +++ b/ext/com_dotnet/com_extension_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b91206482b5119ce6d7c899e9599acfa2e06ec2a */ + * Stub hash: 9b2eea541946c291eb002ee98997f3dcad8bdfce */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_variant_set, 0, 2, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, variant, variant, 0) @@ -123,7 +123,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_com___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, typelib, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_dotnet___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, assembly_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, datatype_name, IS_STRING, 0) @@ -165,7 +165,7 @@ ZEND_FUNCTION(com_message_pump); ZEND_FUNCTION(com_load_typelib); ZEND_METHOD(variant, __construct); ZEND_METHOD(com, __construct); -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) ZEND_METHOD(dotnet, __construct); #endif @@ -215,7 +215,7 @@ static const zend_function_entry class_com_methods[] = { ZEND_FE_END }; -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) static const zend_function_entry class_dotnet_methods[] = { ZEND_ME(dotnet, __construct, arginfo_class_dotnet___construct, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -316,7 +316,7 @@ static zend_class_entry *register_class_com(zend_class_entry *class_entry_varian return class_entry; } -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) static zend_class_entry *register_class_dotnet(zend_class_entry *class_entry_variant) { zend_class_entry ce, *class_entry; diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 78d4291f2feed..1f03454abe8b7 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1040,10 +1040,10 @@ function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env add_to_flag_only = true; } - if (typeof(add_to_flag_only) != "undefined") { + if (typeof(add_to_flag_only) != "undefined" && have) { ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have); - } else if (!configure_hdr.Exists('HAVE_' + sym)) { - AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); + } else if (!configure_hdr.Exists('HAVE_' + sym) && have) { + AC_DEFINE("HAVE_" + sym, have, "Define to 1 if you have the <" + header_name + "> header file."); } return p; From 69d9c12df64e829befd843175bfc9617aabb7450 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Wed, 21 Aug 2024 01:11:31 +0200 Subject: [PATCH 115/280] Fix mysqli_stmt_get_result.phpt (#15495) --- ext/mysqli/tests/mysqli_stmt_get_result.phpt | 52 ++++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt index bfaf111dd6a80..e043f198bd378 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt @@ -28,9 +28,8 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - // FIXME - different versions return different values ?! - if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) - printf("[006] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -39,7 +38,7 @@ require_once 'skipifconnectfailure.inc'; printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (is_object($tmp = mysqli_stmt_store_result($stmt))) - printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_stmt_close($stmt); @@ -56,15 +55,14 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - // FIXME - different versions return different values ?! - if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) - printf("[013] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[013] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_object($tmp = mysqli_stmt_get_result($stmt))) - printf("[016] NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (! ($tmp = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[016] Expecting mysqli_result, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_free_result($tmp); mysqli_stmt_close($stmt); @@ -83,25 +81,25 @@ require_once 'skipifconnectfailure.inc'; printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (false !== ($tmp = mysqli_stmt_get_result($stmt))) - printf("[020] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[020] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_object($tmp = mysqli_stmt_get_result($stmt))) - printf("[024] Expecting object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (! ($tmp = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[024] Expecting mysqli_result, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) { printf("[026] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); printf("[027] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link)); - printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, true)); } if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_stmt_close($stmt); @@ -135,11 +133,11 @@ require_once 'skipifconnectfailure.inc'; $id = NULL; $label = NULL; if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) - printf("[037] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[037] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, true)); - if (!is_object($tmp = $result = mysqli_stmt_get_result($stmt))) - printf("[038] Expecting array, got %s/%s, [%d] %s\n", - gettype($tmp), var_export($tmp, 1), + if (! ($result = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[038] Expecting mysqli_result, got %s/%s, [%d] %s\n", + gettype($result), var_export($result, true), mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (false !== ($tmp = mysqli_stmt_fetch($stmt))) @@ -155,23 +153,23 @@ require_once 'skipifconnectfailure.inc'; $link->real_query('KILL '.mysqli_thread_id($link)); // We kill our own connection so we should get "Query execution was interrupted" - if ($link->errno !== 1317) - printf("[042] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if ($link->errno !== 1317) + printf("[042] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_get_result($stmt))) - printf("[043] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[043] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); - mysqli_stmt_close($stmt); + mysqli_stmt_close($stmt); - try { + try { mysqli_stmt_fetch($stmt); } catch (Error $exception) { echo $exception->getMessage(), "\n"; } - mysqli_close($link); + mysqli_close($link); - print "done!"; + print "done!"; ?> --CLEAN-- Date: Sun, 16 Jun 2024 09:39:18 +0200 Subject: [PATCH 116/280] fixes #13773: DatePeriod does not take microseconds into account --- ext/date/php_date.c | 12 +++-- ext/date/tests/date_period_include_end.phpt | 1 - ext/date/tests/date_period_microseconds.phpt | 51 ++++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 ext/date/tests/date_period_microseconds.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index bfff54c2b6d23..1609b7c510ff2 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1578,11 +1578,15 @@ static zend_result date_period_it_has_more(zend_object_iterator *iter) php_period_obj *object = Z_PHPPERIOD_P(&iterator->intern.data); if (object->end) { - if (object->include_end_date) { - return object->current->sse <= object->end->sse ? SUCCESS : FAILURE; - } else { - return object->current->sse < object->end->sse ? SUCCESS : FAILURE; + if (object->current->sse == object->end->sse) { + if (object->include_end_date) { + return object->current->us <= object->end->us ? SUCCESS : FAILURE; + } else { + return object->current->us < object->end->us ? SUCCESS : FAILURE; + } } + + return object->current->sse < object->end->sse ? SUCCESS : FAILURE; } else { return (iterator->current_index < object->recurrences) ? SUCCESS : FAILURE; } diff --git a/ext/date/tests/date_period_include_end.phpt b/ext/date/tests/date_period_include_end.phpt index c96e279465367..17a059e9dceb9 100644 --- a/ext/date/tests/date_period_include_end.phpt +++ b/ext/date/tests/date_period_include_end.phpt @@ -16,4 +16,3 @@ foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) a 2010-06-08 2010-06-09 2010-06-10 - diff --git a/ext/date/tests/date_period_microseconds.phpt b/ext/date/tests/date_period_microseconds.phpt new file mode 100644 index 0000000000000..e2329acc94ae5 --- /dev/null +++ b/ext/date/tests/date_period_microseconds.phpt @@ -0,0 +1,51 @@ +--TEST-- +DatePeriod: take microseconds into account +--FILE-- +format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (exclusive)\n"; +foreach (new DatePeriod($start, $interval, $end) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (inclusive)\n"; +foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +$end = new DateTime('2010-06-10T01:02:03.456790'); +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (exclusive)\n"; +foreach (new DatePeriod($start, $interval, $end) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +$end = new DateTime('2010-06-10T01:02:03.456788'); +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (inclusive)\n"; +foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +?> +--EXPECT-- +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456789 (exclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456789 (inclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +2010-06-10 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456790 (exclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +2010-06-10 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456788 (inclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 From 0f7aebb61aed11b7091422d451faee741ce5d521 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Wed, 21 Aug 2024 10:59:25 +0100 Subject: [PATCH 117/280] Add NEWS entry --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index ed499d68b9656..24a50d2ac795b 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ PHP NEWS . Fixed bug GH-15501 (Windows HAVE_
_H macros defined to 1 or undefined). (Peter Kokot) +- Date: + . Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end + date). (Mark Bennewitz, Derick) + - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) From c290996db6058eb49b8c28bb0ec1cdaac85275a4 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Tue, 20 Aug 2024 14:30:56 +0200 Subject: [PATCH 118/280] Remove MYSQLI_TYPE_INTERVAL constant --- UPGRADING | 4 ++++ ext/mysqli/mysqli.stub.php | 5 ----- ext/mysqli/mysqli_arginfo.h | 3 +-- ext/mysqli/tests/bug_mysql_49406.phpt | 1 - ext/mysqli/tests/mysqli_constants.phpt | 1 - ext/mysqli/tests/mysqli_fetch_field_types.phpt | 1 - ext/mysqlnd/mysqlnd_enum_n_def.h | 1 - 7 files changed, 5 insertions(+), 11 deletions(-) diff --git a/UPGRADING b/UPGRADING index 4dbef51a65fda..48740ce43418e 100644 --- a/UPGRADING +++ b/UPGRADING @@ -882,6 +882,10 @@ PHP 8.4 UPGRADE NOTES . The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE constants have been removed. This functionality was never implemented, neither with mysqlnd nor with libmysql. + . The unused MYSQLI_TYPE_INTERVAL constant, which is currently a stub + and an alias for MYSQLI_TYPE_ENUM, has been removed. There are no + plans to add such data type to MySQL yet, so it's unclear what its value + would finally be. . A new constant has been added: MYSQLI_TYPE_VECTOR. - Mysqlnd diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index dbed931c93959..9b98369600e38 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -390,11 +390,6 @@ * @cvalue FIELD_TYPE_CHAR */ const MYSQLI_TYPE_CHAR = UNKNOWN; -/** - * @var int - * @cvalue FIELD_TYPE_INTERVAL - */ -const MYSQLI_TYPE_INTERVAL = UNKNOWN; /** * @var int * @cvalue FIELD_TYPE_GEOMETRY diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 2a66413c8012a..223fe9b7f8cef 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: ff768a152d4ee91b184999d351ce39a7d0bfef46 */ + * Stub hash: 245640045ed8172d7772b708787c400f29bb607b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1116,7 +1116,6 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VECTOR", FIELD_TYPE_VECTOR, CONST_PERSISTENT); #if defined(FIELD_TYPE_JSON) diff --git a/ext/mysqli/tests/bug_mysql_49406.phpt b/ext/mysqli/tests/bug_mysql_49406.phpt index f9dd11b619bcc..09cc544a12b75 100644 --- a/ext/mysqli/tests/bug_mysql_49406.phpt +++ b/ext/mysqli/tests/bug_mysql_49406.phpt @@ -58,7 +58,6 @@ require_once 'skipifconnectfailure.inc'; MYSQLI_TYPE_STRING => "STRING", MYSQLI_TYPE_NULL => "NULL", MYSQLI_TYPE_NEWDATE => "NEWDATE", - MYSQLI_TYPE_INTERVAL => "INTERVAL", MYSQLI_TYPE_GEOMETRY => "GEOMETRY", ); diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 1e51e0c92b096..982fe47f75cef 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -75,7 +75,6 @@ $expected_constants = array( "MYSQLI_TYPE_VAR_STRING" => true, "MYSQLI_TYPE_STRING" => true, "MYSQLI_TYPE_CHAR" => true, - "MYSQLI_TYPE_INTERVAL" => true, "MYSQLI_TYPE_GEOMETRY" => true, "MYSQLI_NO_DATA" => true, "MYSQLI_REPORT_INDEX" => true, diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt index 041eb16694a7c..0b810abc3a8c9 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -92,7 +92,6 @@ require_once 'skipifconnectfailure.inc'; MYSQLI_TYPE_STRING => array("SET('I', 'smash', 'the')", 'smash'), MYSQLI_TYPE_NULL => 'MYSQLI_TYPE_NULL - TODO add testing', MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', - MYSQLI_TYPE_INTERVAL => 'MYSQLI_TYPE_INTERVAL - TODO add testing', MYSQLI_TYPE_GEOMETRY => 'MYSQLI_TYPE_GEOMETRY - TODO add testing', ); diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 5739979eccaa1..15db002aa7349 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -332,7 +332,6 @@ typedef enum mysqlnd_server_option #define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING #define FIELD_TYPE_STRING MYSQL_TYPE_STRING #define FIELD_TYPE_CHAR MYSQL_TYPE_TINY -#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM #define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY #define FIELD_TYPE_BIT MYSQL_TYPE_BIT From 0775b99d5e0e0918b38e41f346899926fb0fbbe4 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Tue, 20 Aug 2024 15:05:06 +0200 Subject: [PATCH 119/280] Fix mysqli_fetch_field_types.phpt --- .../tests/mysqli_fetch_field_types.phpt | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt index 0b810abc3a8c9..feb72cabf7a6c 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -30,7 +30,7 @@ require_once 'skipifconnectfailure.inc'; $sql = sprintf("INSERT INTO test(id) VALUES (%s)", $php_value); if (!mysqli_query($link, $sql)) { - printf("[003] '%s' - '%s' - '%s', [%d] %s\n", $sql_type, $create, $sql, + printf("[003] '%s' - '%s', [%d] %s\n", $sql_type, $sql, mysqli_errno($link), mysqli_error($link)); return false; } @@ -67,7 +67,7 @@ require_once 'skipifconnectfailure.inc'; $datatypes = array( MYSQLI_TYPE_TINY => array('TINYINT', 5), MYSQLI_TYPE_SHORT => array('SMALLINT', 10), - MYSQLI_TYPE_LONG => 'MYSQLI_TYPE_LONG - TODO add testing', + MYSQLI_TYPE_LONG => array('INT', 15), MYSQLI_TYPE_FLOAT => array('FLOAT', '1.3'), MYSQLI_TYPE_DOUBLE => array('DOUBLE', '1.4'), MYSQLI_TYPE_TIMESTAMP => array('TIMESTAMP', '2007-08-20 18:34:00'), @@ -77,30 +77,23 @@ require_once 'skipifconnectfailure.inc'; MYSQLI_TYPE_TIME => array('TIME', '18:41:38'), MYSQLI_TYPE_DATETIME => array('DATETIME', '2007-08-20 18:42:01'), MYSQLI_TYPE_YEAR => array('YEAR', '2007'), - MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'), - // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), - string - // MYSQLI_TYPE_TINY_BLOB => array("TINYBLOB", "I got a tiny blog"), - blob - // MYSQLI_TYPE_MEDIUM_BLOB => array("MEDIUMBLOB", "No blob for masses"), - blob - // MYSQLI_TYPE_LONG_BLOB => array("LONGBLOB", "Small is beautiful?"), - blob - MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), - MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), - MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'), // We cannot test ENUM because every ENUM value is just a plain string => MYSQLI_TYPE_STRING + // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), // We cannot test SET because every SET value is just a plain string => MYSQLI_TYPE_STRING + // MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), MYSQLI_TYPE_BLOB => array("BLOB", 'silly'), MYSQLI_TYPE_VAR_STRING => array("VARCHAR(32768)", 'varchar'), - MYSQLI_TYPE_STRING => 'MYSQLI_TYPE_STRING - TODO add testing', MYSQLI_TYPE_STRING => array('CHAR(1)', 'a'), - MYSQLI_TYPE_STRING => array("SET('I', 'smash', 'the')", 'smash'), - MYSQLI_TYPE_NULL => 'MYSQLI_TYPE_NULL - TODO add testing', - MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', - MYSQLI_TYPE_GEOMETRY => 'MYSQLI_TYPE_GEOMETRY - TODO add testing', + // MYSQLI_TYPE_NULL => array('CHAR(1) NULL', null), // We cannot test NULL because MySQL doesn't have standalone NULL type, only nullable types + // MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', // This is an internal type, not a real MySQL type + // MYSQLI_TYPE_GEOMETRY => array('GEOMETRY', 'TODO add testing'), + MYSQLI_TYPE_NEWDECIMAL => array('DECIMAL', '1.1'), + MYSQLI_TYPE_BIT => array('BIT', 0), ); - $datatypes[MYSQLI_TYPE_NEWDECIMAL] = array('DECIMAL', '1.1'); - $datatypes[MYSQLI_TYPE_BIT] = array('BIT', 0); - foreach ($datatypes as $php_type => $datatype) { - if (is_array($datatype)) - mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes); + mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes); } mysqli_close($link); From d4263ddc40358f5267d5e621c66f4ed74c70b5b9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 21 Aug 2024 13:25:16 +0200 Subject: [PATCH 120/280] Fix rename_variation12*.phpt parallel test conflicts (GH-15518) For rename_variation12.phpt this is actually not necessary, since there is no rename_variation11.phpt, but we still fix it to be in sync with rename_variation12-win32.phpt which actually is prone to parallel conflicts. Since we already ran CI in the PR, we can now [skip ci]. --- ext/standard/tests/file/rename_variation12-win32.phpt | 8 ++++---- ext/standard/tests/file/rename_variation12.phpt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/standard/tests/file/rename_variation12-win32.phpt b/ext/standard/tests/file/rename_variation12-win32.phpt index 7ecaed35d7dc7..527a8865c331e 100644 --- a/ext/standard/tests/file/rename_variation12-win32.phpt +++ b/ext/standard/tests/file/rename_variation12-win32.phpt @@ -11,8 +11,8 @@ if (substr(PHP_OS, 0, 3) != 'WIN') die('skip.. for Windows'); /* Creating unique files in various dirs by passing relative paths to $dir arg */ echo "*** Testing rename() with absolute and relative paths ***\n"; -$mainDir = "renameVar11"; -$subDir = "renameVar11Sub"; +$mainDir = "renameVar12"; +$subDir = "renameVar12Sub"; $absMainDir = __DIR__."/".$mainDir; mkdir($absMainDir); $absSubDir = $absMainDir."/".$subDir; @@ -83,12 +83,12 @@ bool(true) -- Iteration 5 -- -Warning: rename(%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/renameMe.tmp,%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/renameMe.tmp,%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d bool(false) -- Iteration 6 -- -Warning: rename(%s/renameVar11/renameVar11Sub/BADDIR/renameMe.tmp,%s/renameVar11/renameVar11Sub/BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/BADDIR/renameMe.tmp,%s/renameVar12/renameVar12Sub/BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d bool(false) -- Iteration 7 -- diff --git a/ext/standard/tests/file/rename_variation12.phpt b/ext/standard/tests/file/rename_variation12.phpt index b38aab7ed1d0b..8675b17aab5c0 100644 --- a/ext/standard/tests/file/rename_variation12.phpt +++ b/ext/standard/tests/file/rename_variation12.phpt @@ -11,8 +11,8 @@ if (substr(PHP_OS, 0, 3) == 'WIN') die('skip.. not for Windows'); /* Creating unique files in various dirs by passing relative paths to $dir arg */ echo "*** Testing rename() with absolute and relative paths ***\n"; -$mainDir = "renameVar11"; -$subDir = "renameVar11Sub"; +$mainDir = "renameVar12"; +$subDir = "renameVar12Sub"; $absMainDir = __DIR__."/".$mainDir; mkdir($absMainDir); $absSubDir = $absMainDir."/".$subDir; @@ -83,12 +83,12 @@ bool(true) -- Iteration 5 -- -Warning: rename(%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/renameMe.tmp,%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/IwasRenamed.tmp): %s in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/renameMe.tmp,%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/IwasRenamed.tmp): %s in %s on line %d bool(false) -- Iteration 6 -- -Warning: rename(%s/renameVar11/renameVar11Sub/BADDIR/renameMe.tmp,%s/renameVar11/renameVar11Sub/BADDIR/IwasRenamed.tmp): %s in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/BADDIR/renameMe.tmp,%s/renameVar12/renameVar12Sub/BADDIR/IwasRenamed.tmp): %s in %s on line %d bool(false) -- Iteration 7 -- From 369eeb73ca6a25329861af948cc23ce3ea837c8d Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Wed, 21 Aug 2024 02:28:43 +0200 Subject: [PATCH 121/280] ext/standard/file.c: Use RETURN_BOOL() instead of if-else --- ext/standard/file.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index 677fd74d225cf..62a370fd77a54 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1499,11 +1499,7 @@ PHP_FUNCTION(copy) context = php_stream_context_from_zval(zcontext, 0); - if (php_copy_file_ctx(source, target, 0, context) == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(php_copy_file_ctx(source, target, 0, context) == SUCCESS); } /* }}} */ From 9147687b6d5c4491e1e19cb0d80ffabc479593ef Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Wed, 21 Aug 2024 02:36:45 +0200 Subject: [PATCH 122/280] ext/standard/file.c: Use more appropriate types --- ext/standard/file.c | 14 +++++++------- ext/standard/file.h | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index 62a370fd77a54..6b6b43b1fb672 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1504,26 +1504,26 @@ PHP_FUNCTION(copy) /* }}} */ /* {{{ php_copy_file */ -PHPAPI int php_copy_file(const char *src, const char *dest) +PHPAPI zend_result php_copy_file(const char *src, const char *dest) { return php_copy_file_ctx(src, dest, 0, NULL); } /* }}} */ /* {{{ php_copy_file_ex */ -PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_flg) +PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags) { - return php_copy_file_ctx(src, dest, src_flg, NULL); + return php_copy_file_ctx(src, dest, src_flags, NULL); } /* }}} */ /* {{{ php_copy_file_ctx */ -PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php_stream_context *ctx) +PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx) { php_stream *srcstream = NULL, *deststream = NULL; - int ret = FAILURE; + zend_result ret = FAILURE; php_stream_statbuf src_s, dest_s; - int src_stat_flags = (src_flg & STREAM_DISABLE_OPEN_BASEDIR) ? PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR : 0; + int src_stat_flags = (src_flags & STREAM_DISABLE_OPEN_BASEDIR) ? PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR : 0; switch (php_stream_stat_path_ex(src, src_stat_flags, &src_s, ctx)) { case -1: @@ -1590,7 +1590,7 @@ PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php } safe_to_copy: - srcstream = php_stream_open_wrapper_ex(src, "rb", src_flg | REPORT_ERRORS, NULL, ctx); + srcstream = php_stream_open_wrapper_ex(src, "rb", src_flags | REPORT_ERRORS, NULL, ctx); if (!srcstream) { return ret; diff --git a/ext/standard/file.h b/ext/standard/file.h index 0f3ccd7c27ab3..ec5f41c52ad36 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -38,9 +38,9 @@ PHP_MINIT_FUNCTION(user_streams); PHPAPI int php_le_stream_context(void); PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block); -PHPAPI int php_copy_file(const char *src, const char *dest); -PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_chk); -PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_chk, php_stream_context *ctx); +PHPAPI zend_result php_copy_file(const char *src, const char *dest); +PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags); +PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx); PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options); PHPAPI int php_mkdir(const char *dir, zend_long mode); PHPAPI void php_fstat(php_stream *stream, zval *return_value); From 63841ba7cfc368398f9310b785298400f6b7b2d9 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 21 Aug 2024 15:51:27 +0200 Subject: [PATCH 123/280] Fix GH-15515: Configure error grep illegal option q (#15516) On Solaris default grep doesn't support the -q option. In such cases the grep output can be redirected to /dev/null and the exit status is checked. --- NEWS | 1 + configure.ac | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 05aec1bdc3cea..04c850f6c1a7a 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ PHP NEWS - Core: . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). (zeriyoshi) + . Fixed bug GH-15515 (Configure error grep illegal option q). (Peter Kokot) - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, diff --git a/configure.ac b/configure.ac index a9cf70ce470d0..e01d2da2b694d 100644 --- a/configure.ac +++ b/configure.ac @@ -262,7 +262,7 @@ esac dnl Detect musl libc AC_MSG_CHECKING([whether we are using musl libc]) -if command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl +if command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1 then AC_MSG_RESULT(yes) AC_DEFINE([__MUSL__], [1], [Define when using musl libc]) From 48a18e5be7d0b46dee4cbe0c29d4d8e7b875d179 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 21 Aug 2024 18:16:07 +0200 Subject: [PATCH 124/280] Fix bug GH-15514 (Configure error: genif.sh: syntax error) Autoconf assigns the current suitable shell to SHELL variable. This notably fixes cases on Solaris 10 when using C shell or KornShell where genif.sh: syntax error at line 35 occurs due to using the `sh` command. --- NEWS | 1 + configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 04c850f6c1a7a..3dfc4308841ec 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ PHP NEWS . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). (zeriyoshi) . Fixed bug GH-15515 (Configure error grep illegal option q). (Peter Kokot) + . Fixed bug GH-15514 (Configure error: genif.sh: syntax error). (Peter Kokot) - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, diff --git a/configure.ac b/configure.ac index e01d2da2b694d..1142c9459d71c 100644 --- a/configure.ac +++ b/configure.ac @@ -1792,10 +1792,10 @@ FEO dnl Run this only when generating all the files. if test -n "\$REDO_ALL"; then echo "creating main/internal_functions.c" - AWK="$AWK" sh $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_STATIC" > main/internal_functions.c + AWK="$AWK" $SHELL $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_STATIC" > main/internal_functions.c echo "creating main/internal_functions_cli.c" - AWK="$AWK" sh $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_CLI_STATIC" > main/internal_functions_cli.c + AWK="$AWK" $SHELL $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_CLI_STATIC" > main/internal_functions_cli.c if test "$PHP_SAPI" = "apache2handler"; then if test "$APACHE_VERSION" -ge 2004001; then From 96d572a18e0ae9954bcf01cef0aa0edbca6ff566 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 20:06:16 +0200 Subject: [PATCH 125/280] Zend: Add helper for "cannot be empty" ValueError --- Zend/zend_API.c | 5 +++++ Zend/zend_API.h | 1 + 2 files changed, 6 insertions(+) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 229af38c2a8c4..9b98e5b6bebed 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -439,6 +439,11 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * } /* }}} */ +ZEND_API ZEND_COLD void zend_argument_cannot_be_empty_error(uint32_t arg_num) +{ + zend_argument_value_error(arg_num, "cannot be empty"); +} + ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce) { if (old_ce->type == ZEND_INTERNAL_CLASS) { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ab67dd5717e69..ad9fb83403857 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1564,6 +1564,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); +ZEND_API ZEND_COLD void zend_argument_cannot_be_empty_error(uint32_t arg_num); ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce); ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce); From e7c4d54d65e39e468c5cc916e870f8fd09baf482 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 20:09:08 +0200 Subject: [PATCH 126/280] Use new helper function for "cannot be empty" ValueErrors --- ext/bz2/bz2.c | 2 +- ext/dba/dba.c | 8 ++--- ext/dom/domimplementation.c | 2 +- ext/dom/element.c | 4 +-- ext/enchant/enchant.c | 2 +- ext/exif/exif.c | 4 +-- ext/fileinfo/fileinfo.c | 2 +- ext/gd/gd.c | 2 +- ext/gettext/gettext.c | 6 ++-- ext/hash/hash.c | 2 +- ext/intl/idn/idn.c | 2 +- .../resourcebundle/resourcebundle_class.c | 2 +- ext/ldap/ldap.c | 2 +- ext/mysqli/mysqli_api.c | 2 +- ext/mysqli/mysqli_nonapi.c | 8 ++--- ext/openssl/openssl.c | 8 ++--- ext/pcntl/pcntl.c | 2 +- ext/pdo/pdo_dbh.c | 6 ++-- ext/pdo/pdo_stmt.c | 4 +-- ext/pdo_pgsql/pgsql_driver.c | 2 +- ext/pdo_sqlite/pdo_sqlite.c | 2 +- ext/pgsql/pgsql.c | 16 +++++----- ext/posix/posix.c | 4 +-- ext/random/randomizer.c | 2 +- ext/simplexml/simplexml.c | 4 +-- ext/soap/soap.c | 6 ++-- ext/spl/spl_directory.c | 2 +- ext/sqlite3/sqlite3.c | 2 +- ext/standard/array.c | 2 +- ext/standard/basic_functions.c | 2 +- ext/standard/dir.c | 2 +- ext/standard/dns.c | 2 +- ext/standard/dns_win32.c | 2 +- ext/standard/exec.c | 4 +-- ext/standard/ftok.c | 2 +- ext/standard/head.c | 2 +- ext/standard/string.c | 10 +++---- ext/xmlreader/php_xmlreader.c | 20 ++++++------- ext/xmlwriter/php_xmlwriter.c | 4 +-- ext/zip/php_zip.c | 30 +++++++++---------- 40 files changed, 96 insertions(+), 96 deletions(-) diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index 0e777851a5f74..cc7605ab066f5 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -349,7 +349,7 @@ PHP_FUNCTION(bzopen) /* If it's not a resource its a string containing the filename to open */ if (Z_TYPE_P(file) == IS_STRING) { if (Z_STRLEN_P(file) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 6f4f78de7a61e..7637b24f8d6d9 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -547,15 +547,15 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) } if (ZSTR_LEN(path) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(mode) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } if (handler_str && ZSTR_LEN(handler_str) == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_cannot_be_empty_error(3); RETURN_THROWS(); } // TODO Check Value for permission @@ -640,7 +640,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) // bool is_file_lock = false; if (ZSTR_LEN(mode) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); efree(resource_key); RETURN_THROWS(); } diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index 7997dcfed1203..d505e5326b3bc 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -64,7 +64,7 @@ PHP_METHOD(DOMImplementation, createDocumentType) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/element.c b/ext/dom/element.c index a1529a0d3bb9b..1542c23149a9f 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -411,7 +411,7 @@ PHP_METHOD(DOMElement, setAttribute) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -903,7 +903,7 @@ PHP_METHOD(DOMElement, getAttributeNS) static void dom_set_attribute_ns_legacy(dom_object *intern, xmlNodePtr elemp, char *uri, size_t uri_len, char *name, size_t name_len, const char *value) { if (name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); return; } diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 2c264a23039f8..faf18b842ed3a 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -447,7 +447,7 @@ PHP_FUNCTION(enchant_broker_request_dict) PHP_ENCHANT_GET_BROKER; if (taglen == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 7e9df52af5b0e..44a193e7c0b6e 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -4550,7 +4550,7 @@ PHP_FUNCTION(exif_read_data) } if (!Z_STRLEN_P(stream)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -4727,7 +4727,7 @@ PHP_FUNCTION(exif_thumbnail) } if (!Z_STRLEN_P(stream)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 8680722ae9541..0d802925d892e 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -374,7 +374,7 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime php_stream_statbuf ssb; if (buffer == NULL || buffer_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); goto clean; } if (CHECK_NULL_PATH(buffer, buffer_len)) { diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 5af2d4a5152bb..b03c4700add37 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -646,7 +646,7 @@ PHP_FUNCTION(imagesetstyle) num_styles = zend_hash_num_elements(Z_ARRVAL_P(styles)); if (num_styles == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 939619bfb3bbc..96ee53144ace5 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -55,7 +55,7 @@ ZEND_GET_MODULE(php_gettext) zend_argument_value_error(_arg_num, "is too long"); \ RETURN_THROWS(); \ } else if (domain_len == 0) { \ - zend_argument_value_error(_arg_num, "cannot be empty"); \ + zend_argument_cannot_be_empty_error(_arg_num); \ RETURN_THROWS(); \ } @@ -191,7 +191,7 @@ PHP_FUNCTION(bindtextdomain) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) if (!ZSTR_LEN(domain)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -313,7 +313,7 @@ PHP_FUNCTION(bind_textdomain_codeset) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) if (!ZSTR_LEN(domain)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 8a1214b3274f7..d4953aa7ec6ef 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -914,7 +914,7 @@ PHP_FUNCTION(hash_hkdf) } if (ZSTR_LEN(ikm) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c index db8765837c193..3fb7ee5cba12a 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.c @@ -125,7 +125,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(domain) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(domain) > INT32_MAX - 1) { diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index 92475b0ed08d3..2d344e054e838 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -186,7 +186,7 @@ static zval *resource_bundle_array_fetch( if (offset_str) { if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) { if (offset_arg_num) { - zend_argument_value_error(offset_arg_num, "cannot be empty"); + zend_argument_cannot_be_empty_error(offset_arg_num); } else { zend_value_error("Offset cannot be empty"); } diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index e15635ffe628e..f1a37dd4dd8eb 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1501,7 +1501,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) nlinks = zend_hash_num_elements(Z_ARRVAL_P(link)); if (nlinks == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); ret = 0; goto cleanup; } diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index b71888f630a14..09fe384938bc2 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -139,7 +139,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if (!types_len) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 425f543d630c0..b6390db653a58 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -572,7 +572,7 @@ PHP_FUNCTION(mysqli_query) } if (!query_len) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && @@ -1013,7 +1013,7 @@ PHP_FUNCTION(mysqli_begin_transaction) RETURN_THROWS(); } if (name && !name_len) { - zend_argument_value_error(ERROR_ARG_POS(3), "cannot be empty"); + zend_argument_cannot_be_empty_error(ERROR_ARG_POS(3)); RETURN_THROWS(); } @@ -1037,7 +1037,7 @@ PHP_FUNCTION(mysqli_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } @@ -1061,7 +1061,7 @@ PHP_FUNCTION(mysqli_release_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if (FAIL == mysqlnd_release_savepoint(mysql->mysql, name)) { diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 4c16279d81856..7be102d1fb21a 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -7243,7 +7243,7 @@ PHP_FUNCTION(openssl_seal) pubkeysht = Z_ARRVAL_P(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { - zend_argument_value_error(4, "cannot be empty"); + zend_argument_cannot_be_empty_error(4); RETURN_THROWS(); } @@ -8017,7 +8017,7 @@ PHP_FUNCTION(openssl_decrypt) } if (!method_len) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -8059,7 +8059,7 @@ PHP_FUNCTION(openssl_cipher_iv_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -8088,7 +8088,7 @@ PHP_FUNCTION(openssl_cipher_key_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index cf66057fc8f69..81c076bc282a4 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -860,7 +860,7 @@ static bool php_pcntl_set_user_signal_infos( bool allow_empty_signal_array ) { if (!allow_empty_signal_array && zend_hash_num_elements(user_signals) == 0) { - zend_argument_value_error(arg_num, "cannot be empty"); + zend_argument_cannot_be_empty_error(arg_num); return false; } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index c67b0eb24e5b4..0be81c463d435 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -563,7 +563,7 @@ PHP_METHOD(PDO, prepare) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1030,7 +1030,7 @@ PHP_METHOD(PDO, exec) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1166,7 +1166,7 @@ PHP_METHOD(PDO, query) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 4674e901da5a5..751781e76ebc6 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1423,7 +1423,7 @@ static void register_bound_param(INTERNAL_FUNCTION_PARAMETERS, int is_param) /* if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; @@ -1471,7 +1471,7 @@ PHP_METHOD(PDOStatement, bindValue) if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index c418e6f5ba986..fbc30a3c09a63 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -627,7 +627,7 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS) } if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index e2c686ed691ff..4b0dc8f99e233 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -82,7 +82,7 @@ PHP_METHOD(Pdo_Sqlite, loadExtension) } if (extension_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index f74667b214fdd..4d3c548025dad 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4613,7 +4613,7 @@ PHP_FUNCTION(pg_meta_data) /* php_pgsql_meta_data() asserts that table_name is not empty */ if (ZSTR_LEN(table_name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -5405,7 +5405,7 @@ PHP_FUNCTION(pg_convert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table_name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -5618,7 +5618,7 @@ PHP_FUNCTION(pg_insert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -5840,7 +5840,7 @@ PHP_FUNCTION(pg_update) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -5939,7 +5939,7 @@ PHP_FUNCTION(pg_delete) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -6095,7 +6095,7 @@ PHP_FUNCTION(pg_select) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -6143,13 +6143,13 @@ PHP_FUNCTION(pg_change_password) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(user) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } /* it is technically possible, but better to disallow it */ if (ZSTR_LEN(passwd) == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_cannot_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 6711492e3d2a5..bea433cd5f297 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -746,7 +746,7 @@ PHP_FUNCTION(posix_eaccess) path = expand_filepath(filename, NULL); if (!path) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1285,7 +1285,7 @@ PHP_FUNCTION(posix_pathconf) ZEND_PARSE_PARAMETERS_END(); if (path_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } else if (php_check_open_basedir(path)) { php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path); diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 1109b497c131d..3768e1b7e16ff 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -434,7 +434,7 @@ PHP_METHOD(Random_Randomizer, getBytesFromString) const size_t max_offset = source_length - 1; if (source_length < 1) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 8a12d430d476f..74350167a5220 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1667,7 +1667,7 @@ PHP_METHOD(SimpleXMLElement, addChild) } if (qname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1734,7 +1734,7 @@ PHP_METHOD(SimpleXMLElement, addAttribute) } if (qname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index b152a1a187af0..fc7e5eb185305 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -571,7 +571,7 @@ PHP_METHOD(SoapParam, __construct) } if (ZSTR_LEN(name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -602,11 +602,11 @@ PHP_METHOD(SoapHeader, __construct) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(ns) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 989f84f1fdd1c..c59ec7f84a4b0 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -696,7 +696,7 @@ static void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_l } if (ZSTR_LEN(path) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 4ef8cb3101ae4..6aea72a6fa761 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -421,7 +421,7 @@ PHP_METHOD(SQLite3, loadExtension) } if (extension_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/array.c b/ext/standard/array.c index 068057e70a9ec..b38b5fe6a6a61 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6211,7 +6211,7 @@ PHPAPI bool php_array_pick_keys(php_random_algo_with_state engine, zval *input, if (num_avail == 0) { if (!silent) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); } return false; } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 7b3494303ca41..a6226ae6cd98d 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2500,7 +2500,7 @@ PHP_FUNCTION(parse_ini_file) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dir.c b/ext/standard/dir.c index edb62c368fcfa..bf0c566678111 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -467,7 +467,7 @@ PHP_FUNCTION(scandir) ZEND_PARSE_PARAMETERS_END(); if (dirn_len < 1) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 41e90e3e924bd..3f9b20cfe5424 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -388,7 +388,7 @@ PHP_FUNCTION(dns_check_record) ZEND_PARSE_PARAMETERS_END(); if (hostname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 2aeedb133e018..5bc41880de54c 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -108,7 +108,7 @@ PHP_FUNCTION(dns_check_record) } if (hostname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 5b3ba60e5fdea..7b1d2c8c8f990 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -218,7 +218,7 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ ZEND_PARSE_PARAMETERS_END(); if (!cmd_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (strlen(cmd) != cmd_len) { @@ -518,7 +518,7 @@ PHP_FUNCTION(shell_exec) ZEND_PARSE_PARAMETERS_END(); if (!command_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (strlen(command) != command_len) { diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 1a046b3de6979..338fb00ee5145 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -40,7 +40,7 @@ PHP_FUNCTION(ftok) ZEND_PARSE_PARAMETERS_END(); if (pathname_len == 0){ - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/head.c b/ext/standard/head.c index 0acd34c83c4e9..ad02faf025577 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -87,7 +87,7 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e smart_str buf = {0}; if (!ZSTR_LEN(name)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); return FAILURE; } if (strpbrk(ZSTR_VAL(name), "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 23c34df958b51..66efa04862b50 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -724,7 +724,7 @@ PHP_FUNCTION(wordwrap) } if (breakchar_len == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_cannot_be_empty_error(3); RETURN_THROWS(); } @@ -930,7 +930,7 @@ PHP_FUNCTION(explode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(delim) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1277,7 +1277,7 @@ PHP_FUNCTION(str_increment) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -1333,7 +1333,7 @@ PHP_FUNCTION(str_decrement) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -5727,7 +5727,7 @@ PHP_FUNCTION(substr_count) ZEND_PARSE_PARAMETERS_END(); if (needle_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index b5a4badd1381a..178053f8f6091 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -382,7 +382,7 @@ static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_rea } if (!name_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -467,7 +467,7 @@ static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int t } if (source != NULL && !source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -574,12 +574,12 @@ PHP_METHOD(XMLReader, getAttributeNs) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -655,7 +655,7 @@ PHP_METHOD(XMLReader, moveToAttribute) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -715,12 +715,12 @@ PHP_METHOD(XMLReader, moveToAttributeNs) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -860,7 +860,7 @@ static void xml_reader_from_uri(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry * } if (!source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1027,7 +1027,7 @@ PHP_METHOD(XMLReader, setSchema) } if (source != NULL && !source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1132,7 +1132,7 @@ static void xml_reader_from_string(INTERNAL_FUNCTION_PARAMETERS, zend_class_entr } if (!source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 6724f4fbfbffb..0e7f3d29153c3 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -817,7 +817,7 @@ PHP_FUNCTION(xmlwriter_open_uri) } if (source_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -858,7 +858,7 @@ PHP_METHOD(XMLWriter, toUri) ZEND_PARSE_PARAMETERS_END(); if (source_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 342d6aabe7240..be3c6d4c58189 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -56,7 +56,7 @@ static int le_zip_entry; This is always used for the first argument*/ #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \ if (path_len == 0) { \ - zend_argument_value_error(1, "cannot be empty"); \ + zend_argument_cannot_be_empty_error(1); \ RETURN_THROWS(); \ } \ if (zip_stat(za, path, flags, &sb) != 0) { \ @@ -1184,7 +1184,7 @@ PHP_FUNCTION(zip_open) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1466,7 +1466,7 @@ PHP_METHOD(ZipArchive, open) ze_obj = Z_ZIP_P(self); if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1753,7 +1753,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* } if (ZSTR_LEN(pattern) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (options && zend_hash_num_elements(options) > 0 && (php_zip_parse_options(options, &opts) < 0)) { @@ -1871,7 +1871,7 @@ PHP_METHOD(ZipArchive, addFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1904,7 +1904,7 @@ PHP_METHOD(ZipArchive, replaceFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2168,7 +2168,7 @@ PHP_METHOD(ZipArchive, setCommentName) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2235,7 +2235,7 @@ PHP_METHOD(ZipArchive, setExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2296,7 +2296,7 @@ PHP_METHOD(ZipArchive, getExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2363,7 +2363,7 @@ PHP_METHOD(ZipArchive, setEncryptionName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2424,7 +2424,7 @@ PHP_METHOD(ZipArchive, getCommentName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2480,7 +2480,7 @@ PHP_METHOD(ZipArchive, setCompressionName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2540,7 +2540,7 @@ PHP_METHOD(ZipArchive, setMtimeName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2654,7 +2654,7 @@ PHP_METHOD(ZipArchive, renameIndex) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -2682,7 +2682,7 @@ PHP_METHOD(ZipArchive, renameName) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } From 10738141d79f0585485a181924492a393d33ed4d Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 20:15:37 +0200 Subject: [PATCH 127/280] ext/standard/exec.c: Use ZPP path modifier to check for nul bytes --- ext/standard/exec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 7b1d2c8c8f990..d4a1af465dfe8 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -514,17 +514,13 @@ PHP_FUNCTION(shell_exec) php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(command, command_len) + Z_PARAM_PATH(command, command_len) ZEND_PARSE_PARAMETERS_END(); if (!command_len) { zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } - if (strlen(command) != command_len) { - zend_argument_value_error(1, "must not contain any null bytes"); - RETURN_THROWS(); - } #ifdef PHP_WIN32 if ((in=VCWD_POPEN(command, "rt"))==NULL) { From f6c464fee56f34080e89c9c0ffd0eb20b501c5d2 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 20:10:12 +0200 Subject: [PATCH 128/280] ext/gettext: Remove duplicate domain length checks It not being empty is already checked by PHP_GETTEXT_DOMAIN_LENGTH_CHECK() --- ext/gettext/gettext.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 96ee53144ace5..ee94fcb26ed74 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -190,11 +190,6 @@ PHP_FUNCTION(bindtextdomain) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) - if (!ZSTR_LEN(domain)) { - zend_argument_cannot_be_empty_error(1); - RETURN_THROWS(); - } - if (dir == NULL) { RETURN_STRING(bindtextdomain(ZSTR_VAL(domain), NULL)); } @@ -312,11 +307,6 @@ PHP_FUNCTION(bind_textdomain_codeset) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) - if (!ZSTR_LEN(domain)) { - zend_argument_cannot_be_empty_error(1); - RETURN_THROWS(); - } - retval = bind_textdomain_codeset(ZSTR_VAL(domain), codeset ? ZSTR_VAL(codeset) : NULL); if (!retval) { From ad8480304da9d5951c080035134d22bde447baac Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 20:26:16 +0200 Subject: [PATCH 129/280] ext/dba: Remove duplicate check for empty mode --- ext/dba/dba.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 7637b24f8d6d9..3c6d07b56c0a3 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -639,11 +639,6 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) bool is_lock_ignored = false; // bool is_file_lock = false; - if (ZSTR_LEN(mode) == 0) { - zend_argument_cannot_be_empty_error(2); - efree(resource_key); - RETURN_THROWS(); - } if (ZSTR_LEN(mode) > 3) { zend_argument_value_error(2, "must be at most 3 characters"); efree(resource_key); From 6d9a74cde0e463e37a4a3906e50db78973f5bf66 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 23:22:22 +0200 Subject: [PATCH 130/280] ext/dom: Use standard wording for ValueError --- ext/dom/document.c | 12 ++++++------ ext/dom/html_document.c | 2 +- ext/dom/tests/DOMDocument_loadHTML_error2.phpt | 2 +- ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt | 2 +- ext/dom/tests/DOMDocument_loadXML_error6.phpt | 2 +- ext/dom/tests/DOMDocument_load_error6.phpt | 2 +- .../DOMDocument_saveHTMLFile_invalid_filename.phpt | 2 +- .../DOMDocument_schemaValidateSource_error3.phpt | 2 +- ext/dom/tests/DOMDocument_schemaValidate_error3.phpt | 2 +- .../HTMLDocument_saveHTMLFile_empty_path.phpt | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index 6e64fe497b025..9b48cd96b65d1 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1525,7 +1525,7 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } if (ZEND_SIZE_T_INT_OVFL(source_len)) { @@ -1579,7 +1579,7 @@ PHP_METHOD(DOMDocument, save) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1883,7 +1883,7 @@ static void dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1992,7 +1992,7 @@ static void dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2085,7 +2085,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -2162,7 +2162,7 @@ PHP_METHOD(DOMDocument, saveHTMLFile) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 44da720b66479..542a5cccab2ce 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -1283,7 +1283,7 @@ PHP_METHOD(Dom_HTMLDocument, saveHtmlFile) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt index 6886240e595bf..1e0eb43247d9b 100644 --- a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt +++ b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt @@ -14,4 +14,4 @@ try { } ?> --EXPECT-- -DOMDocument::loadHTML(): Argument #1 ($source) must not be empty +DOMDocument::loadHTML(): Argument #1 ($source) cannot be empty diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt index a5ef58a65656b..87b3dc9804634 100644 --- a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt +++ b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt @@ -23,5 +23,5 @@ try { } ?> --EXPECT-- -DOMDocument::loadHTMLFile(): Argument #1 ($filename) must not be empty +DOMDocument::loadHTMLFile(): Argument #1 ($filename) cannot be empty DOMDocument::loadHTMLFile(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/dom/tests/DOMDocument_loadXML_error6.phpt b/ext/dom/tests/DOMDocument_loadXML_error6.phpt index 748a8eb5dc1d5..bd552ae719eae 100644 --- a/ext/dom/tests/DOMDocument_loadXML_error6.phpt +++ b/ext/dom/tests/DOMDocument_loadXML_error6.phpt @@ -13,4 +13,4 @@ try { } ?> --EXPECT-- -DOMDocument::loadXML(): Argument #1 ($source) must not be empty +DOMDocument::loadXML(): Argument #1 ($source) cannot be empty diff --git a/ext/dom/tests/DOMDocument_load_error6.phpt b/ext/dom/tests/DOMDocument_load_error6.phpt index a4f9bc4a02a87..96fe5bb5c322a 100644 --- a/ext/dom/tests/DOMDocument_load_error6.phpt +++ b/ext/dom/tests/DOMDocument_load_error6.phpt @@ -22,6 +22,6 @@ try { var_dump($dom->load(str_repeat(" ", PHP_MAXPATHLEN + 1))); ?> --EXPECT-- -DOMDocument::load(): Argument #1 ($filename) must not be empty +DOMDocument::load(): Argument #1 ($filename) cannot be empty DOMDocument::load(): Argument #1 ($filename) must not contain any null bytes bool(false) diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt index 8dc89f2530124..3db1c37a492a9 100644 --- a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt @@ -24,4 +24,4 @@ try { } ?> --EXPECT-- -DOMDocument::saveHTMLFile(): Argument #1 ($filename) must not be empty +DOMDocument::saveHTMLFile(): Argument #1 ($filename) cannot be empty diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt index ec295a55e3391..88c8123a28da7 100644 --- a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt @@ -20,4 +20,4 @@ try { ?> --EXPECT-- -DOMDocument::schemaValidateSource(): Argument #1 ($source) must not be empty +DOMDocument::schemaValidateSource(): Argument #1 ($source) cannot be empty diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt index 274463e62e139..ac70535c5c321 100644 --- a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt +++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt @@ -20,4 +20,4 @@ try { ?> --EXPECT-- -DOMDocument::schemaValidate(): Argument #1 ($filename) must not be empty +DOMDocument::schemaValidate(): Argument #1 ($filename) cannot be empty diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt index 93daf65f72f22..35b6165a18538 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt @@ -11,7 +11,7 @@ $dom->saveHtmlFile(""); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: Dom\HTMLDocument::saveHtmlFile(): Argument #1 ($filename) must not be empty in %s:%d +Fatal error: Uncaught ValueError: Dom\HTMLDocument::saveHtmlFile(): Argument #1 ($filename) cannot be empty in %s:%d Stack trace: #0 %s(%d): Dom\HTMLDocument->saveHtmlFile('') #1 {main} From 997199e9387b1a8f2ab0af03966abc5cb74a0193 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 23:25:35 +0200 Subject: [PATCH 131/280] ext/standard/string.c: use standard wording for ValueError in str_pad() --- ext/standard/string.c | 2 +- ext/standard/tests/strings/str_pad.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index 66efa04862b50..6a15b3db71901 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -5802,7 +5802,7 @@ PHP_FUNCTION(str_pad) } if (pad_str_len == 0) { - zend_argument_value_error(3, "must be a non-empty string"); + zend_argument_cannot_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/standard/tests/strings/str_pad.phpt b/ext/standard/tests/strings/str_pad.phpt index 278db455f8d55..c28bb1217a6e4 100644 --- a/ext/standard/tests/strings/str_pad.phpt +++ b/ext/standard/tests/strings/str_pad.phpt @@ -302,5 +302,5 @@ string(16) "\t\variation\t\t" #### error conditions #### --- empty padding string --- -str_pad(): Argument #3 ($pad_string) must be a non-empty string +str_pad(): Argument #3 ($pad_string) cannot be empty str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH From 9a2fdbec48b7d1de060b520e038f37f0d50b4400 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 23:32:07 +0200 Subject: [PATCH 132/280] ext/mbstring: Use standard wording for ValueError --- ext/mbstring/mbstring.c | 8 ++++---- ext/mbstring/php_mbregex.c | 4 ++-- ext/mbstring/tests/bug43994.phpt | 16 ++++++++-------- ext/mbstring/tests/empty_pattern.phpt | 2 +- ext/mbstring/tests/mb_ereg1.phpt | 2 +- ext/mbstring/tests/mb_ord.phpt | 2 +- ext/mbstring/tests/mb_str_pad.phpt | 22 +++++++++++----------- ext/mbstring/tests/mb_substr_count.phpt | 6 +++--- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index a9670684cbda0..6c5ac38021c6b 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2238,7 +2238,7 @@ PHP_FUNCTION(mb_substr_count) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(needle) == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } @@ -2278,7 +2278,7 @@ PHP_FUNCTION(mb_substr_count) if (ZSTR_LEN(needle_u8) == 0) { zend_string_free(haystack_u8); zend_string_free(needle_u8); - zend_argument_value_error(2, "must not be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } } @@ -5673,7 +5673,7 @@ PHP_FUNCTION(mb_ord) ZEND_PARSE_PARAMETERS_END(); if (str_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -5810,7 +5810,7 @@ PHP_FUNCTION(mb_str_pad) } if (ZSTR_LEN(pad) == 0) { - zend_argument_value_error(3, "must be a non-empty string"); + zend_argument_cannot_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index c947b5e6f049c..c3dab804a5a75 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -900,7 +900,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) } if (arg_pattern_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_cannot_be_empty_error(1); RETURN_THROWS(); } @@ -1468,7 +1468,7 @@ PHP_FUNCTION(mb_ereg_search_init) } if (arg_pattern && arg_pattern_len == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/mbstring/tests/bug43994.phpt b/ext/mbstring/tests/bug43994.phpt index 26f641f6d3d7e..16ed4744e0217 100644 --- a/ext/mbstring/tests/bug43994.phpt +++ b/ext/mbstring/tests/bug43994.phpt @@ -43,28 +43,28 @@ foreach($inputs as $input) { --EXPECT-- -- Iteration 1 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty NULL -- Iteration 2 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty NULL -- Iteration 3 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty NULL -- Iteration 4 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) must not be empty +mb_ereg(): Argument #1 ($pattern) cannot be empty NULL diff --git a/ext/mbstring/tests/empty_pattern.phpt b/ext/mbstring/tests/empty_pattern.phpt index 64e63147ee789..75635395d7051 100644 --- a/ext/mbstring/tests/empty_pattern.phpt +++ b/ext/mbstring/tests/empty_pattern.phpt @@ -25,5 +25,5 @@ try { ?> --EXPECT-- -mb_ereg_search_init(): Argument #2 ($pattern) must not be empty +mb_ereg_search_init(): Argument #2 ($pattern) cannot be empty No pattern was provided diff --git a/ext/mbstring/tests/mb_ereg1.phpt b/ext/mbstring/tests/mb_ereg1.phpt index 813fe5e41ef0d..3cc09a8c2f49d 100644 --- a/ext/mbstring/tests/mb_ereg1.phpt +++ b/ext/mbstring/tests/mb_ereg1.phpt @@ -35,7 +35,7 @@ array(3) { array(0) { } } -ValueError: mb_ereg(): Argument #1 ($pattern) must not be empty +ValueError: mb_ereg(): Argument #1 ($pattern) cannot be empty array(3) { [0]=> string(0) "" diff --git a/ext/mbstring/tests/mb_ord.phpt b/ext/mbstring/tests/mb_ord.phpt index a42cb9497fabd..7f313300f8152 100644 --- a/ext/mbstring/tests/mb_ord.phpt +++ b/ext/mbstring/tests/mb_ord.phpt @@ -56,7 +56,7 @@ try { bool(true) bool(true) bool(true) -mb_ord(): Argument #1 ($string) must not be empty +mb_ord(): Argument #1 ($string) cannot be empty mb_ord(): Argument #2 ($encoding) must be a valid encoding, "typo" given mb_ord(): Argument #2 ($encoding) must be a valid encoding, "pass" given mb_ord() does not support the "JIS" encoding diff --git a/ext/mbstring/tests/mb_str_pad.phpt b/ext/mbstring/tests/mb_str_pad.phpt index 24f5d45e37d06..edee4dc917952 100644 --- a/ext/mbstring/tests/mb_str_pad.phpt +++ b/ext/mbstring/tests/mb_str_pad.phpt @@ -9,27 +9,27 @@ echo "--- Error conditions ---\n"; try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_RIGHT)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_LEFT)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_BOTH)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, ' ', 123456)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { - var_dump(mb_str_pad('▶▶', 6, ' ', STR_PAD_BOTH, 'unexisting')); + var_dump(mb_str_pad('▶▶', 6, ' ', STR_PAD_BOTH, 'non-existing')); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } echo "--- Simple ASCII strings ---\n"; @@ -87,11 +87,11 @@ foreach ($tests as $encoding => $test) { ?> --EXPECT-- --- Error conditions --- -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(90) "mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH" -string(82) "mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "unexisting" given" +ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty +ValueError: mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH +ValueError: mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "non-existing" given --- Simple ASCII strings --- string(7) "+Hello+" string(10) "+-World+-+" diff --git a/ext/mbstring/tests/mb_substr_count.phpt b/ext/mbstring/tests/mb_substr_count.phpt index 2927419930b39..1047284303b58 100644 --- a/ext/mbstring/tests/mb_substr_count.phpt +++ b/ext/mbstring/tests/mb_substr_count.phpt @@ -69,9 +69,9 @@ output_handler= ?> --EXPECT-- == Empty needle should raise an error == -mb_substr_count(): Argument #2 ($needle) must not be empty -mb_substr_count(): Argument #2 ($needle) must not be empty -mb_substr_count(): Argument #2 ($needle) must not be empty +mb_substr_count(): Argument #2 ($needle) cannot be empty +mb_substr_count(): Argument #2 ($needle) cannot be empty +mb_substr_count(): Argument #2 ($needle) cannot be empty == Return value for empty haystack should always be zero == int(0) int(0) From c811d5895317885f8dff6cb275d7d87da48f8a87 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 18 Aug 2024 23:35:40 +0200 Subject: [PATCH 133/280] ext/pcntl: Use standard wording for ValueError --- ext/pcntl/pcntl.c | 3 ++- ext/pcntl/tests/pcntl_cpuaffinity.phpt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 81c076bc282a4..445734a5877a1 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1693,8 +1693,9 @@ PHP_FUNCTION(pcntl_setcpuaffinity) Z_PARAM_ARRAY(hmask) ZEND_PARSE_PARAMETERS_END(); + // TODO Why are the arguments optional? if (!hmask || zend_hash_num_elements(Z_ARRVAL_P(hmask)) == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_cannot_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pcntl/tests/pcntl_cpuaffinity.phpt b/ext/pcntl/tests/pcntl_cpuaffinity.phpt index caeb27d2759cc..9ec9703b3c48b 100644 --- a/ext/pcntl/tests/pcntl_cpuaffinity.phpt +++ b/ext/pcntl/tests/pcntl_cpuaffinity.phpt @@ -60,7 +60,7 @@ array(0) { array(0) { } bool(true) -pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) must not be empty +pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cannot be empty pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id invalid value (def) pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id must be between 0 and %d (%d) pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id must be between 0 and %d (-1024) From 5853cdb73db85c75d5f558a8cf92161a31291de0 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Tue, 20 Aug 2024 13:45:39 +0200 Subject: [PATCH 134/280] Use "must not" instead of "cannot" wording --- .../property_hooks/invalid_empty_hooks.phpt | 4 +-- Zend/zend_API.c | 4 +-- Zend/zend_API.h | 2 +- Zend/zend_compile.c | 2 +- ext/bz2/bz2.c | 2 +- ext/bz2/tests/001.phpt | 4 +-- ext/dba/dba.c | 6 ++-- ext/dba/tests/value_errors_open.phpt | 12 +++---- ext/dom/document.c | 12 +++---- ext/dom/domimplementation.c | 2 +- ext/dom/element.c | 4 +-- ext/dom/html_document.c | 2 +- .../tests/DOMDocument_loadHTML_error2.phpt | 2 +- .../DOMDocument_loadHTMLfile_error2.phpt | 2 +- ext/dom/tests/DOMDocument_loadXML_error6.phpt | 2 +- ext/dom/tests/DOMDocument_load_error6.phpt | 2 +- ...ocument_saveHTMLFile_invalid_filename.phpt | 2 +- ...MDocument_schemaValidateSource_error3.phpt | 2 +- .../DOMDocument_schemaValidate_error3.phpt | 2 +- .../HTMLDocument_saveHTMLFile_empty_path.phpt | 2 +- .../HTMLDocument_fromFile_empty_path.phpt | 2 +- ext/enchant/enchant.c | 2 +- ...roker_request_dict_error_on_empty_tag.phpt | 2 +- ext/exif/exif.c | 4 +-- ext/exif/tests/filename_empty.phpt | 4 +-- ext/fileinfo/fileinfo.c | 2 +- ext/fileinfo/tests/finfo_file_001.phpt | 2 +- ext/fileinfo/tests/mime_content_type_001.phpt | 2 +- ext/filter/logical_filters.c | 2 +- ext/filter/tests/bug51368.phpt | 2 +- ext/gd/gd.c | 2 +- ext/gd/tests/bug72709.phpt | 2 +- ext/gettext/gettext.c | 2 +- ext/gettext/tests/dcngettext.phpt | 4 +-- ...ettext_bind_textdomain_codeset-retval.phpt | 4 +-- .../gettext_bindtextdomain-emptydomain.phpt | 2 +- .../tests/gettext_textdomain-retval.phpt | 2 +- ext/hash/hash.c | 4 +-- ext/hash/tests/hash_hkdf_error.phpt | 2 +- ext/hash/tests/hash_init_error.phpt | 4 +-- ext/intl/idn/idn.c | 2 +- .../resourcebundle/resourcebundle_class.c | 4 +-- ext/intl/tests/idn_uts46_errors.phpt | 2 +- .../resourcebundle_dimension_errors.phpt | 2 +- ext/ldap/ldap.c | 4 +-- ext/ldap/tests/ldap_search_error.phpt | 2 +- ext/mbstring/mbstring.c | 8 ++--- ext/mbstring/php_mbregex.c | 4 +-- ext/mbstring/tests/bug43994.phpt | 16 ++++----- ext/mbstring/tests/empty_pattern.phpt | 2 +- ext/mbstring/tests/mb_ereg1.phpt | 2 +- ext/mbstring/tests/mb_ord.phpt | 2 +- ext/mbstring/tests/mb_str_pad.phpt | 6 ++-- ext/mbstring/tests/mb_substr_count.phpt | 6 ++-- ext/mysqli/mysqli_api.c | 2 +- ext/mysqli/mysqli_nonapi.c | 8 ++--- ext/mysqli/tests/mysqli_query.phpt | 2 +- .../tests/mysqli_release_savepoint.phpt | 2 +- ext/mysqli/tests/mysqli_savepoint.phpt | 2 +- ext/mysqli/tests/mysqli_stmt_bind_param.phpt | 2 +- ext/openssl/openssl.c | 8 ++--- .../tests/openssl_cipher_iv_length_error.phpt | 2 +- .../openssl_cipher_key_length_error.phpt | 2 +- ext/openssl/tests/openssl_seal_basic.phpt | 4 +-- ext/pcntl/pcntl.c | 4 +-- ext/pcntl/tests/pcntl_cpuaffinity.phpt | 2 +- ext/pcntl/tests/pcntl_sigprocmask_errors.phpt | 2 +- .../tests/pcntl_sigtimedwait_errors.phpt | 2 +- ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt | 2 +- ext/pdo/pdo_dbh.c | 6 ++-- ext/pdo/pdo_stmt.c | 4 +-- .../tests/pdo_mysql_prepare_emulated.phpt | 2 +- ...epare_emulated_anonymous_placeholders.phpt | 2 +- .../pdo_mysql_prepare_emulated_myisam.phpt | 2 +- ...o_mysql_prepare_emulated_myisam_index.phpt | 2 +- .../tests/pdo_mysql_prepare_native.phpt | 2 +- ..._prepare_native_anonymous_placeholder.phpt | 2 +- .../pdo_mysql_prepare_native_myisam.phpt | 2 +- ...pdo_mysql_prepare_native_myisam_index.phpt | 2 +- ext/pdo_pgsql/pgsql_driver.c | 2 +- ext/pdo_sqlite/pdo_sqlite.c | 2 +- ext/pgsql/pgsql.c | 18 +++++----- ext/pgsql/tests/changepassword.phpt | 4 +-- ext/pgsql/tests/pg_insert_002.phpt | 2 +- ext/phar/tests/create_path_error.phpt | 8 ++--- ext/phar/util.c | 2 +- ext/posix/posix.c | 4 +-- ext/posix/tests/posix_eaccess.phpt | 2 +- ext/posix/tests/posix_pathconf.phpt | 2 +- ext/random/randomizer.c | 2 +- .../methods/getBytesFromString_error.phpt | 2 +- .../methods/pickArrayKeys_error.phpt | 2 +- ext/simplexml/simplexml.c | 4 +-- ..._addAttribute_required_attribute_name.phpt | 2 +- ext/snmp/snmp.c | 2 +- ext/snmp/tests/snmp2_get.phpt | 2 +- ext/soap/soap.c | 6 ++-- ext/soap/tests/bugs/bug31755.phpt | 2 +- ext/sockets/conversions.c | 2 +- ext/spl/spl_directory.c | 4 +-- .../DirectoryIterator_empty_constructor.phpt | 2 +- ext/sqlite3/sqlite3.c | 2 +- .../sqlite3_33_load_extension_param.phpt | 2 +- ext/standard/array.c | 2 +- ext/standard/basic_functions.c | 2 +- ext/standard/dir.c | 2 +- ext/standard/dns.c | 2 +- ext/standard/dns_win32.c | 2 +- ext/standard/exec.c | 4 +-- ext/standard/ftok.c | 2 +- ext/standard/head.c | 2 +- ext/standard/string.c | 12 +++---- ext/standard/tests/array/array_rand.phpt | 4 +-- ext/standard/tests/dir/bug41693.phpt | 2 +- .../file_get_contents_variation8-win32.phpt | 4 +-- .../file/file_get_contents_variation8.phpt | 4 +-- .../file_put_contents_variation8-win32.phpt | 4 +-- .../file/file_put_contents_variation8.phpt | 4 +-- ext/standard/tests/file/readfile_error.phpt | 4 +-- .../file/readfile_variation10-win32.phpt | 4 +-- .../tests/file/readfile_variation10.phpt | 4 +-- ext/standard/tests/network/bug69523.phpt | 2 +- .../dns_check_record_error_conditions.phpt | 2 +- .../tests/network/setcookie_error.phpt | 2 +- .../tests/network/setrawcookie_error.phpt | 2 +- ext/standard/tests/strings/explode.phpt | 8 ++--- ext/standard/tests/strings/explode1.phpt | 24 ++++++------- ext/standard/tests/strings/md5_file.phpt | 2 +- ext/standard/tests/strings/sha1_file.phpt | 4 +-- .../tests/strings/str_decrement_errors.phpt | 2 +- .../strings/str_decrement_underflow.phpt | 2 +- .../tests/strings/str_increment_errors.phpt | 2 +- ext/standard/tests/strings/str_pad.phpt | 2 +- .../tests/strings/substr_count_basic.phpt | 4 +-- ext/standard/tests/strings/wordwrap.phpt | 2 +- ext/sysvshm/tests/001.phpt | 2 +- ext/tidy/tests/019.phpt | 4 +-- ext/xmlreader/php_xmlreader.c | 20 +++++------ ext/xmlreader/tests/001.phpt | 2 +- ext/xmlreader/tests/002.phpt | 2 +- ext/xmlreader/tests/003-get-errors.phpt | 2 +- ext/xmlreader/tests/003-move-errors.phpt | 2 +- ext/xmlreader/tests/003.phpt | 2 +- ext/xmlreader/tests/007.phpt | 2 +- ext/xmlreader/tests/015-get-errors.phpt | 2 +- ext/xmlreader/tests/015-move-errors.phpt | 2 +- ext/xmlreader/tests/setSchema_error.phpt | 2 +- ext/xmlwriter/php_xmlwriter.c | 4 +-- .../tests/xmlwriter_open_uri_error_001.phpt | 2 +- ext/zip/php_zip.c | 34 +++++++++---------- ext/zip/tests/oo_getcomment.phpt | 2 +- .../oo_getexternalattributesname_error.phpt | 2 +- ext/zip/tests/oo_open.phpt | 2 +- ext/zip/tests/zip_open_error.phpt | 2 +- main/streams/streams.c | 2 +- php.ini-development | 2 +- php.ini-production | 2 +- 157 files changed, 281 insertions(+), 281 deletions(-) diff --git a/Zend/tests/property_hooks/invalid_empty_hooks.phpt b/Zend/tests/property_hooks/invalid_empty_hooks.phpt index c549536b4d61e..c380622d06edd 100644 --- a/Zend/tests/property_hooks/invalid_empty_hooks.phpt +++ b/Zend/tests/property_hooks/invalid_empty_hooks.phpt @@ -1,5 +1,5 @@ --TEST-- -Property hook list cannot be empty +Property hook list must not be empty --FILE-- --EXPECTF-- -Fatal error: Property hook list cannot be empty in %s on line %d +Fatal error: Property hook list must not be empty in %s on line %d diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 9b98e5b6bebed..b5ca938865893 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -439,9 +439,9 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * } /* }}} */ -ZEND_API ZEND_COLD void zend_argument_cannot_be_empty_error(uint32_t arg_num) +ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num) { - zend_argument_value_error(arg_num, "cannot be empty"); + zend_argument_value_error(arg_num, "must not be empty"); } ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ad9fb83403857..cbb9ec163f3c4 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1564,7 +1564,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); -ZEND_API ZEND_COLD void zend_argument_cannot_be_empty_error(uint32_t arg_num); +ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num); ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce); ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 06a55ff761d6a..003e2bd83122e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8390,7 +8390,7 @@ static void zend_compile_property_hooks( } if (hooks->children == 0) { - zend_error_noreturn(E_COMPILE_ERROR, "Property hook list cannot be empty"); + zend_error_noreturn(E_COMPILE_ERROR, "Property hook list must not be empty"); } for (uint32_t i = 0; i < hooks->children; i++) { diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index cc7605ab066f5..86de6a5ca5f2d 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -349,7 +349,7 @@ PHP_FUNCTION(bzopen) /* If it's not a resource its a string containing the filename to open */ if (Z_TYPE_P(file) == IS_STRING) { if (Z_STRLEN_P(file) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/bz2/tests/001.phpt b/ext/bz2/tests/001.phpt index 6b86bd6b0b6db..767a50a27d8bf 100644 --- a/ext/bz2/tests/001.phpt +++ b/ext/bz2/tests/001.phpt @@ -42,8 +42,8 @@ var_dump(bzopen($fp, "r")); ?> --EXPECTF-- -bzopen(): Argument #1 ($file) cannot be empty -bzopen(): Argument #1 ($file) cannot be empty +bzopen(): Argument #1 ($file) must not be empty +bzopen(): Argument #1 ($file) must not be empty bzopen(): Argument #2 ($mode) must be either "r" or "w" bzopen(): Argument #2 ($mode) must be either "r" or "w" bzopen(): Argument #2 ($mode) must be either "r" or "w" diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 3c6d07b56c0a3..c0baf2780dcb7 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -547,15 +547,15 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) } if (ZSTR_LEN(path) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(mode) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } if (handler_str && ZSTR_LEN(handler_str) == 0) { - zend_argument_cannot_be_empty_error(3); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } // TODO Check Value for permission diff --git a/ext/dba/tests/value_errors_open.phpt b/ext/dba/tests/value_errors_open.phpt index 9bbb0b00a94d0..ee995fe5b8d66 100644 --- a/ext/dba/tests/value_errors_open.phpt +++ b/ext/dba/tests/value_errors_open.phpt @@ -121,9 +121,9 @@ object(Dba\Connection)#%d (%d) { Warning: dba_open(): Handler "bogus" is not available in %s on line %d bool(false) -dba_open(): Argument #1 ($path) cannot be empty -dba_open(): Argument #2 ($mode) cannot be empty -dba_open(): Argument #3 ($handler) cannot be empty +dba_open(): Argument #1 ($path) must not be empty +dba_open(): Argument #2 ($mode) must not be empty +dba_open(): Argument #3 ($handler) must not be empty dba_open(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n" dba_open(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t" dba_open(): Argument #2 ($mode) third character must be "t" @@ -133,9 +133,9 @@ dba_open(): Argument #5 ($map_size) must be greater than or equal to 0 Warning: dba_popen(): Handler "bogus" is not available in %s on line %d bool(false) -dba_popen(): Argument #1 ($path) cannot be empty -dba_popen(): Argument #2 ($mode) cannot be empty -dba_popen(): Argument #3 ($handler) cannot be empty +dba_popen(): Argument #1 ($path) must not be empty +dba_popen(): Argument #2 ($mode) must not be empty +dba_popen(): Argument #3 ($handler) must not be empty dba_popen(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n" dba_popen(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t" dba_popen(): Argument #2 ($mode) third character must be "t" diff --git a/ext/dom/document.c b/ext/dom/document.c index 9b48cd96b65d1..2dc6fc9c49beb 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1525,7 +1525,7 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZEND_SIZE_T_INT_OVFL(source_len)) { @@ -1579,7 +1579,7 @@ PHP_METHOD(DOMDocument, save) } if (file_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1883,7 +1883,7 @@ static void dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1992,7 +1992,7 @@ static void dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2085,7 +2085,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2162,7 +2162,7 @@ PHP_METHOD(DOMDocument, saveHTMLFile) } if (file_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index d505e5326b3bc..0737be5fa5c9f 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -64,7 +64,7 @@ PHP_METHOD(DOMImplementation, createDocumentType) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/element.c b/ext/dom/element.c index 1542c23149a9f..75c772fa2c306 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -411,7 +411,7 @@ PHP_METHOD(DOMElement, setAttribute) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -903,7 +903,7 @@ PHP_METHOD(DOMElement, getAttributeNS) static void dom_set_attribute_ns_legacy(dom_object *intern, xmlNodePtr elemp, char *uri, size_t uri_len, char *name, size_t name_len, const char *value) { if (name_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); return; } diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 542a5cccab2ce..18c6c909ad672 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -1283,7 +1283,7 @@ PHP_METHOD(Dom_HTMLDocument, saveHtmlFile) } if (file_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt index 1e0eb43247d9b..6886240e595bf 100644 --- a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt +++ b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt @@ -14,4 +14,4 @@ try { } ?> --EXPECT-- -DOMDocument::loadHTML(): Argument #1 ($source) cannot be empty +DOMDocument::loadHTML(): Argument #1 ($source) must not be empty diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt index 87b3dc9804634..a5ef58a65656b 100644 --- a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt +++ b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt @@ -23,5 +23,5 @@ try { } ?> --EXPECT-- -DOMDocument::loadHTMLFile(): Argument #1 ($filename) cannot be empty +DOMDocument::loadHTMLFile(): Argument #1 ($filename) must not be empty DOMDocument::loadHTMLFile(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/dom/tests/DOMDocument_loadXML_error6.phpt b/ext/dom/tests/DOMDocument_loadXML_error6.phpt index bd552ae719eae..748a8eb5dc1d5 100644 --- a/ext/dom/tests/DOMDocument_loadXML_error6.phpt +++ b/ext/dom/tests/DOMDocument_loadXML_error6.phpt @@ -13,4 +13,4 @@ try { } ?> --EXPECT-- -DOMDocument::loadXML(): Argument #1 ($source) cannot be empty +DOMDocument::loadXML(): Argument #1 ($source) must not be empty diff --git a/ext/dom/tests/DOMDocument_load_error6.phpt b/ext/dom/tests/DOMDocument_load_error6.phpt index 96fe5bb5c322a..a4f9bc4a02a87 100644 --- a/ext/dom/tests/DOMDocument_load_error6.phpt +++ b/ext/dom/tests/DOMDocument_load_error6.phpt @@ -22,6 +22,6 @@ try { var_dump($dom->load(str_repeat(" ", PHP_MAXPATHLEN + 1))); ?> --EXPECT-- -DOMDocument::load(): Argument #1 ($filename) cannot be empty +DOMDocument::load(): Argument #1 ($filename) must not be empty DOMDocument::load(): Argument #1 ($filename) must not contain any null bytes bool(false) diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt index 3db1c37a492a9..8dc89f2530124 100644 --- a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt @@ -24,4 +24,4 @@ try { } ?> --EXPECT-- -DOMDocument::saveHTMLFile(): Argument #1 ($filename) cannot be empty +DOMDocument::saveHTMLFile(): Argument #1 ($filename) must not be empty diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt index 88c8123a28da7..ec295a55e3391 100644 --- a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt @@ -20,4 +20,4 @@ try { ?> --EXPECT-- -DOMDocument::schemaValidateSource(): Argument #1 ($source) cannot be empty +DOMDocument::schemaValidateSource(): Argument #1 ($source) must not be empty diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt index ac70535c5c321..274463e62e139 100644 --- a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt +++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt @@ -20,4 +20,4 @@ try { ?> --EXPECT-- -DOMDocument::schemaValidate(): Argument #1 ($filename) cannot be empty +DOMDocument::schemaValidate(): Argument #1 ($filename) must not be empty diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt index 35b6165a18538..93daf65f72f22 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_saveHTMLFile_empty_path.phpt @@ -11,7 +11,7 @@ $dom->saveHtmlFile(""); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: Dom\HTMLDocument::saveHtmlFile(): Argument #1 ($filename) cannot be empty in %s:%d +Fatal error: Uncaught ValueError: Dom\HTMLDocument::saveHtmlFile(): Argument #1 ($filename) must not be empty in %s:%d Stack trace: #0 %s(%d): Dom\HTMLDocument->saveHtmlFile('') #1 {main} diff --git a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt index 96b054168a2dc..98e2bd48addf8 100644 --- a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt +++ b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt @@ -9,7 +9,7 @@ $dom = Dom\HTMLDocument::createFromFile(""); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: Path cannot be empty in %s:%d +Fatal error: Uncaught ValueError: Path must not be empty in %s:%d Stack trace: #0 %s(%d): Dom\HTMLDocument::createFromFile('') #1 {main} diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index faf18b842ed3a..d27db9bcd29b5 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -447,7 +447,7 @@ PHP_FUNCTION(enchant_broker_request_dict) PHP_ENCHANT_GET_BROKER; if (taglen == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt b/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt index b49967cbedc3f..37f5d359481b3 100644 --- a/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt +++ b/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt @@ -18,4 +18,4 @@ try { ?> --EXPECT-- -enchant_broker_request_dict(): Argument #2 ($tag) cannot be empty +enchant_broker_request_dict(): Argument #2 ($tag) must not be empty diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 44a193e7c0b6e..518c31526532d 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -4550,7 +4550,7 @@ PHP_FUNCTION(exif_read_data) } if (!Z_STRLEN_P(stream)) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -4727,7 +4727,7 @@ PHP_FUNCTION(exif_thumbnail) } if (!Z_STRLEN_P(stream)) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/exif/tests/filename_empty.phpt b/ext/exif/tests/filename_empty.phpt index a089926c3b513..8e83f6b487f85 100644 --- a/ext/exif/tests/filename_empty.phpt +++ b/ext/exif/tests/filename_empty.phpt @@ -31,7 +31,7 @@ try { ?> --EXPECT-- -exif_read_data(): Argument #1 ($file) cannot be empty -exif_thumbnail(): Argument #1 ($file) cannot be empty +exif_read_data(): Argument #1 ($file) must not be empty +exif_thumbnail(): Argument #1 ($file) must not be empty exif_read_data(): Argument #1 ($file) must not contain any null bytes exif_thumbnail(): Argument #1 ($file) must not contain any null bytes diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 0d802925d892e..eb505f0085af9 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -374,7 +374,7 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime php_stream_statbuf ssb; if (buffer == NULL || buffer_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); goto clean; } if (CHECK_NULL_PATH(buffer, buffer_len)) { diff --git a/ext/fileinfo/tests/finfo_file_001.phpt b/ext/fileinfo/tests/finfo_file_001.phpt index 7eb39487b7d2b..86ce797a04db4 100644 --- a/ext/fileinfo/tests/finfo_file_001.phpt +++ b/ext/fileinfo/tests/finfo_file_001.phpt @@ -22,7 +22,7 @@ var_dump(finfo_file($fp, '&')); ?> --EXPECTF-- finfo_file(): Argument #1 ($finfo) must not contain any null bytes -finfo_file(): Argument #1 ($finfo) cannot be empty +finfo_file(): Argument #1 ($finfo) must not be empty string(9) "directory" Warning: finfo_file(&): Failed to open stream: No such file or directory in %s on line %d diff --git a/ext/fileinfo/tests/mime_content_type_001.phpt b/ext/fileinfo/tests/mime_content_type_001.phpt index 38c136f3844c7..98c1325959d85 100644 --- a/ext/fileinfo/tests/mime_content_type_001.phpt +++ b/ext/fileinfo/tests/mime_content_type_001.phpt @@ -47,5 +47,5 @@ mime_content_type(): Argument #1 ($filename) must be of type resource|string, st mime_content_type(): Argument #1 ($filename) must be of type resource|string, array given Warning: mime_content_type(foo/inexistent): Failed to open stream: No such file or directory in %s on line %d -mime_content_type(): Argument #1 ($filename) cannot be empty +mime_content_type(): Argument #1 ($filename) must not be empty mime_content_type(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index ca8e65c1f75f6..b8758199279c7 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -382,7 +382,7 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if (thousand_set) { if (thousand_len < 1) { - zend_value_error("%s(): \"thousand\" option cannot be empty", get_active_function_name()); + zend_value_error("%s(): \"thousand\" option must not be empty", get_active_function_name()); RETURN_VALIDATION_FAILED } else { tsd_sep = thousand; diff --git a/ext/filter/tests/bug51368.phpt b/ext/filter/tests/bug51368.phpt index 73c743b5dee4f..78f374848b644 100644 --- a/ext/filter/tests/bug51368.phpt +++ b/ext/filter/tests/bug51368.phpt @@ -21,4 +21,4 @@ try { --EXPECT-- float(1000) float(1234.567) -filter_var(): "thousand" option cannot be empty +filter_var(): "thousand" option must not be empty diff --git a/ext/gd/gd.c b/ext/gd/gd.c index b03c4700add37..899dc05b3e829 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -646,7 +646,7 @@ PHP_FUNCTION(imagesetstyle) num_styles = zend_hash_num_elements(Z_ARRVAL_P(styles)); if (num_styles == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/gd/tests/bug72709.phpt b/ext/gd/tests/bug72709.phpt index 7ea80df9a78e4..b0b4aa77bdf92 100644 --- a/ext/gd/tests/bug72709.phpt +++ b/ext/gd/tests/bug72709.phpt @@ -18,5 +18,5 @@ imagedestroy($im); ?> ====DONE==== --EXPECT-- -imagesetstyle(): Argument #2 ($style) cannot be empty +imagesetstyle(): Argument #2 ($style) must not be empty ====DONE==== diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index ee94fcb26ed74..ebf9bd767180a 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -55,7 +55,7 @@ ZEND_GET_MODULE(php_gettext) zend_argument_value_error(_arg_num, "is too long"); \ RETURN_THROWS(); \ } else if (domain_len == 0) { \ - zend_argument_cannot_be_empty_error(_arg_num); \ + zend_argument_must_not_be_empty_error(_arg_num); \ RETURN_THROWS(); \ } diff --git a/ext/gettext/tests/dcngettext.phpt b/ext/gettext/tests/dcngettext.phpt index 3b8123413e252..16258d6780153 100644 --- a/ext/gettext/tests/dcngettext.phpt +++ b/ext/gettext/tests/dcngettext.phpt @@ -33,6 +33,6 @@ string(1) "1" string(4) "test" string(4) "test" string(4) "test" -dcngettext(): Argument #1 ($domain) cannot be empty -dcngettext(): Argument #1 ($domain) cannot be empty +dcngettext(): Argument #1 ($domain) must not be empty +dcngettext(): Argument #1 ($domain) must not be empty Done diff --git a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt index e6df576edf063..cd07db1a94227 100644 --- a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt +++ b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt @@ -20,8 +20,8 @@ gettext echo "Done\n"; ?> --EXPECT-- -bind_textdomain_codeset(): Argument #1 ($domain) cannot be empty -bind_textdomain_codeset(): Argument #1 ($domain) cannot be empty +bind_textdomain_codeset(): Argument #1 ($domain) must not be empty +bind_textdomain_codeset(): Argument #1 ($domain) must not be empty string(5) "UTF-8" Done --CREDITS-- diff --git a/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt b/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt index f80063bed1105..607460b3c2db0 100644 --- a/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt +++ b/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt @@ -15,7 +15,7 @@ try { ?> --EXPECT-- -bindtextdomain(): Argument #1 ($domain) cannot be empty +bindtextdomain(): Argument #1 ($domain) must not be empty --CREDITS-- Till Klampaeckel, till@php.net PHP Testfest Berlin 2009-05-09 diff --git a/ext/gettext/tests/gettext_textdomain-retval.phpt b/ext/gettext/tests/gettext_textdomain-retval.phpt index 96b29c7bf946c..2f2f52d37743b 100644 --- a/ext/gettext/tests/gettext_textdomain-retval.phpt +++ b/ext/gettext/tests/gettext_textdomain-retval.phpt @@ -36,7 +36,7 @@ test test foo textdomain(): Argument #1 ($domain) cannot be zero -textdomain(): Argument #1 ($domain) cannot be empty +textdomain(): Argument #1 ($domain) must not be empty --CREDITS-- Christian Weiske, cweiske@php.net PHP Testfest Berlin 2009-05-09 diff --git a/ext/hash/hash.c b/ext/hash/hash.c index d4953aa7ec6ef..89a3aab26e78b 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -635,7 +635,7 @@ PHP_FUNCTION(hash_init) } if (!key || (ZSTR_LEN(key) == 0)) { /* Note: a zero length key is no key at all */ - zend_argument_value_error(3, "cannot be empty when HMAC is requested"); + zend_argument_value_error(3, "must not be empty when HMAC is requested"); RETURN_THROWS(); } } @@ -914,7 +914,7 @@ PHP_FUNCTION(hash_hkdf) } if (ZSTR_LEN(ikm) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/hash/tests/hash_hkdf_error.phpt b/ext/hash/tests/hash_hkdf_error.phpt index 60a887d003d01..86aa10a02f351 100644 --- a/ext/hash/tests/hash_hkdf_error.phpt +++ b/ext/hash/tests/hash_hkdf_error.phpt @@ -61,6 +61,6 @@ trycatch_dump( [ValueError] hash_hkdf(): Argument #1 ($algo) must be a valid cryptographic hashing algorithm -- Testing hash_hkdf() function with invalid parameters -- -[ValueError] hash_hkdf(): Argument #2 ($key) cannot be empty +[ValueError] hash_hkdf(): Argument #2 ($key) must not be empty [ValueError] hash_hkdf(): Argument #3 ($length) must be greater than or equal to 0 [ValueError] hash_hkdf(): Argument #3 ($length) must be less than or equal to 5100 diff --git a/ext/hash/tests/hash_init_error.phpt b/ext/hash/tests/hash_init_error.phpt index 4256b570e45b6..560ad4f8e9ae3 100644 --- a/ext/hash/tests/hash_init_error.phpt +++ b/ext/hash/tests/hash_init_error.phpt @@ -47,7 +47,7 @@ hash_init(): Argument #1 ($algo) must be a valid hashing algorithm hash_init(): Argument #1 ($algo) must be a cryptographic hashing algorithm if HMAC is requested -- Testing hash_init() function with HASH_HMAC and no key -- -hash_init(): Argument #3 ($key) cannot be empty when HMAC is requested +hash_init(): Argument #3 ($key) must not be empty when HMAC is requested Deprecated: hash_init(): Passing null to parameter #3 ($key) of type string is deprecated in %s on line %d -hash_init(): Argument #3 ($key) cannot be empty when HMAC is requested +hash_init(): Argument #3 ($key) must not be empty when HMAC is requested diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c index 3fb7ee5cba12a..62ee83f62f9ba 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.c @@ -125,7 +125,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(domain) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(domain) > INT32_MAX - 1) { diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index 2d344e054e838..c64bf1d451849 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -186,9 +186,9 @@ static zval *resource_bundle_array_fetch( if (offset_str) { if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) { if (offset_arg_num) { - zend_argument_cannot_be_empty_error(offset_arg_num); + zend_argument_must_not_be_empty_error(offset_arg_num); } else { - zend_value_error("Offset cannot be empty"); + zend_value_error("Offset must not be empty"); } return NULL; } diff --git a/ext/intl/tests/idn_uts46_errors.phpt b/ext/intl/tests/idn_uts46_errors.phpt index 435d464f7ac3c..1cbf336defa61 100644 --- a/ext/intl/tests/idn_uts46_errors.phpt +++ b/ext/intl/tests/idn_uts46_errors.phpt @@ -48,7 +48,7 @@ var_dump($foo["errors"]==IDNA_ERROR_CONTEXTJ); bad variant: ValueError: idn_to_ascii(): Argument #2 ($flags) must be INTL_IDNA_VARIANT_UTS46 empty domain: -ValueError: idn_to_ascii(): Argument #1 ($domain) cannot be empty +ValueError: idn_to_ascii(): Argument #1 ($domain) must not be empty with error, but no details arg: bool(false) with error, with details arg: diff --git a/ext/intl/tests/resourcebundle_dimension_errors.phpt b/ext/intl/tests/resourcebundle_dimension_errors.phpt index 77f30262008ad..2c2d0839e02fc 100644 --- a/ext/intl/tests/resourcebundle_dimension_errors.phpt +++ b/ext/intl/tests/resourcebundle_dimension_errors.phpt @@ -57,5 +57,5 @@ Error: Cannot use object of type ResourceBundle as array string(7) "default" TypeError: Cannot access offset of type float on ResourceBundle TypeError: Cannot access offset of type stdClass on ResourceBundle -ValueError: Offset cannot be empty +ValueError: Offset must not be empty ValueError: Index must be between -2147483648 and 2147483647 diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index f1a37dd4dd8eb..b7db6bbbcf3f0 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1501,7 +1501,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) nlinks = zend_hash_num_elements(Z_ARRVAL_P(link)); if (nlinks == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); ret = 0; goto cleanup; } @@ -2696,7 +2696,7 @@ PHP_FUNCTION(ldap_modify_batch) zend_hash_internal_pointer_reset(Z_ARRVAL_P(modinfo)); num_modvals = zend_hash_num_elements(Z_ARRVAL_P(modinfo)); if (num_modvals == 0) { - zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" cannot be empty", get_active_function_name()); + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must not be empty", get_active_function_name()); RETURN_THROWS(); } diff --git a/ext/ldap/tests/ldap_search_error.phpt b/ext/ldap/tests/ldap_search_error.phpt index 659b8a6c0664b..4e775ad13d66e 100644 --- a/ext/ldap/tests/ldap_search_error.phpt +++ b/ext/ldap/tests/ldap_search_error.phpt @@ -59,7 +59,7 @@ bool(false) Warning: ldap_search(): Array initialization wrong in %s on line %d bool(false) -ldap_search(): Argument #1 ($ldap) cannot be empty +ldap_search(): Argument #1 ($ldap) must not be empty ldap_search(): Argument #2 ($base) must have the same number of elements as the links array ldap_search(): Argument #3 ($filter) must have the same number of elements as the links array ldap_search(): Argument #2 ($base) must be of type string when argument #1 ($ldap) is an LDAP instance diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 6c5ac38021c6b..1ca160d4740a6 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2238,7 +2238,7 @@ PHP_FUNCTION(mb_substr_count) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(needle) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -2278,7 +2278,7 @@ PHP_FUNCTION(mb_substr_count) if (ZSTR_LEN(needle_u8) == 0) { zend_string_free(haystack_u8); zend_string_free(needle_u8); - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } } @@ -5673,7 +5673,7 @@ PHP_FUNCTION(mb_ord) ZEND_PARSE_PARAMETERS_END(); if (str_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -5810,7 +5810,7 @@ PHP_FUNCTION(mb_str_pad) } if (ZSTR_LEN(pad) == 0) { - zend_argument_cannot_be_empty_error(3); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index c3dab804a5a75..e1a5a10c39938 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -900,7 +900,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) } if (arg_pattern_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1468,7 +1468,7 @@ PHP_FUNCTION(mb_ereg_search_init) } if (arg_pattern && arg_pattern_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/mbstring/tests/bug43994.phpt b/ext/mbstring/tests/bug43994.phpt index 16ed4744e0217..26f641f6d3d7e 100644 --- a/ext/mbstring/tests/bug43994.phpt +++ b/ext/mbstring/tests/bug43994.phpt @@ -43,28 +43,28 @@ foreach($inputs as $input) { --EXPECT-- -- Iteration 1 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty NULL -- Iteration 2 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty NULL -- Iteration 3 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty NULL -- Iteration 4 -- Without $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: -mb_ereg(): Argument #1 ($pattern) cannot be empty +mb_ereg(): Argument #1 ($pattern) must not be empty NULL diff --git a/ext/mbstring/tests/empty_pattern.phpt b/ext/mbstring/tests/empty_pattern.phpt index 75635395d7051..64e63147ee789 100644 --- a/ext/mbstring/tests/empty_pattern.phpt +++ b/ext/mbstring/tests/empty_pattern.phpt @@ -25,5 +25,5 @@ try { ?> --EXPECT-- -mb_ereg_search_init(): Argument #2 ($pattern) cannot be empty +mb_ereg_search_init(): Argument #2 ($pattern) must not be empty No pattern was provided diff --git a/ext/mbstring/tests/mb_ereg1.phpt b/ext/mbstring/tests/mb_ereg1.phpt index 3cc09a8c2f49d..813fe5e41ef0d 100644 --- a/ext/mbstring/tests/mb_ereg1.phpt +++ b/ext/mbstring/tests/mb_ereg1.phpt @@ -35,7 +35,7 @@ array(3) { array(0) { } } -ValueError: mb_ereg(): Argument #1 ($pattern) cannot be empty +ValueError: mb_ereg(): Argument #1 ($pattern) must not be empty array(3) { [0]=> string(0) "" diff --git a/ext/mbstring/tests/mb_ord.phpt b/ext/mbstring/tests/mb_ord.phpt index 7f313300f8152..a42cb9497fabd 100644 --- a/ext/mbstring/tests/mb_ord.phpt +++ b/ext/mbstring/tests/mb_ord.phpt @@ -56,7 +56,7 @@ try { bool(true) bool(true) bool(true) -mb_ord(): Argument #1 ($string) cannot be empty +mb_ord(): Argument #1 ($string) must not be empty mb_ord(): Argument #2 ($encoding) must be a valid encoding, "typo" given mb_ord(): Argument #2 ($encoding) must be a valid encoding, "pass" given mb_ord() does not support the "JIS" encoding diff --git a/ext/mbstring/tests/mb_str_pad.phpt b/ext/mbstring/tests/mb_str_pad.phpt index edee4dc917952..2ea118e03fa58 100644 --- a/ext/mbstring/tests/mb_str_pad.phpt +++ b/ext/mbstring/tests/mb_str_pad.phpt @@ -87,9 +87,9 @@ foreach ($tests as $encoding => $test) { ?> --EXPECT-- --- Error conditions --- -ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty -ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty -ValueError: mb_str_pad(): Argument #3 ($pad_string) cannot be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty ValueError: mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH ValueError: mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "non-existing" given --- Simple ASCII strings --- diff --git a/ext/mbstring/tests/mb_substr_count.phpt b/ext/mbstring/tests/mb_substr_count.phpt index 1047284303b58..2927419930b39 100644 --- a/ext/mbstring/tests/mb_substr_count.phpt +++ b/ext/mbstring/tests/mb_substr_count.phpt @@ -69,9 +69,9 @@ output_handler= ?> --EXPECT-- == Empty needle should raise an error == -mb_substr_count(): Argument #2 ($needle) cannot be empty -mb_substr_count(): Argument #2 ($needle) cannot be empty -mb_substr_count(): Argument #2 ($needle) cannot be empty +mb_substr_count(): Argument #2 ($needle) must not be empty +mb_substr_count(): Argument #2 ($needle) must not be empty +mb_substr_count(): Argument #2 ($needle) must not be empty == Return value for empty haystack should always be zero == int(0) int(0) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 09fe384938bc2..6017a2b9ed9ea 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -139,7 +139,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if (!types_len) { - zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index b6390db653a58..365c4891a09a7 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -572,7 +572,7 @@ PHP_FUNCTION(mysqli_query) } if (!query_len) { - zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && @@ -1013,7 +1013,7 @@ PHP_FUNCTION(mysqli_begin_transaction) RETURN_THROWS(); } if (name && !name_len) { - zend_argument_cannot_be_empty_error(ERROR_ARG_POS(3)); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(3)); RETURN_THROWS(); } @@ -1037,7 +1037,7 @@ PHP_FUNCTION(mysqli_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } @@ -1061,7 +1061,7 @@ PHP_FUNCTION(mysqli_release_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_cannot_be_empty_error(ERROR_ARG_POS(2)); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if (FAIL == mysqlnd_release_savepoint(mysql->mysql, name)) { diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index 640dbacaaf2c4..49324aeb01df0 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -114,7 +114,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) mysqli_close($link); ?> --EXPECTF-- -mysqli_query(): Argument #2 ($query) cannot be empty +mysqli_query(): Argument #2 ($query) must not be empty array(1) { ["valid"]=> string(30) "this is sql but with semicolon" diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index f1d7fba992d39..3e02bed816a26 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -61,7 +61,7 @@ if (!have_innodb($link)) require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_release_savepoint(): Argument #2 ($name) cannot be empty +mysqli_release_savepoint(): Argument #2 ($name) must not be empty array(1) { ["id"]=> string(1) "1" diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index 0de39d7d71546..f1bc787312fa5 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -52,5 +52,5 @@ if (!have_innodb($link)) require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_savepoint(): Argument #2 ($name) cannot be empty +mysqli_savepoint(): Argument #2 ($name) must not be empty done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt index c4b0c21f25867..573a88689d667 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -413,7 +413,7 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- The number of variables must match the number of parameters in the prepared statement -mysqli_stmt_bind_param(): Argument #2 ($types) cannot be empty +mysqli_stmt_bind_param(): Argument #2 ($types) must not be empty The number of elements in the type definition string must match the number of bind variables The number of variables must match the number of parameters in the prepared statement The number of elements in the type definition string must match the number of bind variables diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 7be102d1fb21a..e0a27a990f904 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -7243,7 +7243,7 @@ PHP_FUNCTION(openssl_seal) pubkeysht = Z_ARRVAL_P(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { - zend_argument_cannot_be_empty_error(4); + zend_argument_must_not_be_empty_error(4); RETURN_THROWS(); } @@ -8017,7 +8017,7 @@ PHP_FUNCTION(openssl_decrypt) } if (!method_len) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -8059,7 +8059,7 @@ PHP_FUNCTION(openssl_cipher_iv_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -8088,7 +8088,7 @@ PHP_FUNCTION(openssl_cipher_key_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt index 8fca1fdd71e66..cdd5f3616fb23 100644 --- a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt @@ -18,4 +18,4 @@ try { Warning: openssl_cipher_iv_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_iv_length(): Argument #1 ($cipher_algo) cannot be empty +openssl_cipher_iv_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_cipher_key_length_error.phpt b/ext/openssl/tests/openssl_cipher_key_length_error.phpt index 08c08d382eb0c..a4e4e8e6bfcff 100644 --- a/ext/openssl/tests/openssl_cipher_key_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_key_length_error.phpt @@ -18,4 +18,4 @@ try { Warning: openssl_cipher_key_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_key_length(): Argument #1 ($cipher_algo) cannot be empty +openssl_cipher_key_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_seal_basic.phpt b/ext/openssl/tests/openssl_seal_basic.phpt index 2d9d2cdd263c8..6c08efa6d70d2 100644 --- a/ext/openssl/tests/openssl_seal_basic.phpt +++ b/ext/openssl/tests/openssl_seal_basic.phpt @@ -40,13 +40,13 @@ var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong), $method)); --EXPECTF-- Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) cannot be empty +openssl_seal(): Argument #4 ($public_key) must not be empty int(32) int(32) Warning: openssl_seal(): Not a public key (2th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) cannot be empty +openssl_seal(): Argument #4 ($public_key) must not be empty Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 445734a5877a1..b2fe964e7face 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -860,7 +860,7 @@ static bool php_pcntl_set_user_signal_infos( bool allow_empty_signal_array ) { if (!allow_empty_signal_array && zend_hash_num_elements(user_signals) == 0) { - zend_argument_cannot_be_empty_error(arg_num); + zend_argument_must_not_be_empty_error(arg_num); return false; } @@ -1695,7 +1695,7 @@ PHP_FUNCTION(pcntl_setcpuaffinity) // TODO Why are the arguments optional? if (!hmask || zend_hash_num_elements(Z_ARRVAL_P(hmask)) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pcntl/tests/pcntl_cpuaffinity.phpt b/ext/pcntl/tests/pcntl_cpuaffinity.phpt index 9ec9703b3c48b..caeb27d2759cc 100644 --- a/ext/pcntl/tests/pcntl_cpuaffinity.phpt +++ b/ext/pcntl/tests/pcntl_cpuaffinity.phpt @@ -60,7 +60,7 @@ array(0) { array(0) { } bool(true) -pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cannot be empty +pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) must not be empty pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id invalid value (def) pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id must be between 0 and %d (%d) pcntl_setcpuaffinity(): Argument #2 ($cpu_ids) cpu id must be between 0 and %d (-1024) diff --git a/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt b/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt index 61370039c17d4..6815b208955da 100644 --- a/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt @@ -60,7 +60,7 @@ try { ?> --EXPECTF-- ValueError: pcntl_sigprocmask(): Argument #1 ($mode) must be one of SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK -ValueError: pcntl_sigprocmask(): Argument #2 ($signals) cannot be empty +ValueError: pcntl_sigprocmask(): Argument #2 ($signals) must not be empty ValueError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be between 1 and %d ValueError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be between 1 and %d TypeError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be of type int, string given diff --git a/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt b/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt index 3dbc3c904afef..70cd806a8e8d4 100644 --- a/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt @@ -86,7 +86,7 @@ try { ?> --EXPECTF-- -ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) cannot be empty +ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) must not be empty ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d diff --git a/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt b/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt index a58aa82c57f7d..1e237b4a1993a 100644 --- a/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt @@ -51,7 +51,7 @@ try { } ?> --EXPECTF-- -ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) cannot be empty +ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) must not be empty ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be between 1 and %d TypeError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be of type int, string given diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 0be81c463d435..dce5d64779a2b 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -563,7 +563,7 @@ PHP_METHOD(PDO, prepare) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1030,7 +1030,7 @@ PHP_METHOD(PDO, exec) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(statement) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1166,7 +1166,7 @@ PHP_METHOD(PDO, query) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 751781e76ebc6..4fc95aa7d6fee 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1423,7 +1423,7 @@ static void register_bound_param(INTERNAL_FUNCTION_PARAMETERS, int is_param) /* if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; @@ -1471,7 +1471,7 @@ PHP_METHOD(PDOStatement, bindValue) if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt index 556d1f28b0b0a..29074fb5505f5 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt @@ -162,7 +162,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated'); ?> --EXPECTF-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { ["one"]=> string(1) "1" diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt index ea13fa229bb2c..ac4f85949bb17 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt @@ -161,7 +161,7 @@ $db = MySQLPDOTest::factory(); $db->query('DROP TABLE IF EXISTS test_prepare_emulated_anonymous_placeholder'); ?> --EXPECTF-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt index 976219fc2320b..8406be4db6d76 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt @@ -152,5 +152,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated_myisam'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt index f6d02031da3d1..1acc055e12a0c 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt @@ -164,5 +164,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated_myisam_index'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt index 4c7497f69e5d9..02690d4164c69 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt @@ -165,7 +165,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt index c469112c3d06a..db7844b1e6fbf 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt @@ -243,7 +243,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_anonymous_placeholder'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt index de40cbdbb0504..c8ede104016a3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt @@ -155,5 +155,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_myisam'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt index 2bb6ea0caa7ee..f1547281438ec 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt @@ -175,5 +175,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_myisam_index'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index fbc30a3c09a63..684f7798a45f8 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -627,7 +627,7 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS) } if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index 4b0dc8f99e233..bc47c15a1eb5e 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -82,7 +82,7 @@ PHP_METHOD(Pdo_Sqlite, loadExtension) } if (extension_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 4d3c548025dad..af95c81d803af 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4613,7 +4613,7 @@ PHP_FUNCTION(pg_meta_data) /* php_pgsql_meta_data() asserts that table_name is not empty */ if (ZSTR_LEN(table_name) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -4799,7 +4799,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * ZEND_ASSERT(Z_TYPE_P(result) == IS_ARRAY); ZEND_ASSERT(!(opt & ~PGSQL_CONV_OPTS)); ZEND_ASSERT(table_name); - /* Table name cannot be empty for php_pgsql_meta_data() */ + /* Table name must not be empty for php_pgsql_meta_data() */ ZEND_ASSERT(ZSTR_LEN(table_name) != 0); array_init(&meta); @@ -5405,7 +5405,7 @@ PHP_FUNCTION(pg_convert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table_name) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5618,7 +5618,7 @@ PHP_FUNCTION(pg_insert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5840,7 +5840,7 @@ PHP_FUNCTION(pg_update) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5939,7 +5939,7 @@ PHP_FUNCTION(pg_delete) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -6095,7 +6095,7 @@ PHP_FUNCTION(pg_select) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -6143,13 +6143,13 @@ PHP_FUNCTION(pg_change_password) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(user) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } /* it is technically possible, but better to disallow it */ if (ZSTR_LEN(passwd) == 0) { - zend_argument_cannot_be_empty_error(3); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/pgsql/tests/changepassword.phpt b/ext/pgsql/tests/changepassword.phpt index 9c2eed40ef410..3271cd30331c5 100644 --- a/ext/pgsql/tests/changepassword.phpt +++ b/ext/pgsql/tests/changepassword.phpt @@ -24,6 +24,6 @@ try { var_dump(pg_change_password($conn, "inexistent_user", "postitpwd")); ?> --EXPECT-- -pg_change_password(): Argument #2 ($user) cannot be empty -pg_change_password(): Argument #3 ($password) cannot be empty +pg_change_password(): Argument #2 ($user) must not be empty +pg_change_password(): Argument #3 ($password) must not be empty bool(false) diff --git a/ext/pgsql/tests/pg_insert_002.phpt b/ext/pgsql/tests/pg_insert_002.phpt index 533b1762706cf..f304e561bb5f1 100644 --- a/ext/pgsql/tests/pg_insert_002.phpt +++ b/ext/pgsql/tests/pg_insert_002.phpt @@ -21,7 +21,7 @@ foreach (array('', '.', '..') as $table) { ?> Done --EXPECTF-- -pg_insert(): Argument #2 ($table_name) cannot be empty +pg_insert(): Argument #2 ($table_name) must not be empty pg_insert(): Argument #2 ($table_name) must be specified (.) pg_insert(): Argument #2 ($table_name) must be specified (..) Done diff --git a/ext/phar/tests/create_path_error.phpt b/ext/phar/tests/create_path_error.phpt index b0b15612222b1..fea390e477cb8 100644 --- a/ext/phar/tests/create_path_error.phpt +++ b/ext/phar/tests/create_path_error.phpt @@ -65,10 +65,10 @@ foreach($checks as $check) --EXPECTF-- string(5) "query" string(5) "query" -1:Error: file_put_contents(phar://%s//): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -2:Error: file_put_contents(phar://%s/.): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -3:Error: file_put_contents(phar://%s/../): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -4:Error: file_put_contents(phar://%s/a/..): Failed to open stream: phar error: file "" in phar "%s" cannot be empty +1:Error: file_put_contents(phar://%s//): Failed to open stream: phar error: file "" in phar "%s" must not be empty +2:Error: file_put_contents(phar://%s/.): Failed to open stream: phar error: file "" in phar "%s" must not be empty +3:Error: file_put_contents(phar://%s/../): Failed to open stream: phar error: file "" in phar "%s" must not be empty +4:Error: file_put_contents(phar://%s/a/..): Failed to open stream: phar error: file "" in phar "%s" must not be empty 5: 6: 7: diff --git a/ext/phar/util.c b/ext/phar/util.c index d5a574cfd2ccb..3a366216650a2 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -380,7 +380,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, ch if (!path_len) { if (error) { - spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" cannot be empty", fname); + spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", fname); } return FAILURE; } diff --git a/ext/posix/posix.c b/ext/posix/posix.c index bea433cd5f297..fc4928d5d2cf5 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -746,7 +746,7 @@ PHP_FUNCTION(posix_eaccess) path = expand_filepath(filename, NULL); if (!path) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1285,7 +1285,7 @@ PHP_FUNCTION(posix_pathconf) ZEND_PARSE_PARAMETERS_END(); if (path_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } else if (php_check_open_basedir(path)) { php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path); diff --git a/ext/posix/tests/posix_eaccess.phpt b/ext/posix/tests/posix_eaccess.phpt index ab47a1a0e8e36..4211e6ef13e72 100644 --- a/ext/posix/tests/posix_eaccess.phpt +++ b/ext/posix/tests/posix_eaccess.phpt @@ -17,4 +17,4 @@ try { ?> --EXPECT-- -posix_eaccess(): Argument #1 ($filename) cannot be empty +posix_eaccess(): Argument #1 ($filename) must not be empty diff --git a/ext/posix/tests/posix_pathconf.phpt b/ext/posix/tests/posix_pathconf.phpt index ffbec521f92c0..ba451c62df97b 100644 --- a/ext/posix/tests/posix_pathconf.phpt +++ b/ext/posix/tests/posix_pathconf.phpt @@ -18,7 +18,7 @@ var_dump(posix_errno() != 0); var_dump(posix_pathconf(sys_get_temp_dir(), POSIX_PC_PATH_MAX)); ?> --EXPECTF-- -posix_pathconf(): Argument #1 ($path) cannot be empty +posix_pathconf(): Argument #1 ($path) must not be empty bool(false) bool(true) int(%d) diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 3768e1b7e16ff..379641d5b8d78 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -434,7 +434,7 @@ PHP_METHOD(Random_Randomizer, getBytesFromString) const size_t max_offset = source_length - 1; if (source_length < 1) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt b/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt index 7280949d647e8..29c845353630c 100644 --- a/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt @@ -24,5 +24,5 @@ try { ?> --EXPECTF-- -Random\Randomizer::getBytesFromString(): Argument #1 ($string) cannot be empty +Random\Randomizer::getBytesFromString(): Argument #1 ($string) must not be empty Random\Randomizer::getBytesFromString(): Argument #2 ($length) must be greater than 0 diff --git a/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt b/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt index 15526327b095c..cbd0495676c1e 100644 --- a/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt +++ b/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt @@ -43,7 +43,7 @@ try { ?> --EXPECTF-- Random\Randomizer::pickArrayKeys(): Argument #1 ($array) must be of type array, string given -Random\Randomizer::pickArrayKeys(): Argument #1 ($array) cannot be empty +Random\Randomizer::pickArrayKeys(): Argument #1 ($array) must not be empty Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 74350167a5220..c98aa9381126a 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1667,7 +1667,7 @@ PHP_METHOD(SimpleXMLElement, addChild) } if (qname_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1734,7 +1734,7 @@ PHP_METHOD(SimpleXMLElement, addAttribute) } if (qname_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt index 8969cf0751de7..65f8f7baa8b7f 100644 --- a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt +++ b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt @@ -18,6 +18,6 @@ try { echo $a->asXML(); ?> --EXPECT-- -SimpleXMLElement::addAttribute(): Argument #1 ($qualifiedName) cannot be empty +SimpleXMLElement::addAttribute(): Argument #1 ($qualifiedName) must not be empty testfest diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 62e77979a3a0c..7e8d4d0bc2fc1 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -668,7 +668,7 @@ static bool php_snmp_parse_oid( objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - zend_value_error("Array of object IDs cannot be empty"); + zend_value_error("Array of object IDs must not be empty"); return false; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); diff --git a/ext/snmp/tests/snmp2_get.phpt b/ext/snmp/tests/snmp2_get.phpt index 174fbc91462e7..30500eb5ca9b3 100644 --- a/ext/snmp/tests/snmp2_get.phpt +++ b/ext/snmp/tests/snmp2_get.phpt @@ -54,7 +54,7 @@ var_dump(snmp2_get($hostname, $community, array('.1.3.6.1.2.1.1.1.0', '.1.3.6.1. --EXPECTF-- Checking error handling Empty OID array -Array of object IDs cannot be empty +Array of object IDs must not be empty Checking working Single OID string(%d) "%s" diff --git a/ext/soap/soap.c b/ext/soap/soap.c index fc7e5eb185305..401fbde9d82a9 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -571,7 +571,7 @@ PHP_METHOD(SoapParam, __construct) } if (ZSTR_LEN(name) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -602,11 +602,11 @@ PHP_METHOD(SoapHeader, __construct) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(ns) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(name) == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/soap/tests/bugs/bug31755.phpt b/ext/soap/tests/bugs/bug31755.phpt index 9284ba145e073..cf8987db3ee13 100644 --- a/ext/soap/tests/bugs/bug31755.phpt +++ b/ext/soap/tests/bugs/bug31755.phpt @@ -26,6 +26,6 @@ $response= $client->__soapCall('function', array(), null, $header); print $client->__getLastRequest(); ?> --EXPECT-- -SoapHeader::__construct(): Argument #1 ($namespace) cannot be empty +SoapHeader::__construct(): Argument #1 ($namespace) must not be empty bar diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 198ec02583edc..04dad88ac5915 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -662,7 +662,7 @@ static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_ * this is not required, at least on linux for abstract paths. It also * assumes that the path is not empty */ if (ZSTR_LEN(path_str) == 0) { - do_from_zval_err(ctx, "%s", "the path is cannot be empty"); + do_from_zval_err(ctx, "%s", "the path is must not be empty"); zend_tmp_string_release(tmp_path_str); return; } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index c59ec7f84a4b0..1f75c4e3ae8f8 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -696,7 +696,7 @@ static void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_l } if (ZSTR_LEN(path) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1227,7 +1227,7 @@ PHP_METHOD(SplFileInfo, getLinkTarget) } #if defined(PHP_WIN32) || defined(HAVE_SYMLINK) if (intern->file_name == NULL) { - zend_value_error("Filename cannot be empty"); + zend_value_error("Filename must not be empty"); RETURN_THROWS(); } if (!IS_ABSOLUTE_PATH(ZSTR_VAL(intern->file_name), ZSTR_LEN(intern->file_name))) { diff --git a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt index 01b7c7d72cf19..3db6700d2e94c 100644 --- a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt +++ b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt @@ -12,4 +12,4 @@ try { } ?> --EXPECT-- -DirectoryIterator::__construct(): Argument #1 ($directory) cannot be empty +DirectoryIterator::__construct(): Argument #1 ($directory) must not be empty diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 6aea72a6fa761..01b8af435b633 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -421,7 +421,7 @@ PHP_METHOD(SQLite3, loadExtension) } if (extension_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt index 8ab22520267f0..0be7469c8944b 100644 --- a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt +++ b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt @@ -26,4 +26,4 @@ try { ?> --EXPECTF-- -string(61) "SQLite3::loadExtension(): Argument #1 ($name) cannot be empty" +string(63) "SQLite3::loadExtension(): Argument #1 ($name) must not be empty" diff --git a/ext/standard/array.c b/ext/standard/array.c index b38b5fe6a6a61..a2fef8b145283 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6211,7 +6211,7 @@ PHPAPI bool php_array_pick_keys(php_random_algo_with_state engine, zval *input, if (num_avail == 0) { if (!silent) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); } return false; } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index a6226ae6cd98d..67276adb1627e 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2500,7 +2500,7 @@ PHP_FUNCTION(parse_ini_file) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(filename) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dir.c b/ext/standard/dir.c index bf0c566678111..1af6efe211a7e 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -467,7 +467,7 @@ PHP_FUNCTION(scandir) ZEND_PARSE_PARAMETERS_END(); if (dirn_len < 1) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 3f9b20cfe5424..04477129e3599 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -388,7 +388,7 @@ PHP_FUNCTION(dns_check_record) ZEND_PARSE_PARAMETERS_END(); if (hostname_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 5bc41880de54c..a41d6f44d03a0 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -108,7 +108,7 @@ PHP_FUNCTION(dns_check_record) } if (hostname_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index d4a1af465dfe8..8ebca90bce396 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -218,7 +218,7 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ ZEND_PARSE_PARAMETERS_END(); if (!cmd_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (strlen(cmd) != cmd_len) { @@ -518,7 +518,7 @@ PHP_FUNCTION(shell_exec) ZEND_PARSE_PARAMETERS_END(); if (!command_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 338fb00ee5145..98715b2ee8a08 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -40,7 +40,7 @@ PHP_FUNCTION(ftok) ZEND_PARSE_PARAMETERS_END(); if (pathname_len == 0){ - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/head.c b/ext/standard/head.c index ad02faf025577..ccef4be16bdfd 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -87,7 +87,7 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e smart_str buf = {0}; if (!ZSTR_LEN(name)) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); return FAILURE; } if (strpbrk(ZSTR_VAL(name), "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 6a15b3db71901..1082066dcec55 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -724,7 +724,7 @@ PHP_FUNCTION(wordwrap) } if (breakchar_len == 0) { - zend_argument_cannot_be_empty_error(3); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } @@ -930,7 +930,7 @@ PHP_FUNCTION(explode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(delim) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1277,7 +1277,7 @@ PHP_FUNCTION(str_increment) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -1333,7 +1333,7 @@ PHP_FUNCTION(str_decrement) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -5727,7 +5727,7 @@ PHP_FUNCTION(substr_count) ZEND_PARSE_PARAMETERS_END(); if (needle_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5802,7 +5802,7 @@ PHP_FUNCTION(str_pad) } if (pad_str_len == 0) { - zend_argument_cannot_be_empty_error(3); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/standard/tests/array/array_rand.phpt b/ext/standard/tests/array/array_rand.phpt index 03fb91eb53062..24f6966bb085e 100644 --- a/ext/standard/tests/array/array_rand.phpt +++ b/ext/standard/tests/array/array_rand.phpt @@ -38,8 +38,8 @@ var_dump(array_rand(array(1,2,3), 2)); ?> --EXPECTF-- -array_rand(): Argument #1 ($array) cannot be empty -array_rand(): Argument #1 ($array) cannot be empty +array_rand(): Argument #1 ($array) must not be empty +array_rand(): Argument #1 ($array) must not be empty array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) diff --git a/ext/standard/tests/dir/bug41693.phpt b/ext/standard/tests/dir/bug41693.phpt index 2c779bedcd41f..05722b9558d2d 100644 --- a/ext/standard/tests/dir/bug41693.phpt +++ b/ext/standard/tests/dir/bug41693.phpt @@ -11,4 +11,4 @@ try { ?> --EXPECT-- -scandir(): Argument #1 ($directory) cannot be empty +scandir(): Argument #1 ($directory) must not be empty diff --git a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt index b6d801e9e701b..ee408b2c97582 100644 --- a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt @@ -55,10 +55,10 @@ Warning: file_get_contents(1): Failed to open stream: No such file or directory bool(false) -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/file_get_contents_variation8.phpt b/ext/standard/tests/file/file_get_contents_variation8.phpt index ad23a13bb6b79..d6edef55db612 100644 --- a/ext/standard/tests/file/file_get_contents_variation8.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8.phpt @@ -52,9 +52,9 @@ bool(false) Warning: file_get_contents(1): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 2 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 3 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 4 -- Warning: file_get_contents( ): Failed to open stream: No such file or directory in %s on line %d diff --git a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt index dac2ba6d37ad3..b1625f030b06c 100644 --- a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt @@ -55,10 +55,10 @@ foreach($names_arr as $key =>$value) { 9 bytes written to: '1' -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/file_put_contents_variation8.phpt b/ext/standard/tests/file/file_put_contents_variation8.phpt index 705efcade7bf3..81bbd25168801 100644 --- a/ext/standard/tests/file/file_put_contents_variation8.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8.phpt @@ -64,9 +64,9 @@ rmdir($dir); -- Iteration 1 -- 9 bytes written to: '1' -- Iteration 2 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 3 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 4 -- 9 bytes written to: ' ' -- Iteration 5 -- diff --git a/ext/standard/tests/file/readfile_error.phpt b/ext/standard/tests/file/readfile_error.phpt index 9e47e68fac3c9..ec2cf53946a6d 100644 --- a/ext/standard/tests/file/readfile_error.phpt +++ b/ext/standard/tests/file/readfile_error.phpt @@ -29,8 +29,8 @@ echo "Done\n"; *** Test readfile(): error conditions *** -- Testing readfile() with invalid arguments -- -Path cannot be empty -Path cannot be empty +Path must not be empty +Path must not be empty -- Testing readfile() with non-existent file -- diff --git a/ext/standard/tests/file/readfile_variation10-win32.phpt b/ext/standard/tests/file/readfile_variation10-win32.phpt index 325e47224dccb..2ec770b4101c7 100644 --- a/ext/standard/tests/file/readfile_variation10-win32.phpt +++ b/ext/standard/tests/file/readfile_variation10-win32.phpt @@ -51,10 +51,10 @@ Warning: readfile(-1): Failed to open stream: No such file or directory in %s on Warning: readfile(1): Failed to open stream: No such file or directory in %s on line %d -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/readfile_variation10.phpt b/ext/standard/tests/file/readfile_variation10.phpt index 5afc5622ed166..d2875215e5f7b 100644 --- a/ext/standard/tests/file/readfile_variation10.phpt +++ b/ext/standard/tests/file/readfile_variation10.phpt @@ -49,9 +49,9 @@ Warning: readfile(-1): Failed to open stream: %s in %s on line %d Warning: readfile(1): Failed to open stream: %s in %s on line %d -- testing '' -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- testing '' -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- testing ' ' -- Warning: readfile( ): Failed to open stream: %s in %s on line %d diff --git a/ext/standard/tests/network/bug69523.phpt b/ext/standard/tests/network/bug69523.phpt index 60f3643044c60..5552ca2afdf82 100644 --- a/ext/standard/tests/network/bug69523.phpt +++ b/ext/standard/tests/network/bug69523.phpt @@ -9,4 +9,4 @@ try { } ?> --EXPECT-- -setcookie(): Argument #1 ($name) cannot be empty +setcookie(): Argument #1 ($name) must not be empty diff --git a/ext/standard/tests/network/dns_check_record_error_conditions.phpt b/ext/standard/tests/network/dns_check_record_error_conditions.phpt index dae0bfb3750c6..de33d74bce63d 100644 --- a/ext/standard/tests/network/dns_check_record_error_conditions.phpt +++ b/ext/standard/tests/network/dns_check_record_error_conditions.phpt @@ -15,5 +15,5 @@ try { } ?> --EXPECT-- -dns_check_record(): Argument #1 ($hostname) cannot be empty +dns_check_record(): Argument #1 ($hostname) must not be empty dns_check_record(): Argument #2 ($type) must be a valid DNS record type diff --git a/ext/standard/tests/network/setcookie_error.phpt b/ext/standard/tests/network/setcookie_error.phpt index 8c071199f8625..90177c714e583 100644 --- a/ext/standard/tests/network/setcookie_error.phpt +++ b/ext/standard/tests/network/setcookie_error.phpt @@ -50,7 +50,7 @@ var_dump(headers_list()); --EXPECTHEADERS-- --EXPECTF-- -setcookie(): Argument #1 ($name) cannot be empty +setcookie(): Argument #1 ($name) must not be empty setcookie(): Argument #1 ($name) cannot contain "=", ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "domain" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" diff --git a/ext/standard/tests/network/setrawcookie_error.phpt b/ext/standard/tests/network/setrawcookie_error.phpt index eba7b04bb03a5..9aae95673df09 100644 --- a/ext/standard/tests/network/setrawcookie_error.phpt +++ b/ext/standard/tests/network/setrawcookie_error.phpt @@ -50,7 +50,7 @@ var_dump(headers_list()); --EXPECTHEADERS-- --EXPECTF-- -setrawcookie(): Argument #1 ($name) cannot be empty +setrawcookie(): Argument #1 ($name) must not be empty setrawcookie(): Argument #1 ($name) cannot contain "=", ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setrawcookie(): Argument #2 ($value) cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setrawcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" diff --git a/ext/standard/tests/strings/explode.phpt b/ext/standard/tests/strings/explode.phpt index 07ab4488da5f7..ea467a2d55043 100644 --- a/ext/standard/tests/strings/explode.phpt +++ b/ext/standard/tests/strings/explode.phpt @@ -62,9 +62,9 @@ array ( 4 => 'd', ) d6bee42a771449205344c0938ad4f035 -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty array(1) { [0]=> string(0) "" @@ -79,7 +79,7 @@ array(1) { [0]=> string(0) "" } -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty array(1) { [0]=> string(3) "acb" diff --git a/ext/standard/tests/strings/explode1.phpt b/ext/standard/tests/strings/explode1.phpt index a15290f29fce5..876b159821cdc 100644 --- a/ext/standard/tests/strings/explode1.phpt +++ b/ext/standard/tests/strings/explode1.phpt @@ -91,15 +91,15 @@ var_dump( explode("b", $obj) ); --EXPECT-- *** Testing explode() for basic operations *** -- Iteration 1 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 2 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 3 -- array(1) { [0]=> @@ -201,10 +201,10 @@ array(2) { string(56) "234NULL23abcd00000TRUEFALSE-11.234444true-11.24%PHP%ZEND" } -- Iteration 7 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 8 -- array(2) { [0]=> diff --git a/ext/standard/tests/strings/md5_file.phpt b/ext/standard/tests/strings/md5_file.phpt index 7acb81c3a412b..1eb9b2654ada1 100644 --- a/ext/standard/tests/strings/md5_file.phpt +++ b/ext/standard/tests/strings/md5_file.phpt @@ -64,7 +64,7 @@ echo "\nDone"; ?> --EXPECTF-- *** Testing for error conditions *** -Path cannot be empty +Path must not be empty Warning: md5_file(aZrq16u): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/standard/tests/strings/sha1_file.phpt b/ext/standard/tests/strings/sha1_file.phpt index 62419d708f220..60d6ad808f8ca 100644 --- a/ext/standard/tests/strings/sha1_file.phpt +++ b/ext/standard/tests/strings/sha1_file.phpt @@ -74,7 +74,7 @@ unlink("EmptyFileSHA1.txt"); *** Testing for error conditions *** -- No filename -- -Path cannot be empty +Path must not be empty -- invalid filename -- @@ -89,7 +89,7 @@ bool(false) -- NULL as filename -- Deprecated: sha1_file(): Passing null to parameter #1 ($filename) of type string is deprecated in %s on line %d -Path cannot be empty +Path must not be empty -- Hexadecimal Output for Empty file as Argument -- string(40) "da39a3ee5e6b4b0d3255bfef95601890afd80709" diff --git a/ext/standard/tests/strings/str_decrement_errors.phpt b/ext/standard/tests/strings/str_decrement_errors.phpt index 6f7f61e6b7b9a..3186d24b81ed0 100644 --- a/ext/standard/tests/strings/str_decrement_errors.phpt +++ b/ext/standard/tests/strings/str_decrement_errors.phpt @@ -37,7 +37,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_decrement(): Argument #1 ($string) cannot be empty +str_decrement(): Argument #1 ($string) must not be empty str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters diff --git a/ext/standard/tests/strings/str_decrement_underflow.phpt b/ext/standard/tests/strings/str_decrement_underflow.phpt index ea60f0069342c..0521497713a17 100644 --- a/ext/standard/tests/strings/str_decrement_underflow.phpt +++ b/ext/standard/tests/strings/str_decrement_underflow.phpt @@ -23,7 +23,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_decrement(): Argument #1 ($string) cannot be empty +str_decrement(): Argument #1 ($string) must not be empty str_decrement(): Argument #1 ($string) "0" is out of decrement range str_decrement(): Argument #1 ($string) "a" is out of decrement range str_decrement(): Argument #1 ($string) "A" is out of decrement range diff --git a/ext/standard/tests/strings/str_increment_errors.phpt b/ext/standard/tests/strings/str_increment_errors.phpt index 41e4ac10e1078..e06d7e4bba861 100644 --- a/ext/standard/tests/strings/str_increment_errors.phpt +++ b/ext/standard/tests/strings/str_increment_errors.phpt @@ -37,7 +37,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_increment(): Argument #1 ($string) cannot be empty +str_increment(): Argument #1 ($string) must not be empty str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters diff --git a/ext/standard/tests/strings/str_pad.phpt b/ext/standard/tests/strings/str_pad.phpt index c28bb1217a6e4..c7b11e4ac0ce5 100644 --- a/ext/standard/tests/strings/str_pad.phpt +++ b/ext/standard/tests/strings/str_pad.phpt @@ -302,5 +302,5 @@ string(16) "\t\variation\t\t" #### error conditions #### --- empty padding string --- -str_pad(): Argument #3 ($pad_string) cannot be empty +str_pad(): Argument #3 ($pad_string) must not be empty str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH diff --git a/ext/standard/tests/strings/substr_count_basic.phpt b/ext/standard/tests/strings/substr_count_basic.phpt index 3b871ac0da3d8..efb5806d1621b 100644 --- a/ext/standard/tests/strings/substr_count_basic.phpt +++ b/ext/standard/tests/strings/substr_count_basic.phpt @@ -34,8 +34,8 @@ var_dump(substr_count($a, "bca", -200, -50)); ?> --EXPECT-- ***Testing basic operations *** -substr_count(): Argument #2 ($needle) cannot be empty -substr_count(): Argument #2 ($needle) cannot be empty +substr_count(): Argument #2 ($needle) must not be empty +substr_count(): Argument #2 ($needle) must not be empty int(0) int(0) int(0) diff --git a/ext/standard/tests/strings/wordwrap.phpt b/ext/standard/tests/strings/wordwrap.phpt index ff1d1fcbba593..efa12bef18dd6 100644 --- a/ext/standard/tests/strings/wordwrap.phpt +++ b/ext/standard/tests/strings/wordwrap.phpt @@ -53,4 +53,4 @@ bool(true) bool(true) bool(true) bool(true) -wordwrap(): Argument #3 ($break) cannot be empty +wordwrap(): Argument #3 ($break) must not be empty diff --git a/ext/sysvshm/tests/001.phpt b/ext/sysvshm/tests/001.phpt index 00483c2a3cb04..10b258da2d0be 100644 --- a/ext/sysvshm/tests/001.phpt +++ b/ext/sysvshm/tests/001.phpt @@ -35,7 +35,7 @@ var_dump(ftok(__FILE__,"q")); echo "Done\n"; ?> --EXPECTF-- -ftok(): Argument #1 ($filename) cannot be empty +ftok(): Argument #1 ($filename) must not be empty ftok(): Argument #2 ($project_id) must be a single character ftok(): Argument #2 ($project_id) must be a single character diff --git a/ext/tidy/tests/019.phpt b/ext/tidy/tests/019.phpt index 444ecc155a45c..9bf6cf6349a3f 100644 --- a/ext/tidy/tests/019.phpt +++ b/ext/tidy/tests/019.phpt @@ -37,6 +37,6 @@ Warning: tidy_repair_string(): Could not load the Tidy configuration file "" in Warning: tidy_repair_string(): Could not load the Tidy configuration file "1" in %s on line %d Warning: tidy_repair_string(): Could not set encoding "1" in %s on line %d -Path cannot be empty -Path cannot be empty +Path must not be empty +Path must not be empty Done diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 178053f8f6091..528fd8b351c61 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -382,7 +382,7 @@ static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_rea } if (!name_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -467,7 +467,7 @@ static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int t } if (source != NULL && !source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -574,12 +574,12 @@ PHP_METHOD(XMLReader, getAttributeNs) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -655,7 +655,7 @@ PHP_METHOD(XMLReader, moveToAttribute) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -715,12 +715,12 @@ PHP_METHOD(XMLReader, moveToAttributeNs) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -860,7 +860,7 @@ static void xml_reader_from_uri(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry * } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1027,7 +1027,7 @@ PHP_METHOD(XMLReader, setSchema) } if (source != NULL && !source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1132,7 +1132,7 @@ static void xml_reader_from_string(INTERNAL_FUNCTION_PARAMETERS, zend_class_entr } if (!source_len) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/xmlreader/tests/001.phpt b/ext/xmlreader/tests/001.phpt index bcfa02fbc9234..ab84cd0b3a222 100644 --- a/ext/xmlreader/tests/001.phpt +++ b/ext/xmlreader/tests/001.phpt @@ -28,4 +28,4 @@ try { --EXPECT-- books books -XMLReader::XML(): Argument #1 ($source) cannot be empty +XMLReader::XML(): Argument #1 ($source) must not be empty diff --git a/ext/xmlreader/tests/002.phpt b/ext/xmlreader/tests/002.phpt index e33bc0abd55a0..a0f55a2af3b4f 100644 --- a/ext/xmlreader/tests/002.phpt +++ b/ext/xmlreader/tests/002.phpt @@ -36,6 +36,6 @@ unlink($filename); ?> --EXPECT-- -XMLReader::open(): Argument #1 ($uri) cannot be empty +XMLReader::open(): Argument #1 ($uri) must not be empty books books diff --git a/ext/xmlreader/tests/003-get-errors.phpt b/ext/xmlreader/tests/003-get-errors.phpt index 81087f7e253c8..6cb2f20b8d5fe 100644 --- a/ext/xmlreader/tests/003-get-errors.phpt +++ b/ext/xmlreader/tests/003-get-errors.phpt @@ -69,7 +69,7 @@ unlink(__DIR__.'/003-get-errors.xml'); book bool(true) num: 1 -XMLReader::getAttribute(): Argument #1 ($name) cannot be empty +XMLReader::getAttribute(): Argument #1 ($name) must not be empty num: 1 NULL num: 1 diff --git a/ext/xmlreader/tests/003-move-errors.phpt b/ext/xmlreader/tests/003-move-errors.phpt index 89f4b46094432..be36d252c453b 100644 --- a/ext/xmlreader/tests/003-move-errors.phpt +++ b/ext/xmlreader/tests/003-move-errors.phpt @@ -68,7 +68,7 @@ unlink(__DIR__.'/003-move-errors.xml'); book bool(true) num: 1 -XMLReader::moveToAttribute(): Argument #1 ($name) cannot be empty +XMLReader::moveToAttribute(): Argument #1 ($name) must not be empty num: 1 bool(false) num: 1 diff --git a/ext/xmlreader/tests/003.phpt b/ext/xmlreader/tests/003.phpt index 880d8b8edd095..a581d0dea02d1 100644 --- a/ext/xmlreader/tests/003.phpt +++ b/ext/xmlreader/tests/003.phpt @@ -88,4 +88,4 @@ num: 1 idx: 2 bool(false) bool(false) -XMLReader::moveToAttribute(): Argument #1 ($name) cannot be empty +XMLReader::moveToAttribute(): Argument #1 ($name) must not be empty diff --git a/ext/xmlreader/tests/007.phpt b/ext/xmlreader/tests/007.phpt index 7e95bc7926e51..e9705cc5af66c 100644 --- a/ext/xmlreader/tests/007.phpt +++ b/ext/xmlreader/tests/007.phpt @@ -53,4 +53,4 @@ $reader->close(); --EXPECT-- file relaxNG: ok string relaxNG: ok -XMLReader::setRelaxNGSchema(): Argument #1 ($filename) cannot be empty +XMLReader::setRelaxNGSchema(): Argument #1 ($filename) must not be empty diff --git a/ext/xmlreader/tests/015-get-errors.phpt b/ext/xmlreader/tests/015-get-errors.phpt index 5bde0a9b2b4a4..3cf6134df2053 100644 --- a/ext/xmlreader/tests/015-get-errors.phpt +++ b/ext/xmlreader/tests/015-get-errors.phpt @@ -47,5 +47,5 @@ unlink(__DIR__.'/015-get-errors.xml'); ?> --EXPECTF-- Deprecated: XMLReader::getAttributeNs(): Passing null to parameter #2 ($namespace) of type string is deprecated in %s on line %d -XMLReader::getAttributeNs(): Argument #2 ($namespace) cannot be empty +XMLReader::getAttributeNs(): Argument #2 ($namespace) must not be empty ns1:num: 1 diff --git a/ext/xmlreader/tests/015-move-errors.phpt b/ext/xmlreader/tests/015-move-errors.phpt index 14c7cfd83bea3..d885c5a6fe97b 100644 --- a/ext/xmlreader/tests/015-move-errors.phpt +++ b/ext/xmlreader/tests/015-move-errors.phpt @@ -42,4 +42,4 @@ unlink(__DIR__.'/015-move-errors.xml'); ?> --EXPECTF-- Deprecated: XMLReader::moveToAttributeNs(): Passing null to parameter #2 ($namespace) of type string is deprecated in %s on line %d -XMLReader::moveToAttributeNs(): Argument #2 ($namespace) cannot be empty +XMLReader::moveToAttributeNs(): Argument #2 ($namespace) must not be empty diff --git a/ext/xmlreader/tests/setSchema_error.phpt b/ext/xmlreader/tests/setSchema_error.phpt index 1292f0fb052e1..a586c38f55320 100644 --- a/ext/xmlreader/tests/setSchema_error.phpt +++ b/ext/xmlreader/tests/setSchema_error.phpt @@ -37,7 +37,7 @@ var_dump(@$reader->setSchema('schema-bad.xsd')); $reader->close(); ?> --EXPECT-- -XMLReader::setSchema(): Argument #1 ($filename) cannot be empty +XMLReader::setSchema(): Argument #1 ($filename) must not be empty Schema must be set prior to reading Schema must be set prior to reading bool(false) diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 0e7f3d29153c3..2029bcbb12e7e 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -817,7 +817,7 @@ PHP_FUNCTION(xmlwriter_open_uri) } if (source_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -858,7 +858,7 @@ PHP_METHOD(XMLWriter, toUri) ZEND_PARSE_PARAMETERS_END(); if (source_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt index 372dade4dfcd6..3b136a9be2c88 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt @@ -15,4 +15,4 @@ Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 --EXPECT-- -xmlwriter_open_uri(): Argument #1 ($uri) cannot be empty +xmlwriter_open_uri(): Argument #1 ($uri) must not be empty diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index be3c6d4c58189..9fc0af4fcaca4 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -56,7 +56,7 @@ static int le_zip_entry; This is always used for the first argument*/ #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \ if (path_len == 0) { \ - zend_argument_cannot_be_empty_error(1); \ + zend_argument_must_not_be_empty_error(1); \ RETURN_THROWS(); \ } \ if (zip_stat(za, path, flags, &sb) != 0) { \ @@ -417,7 +417,7 @@ static int php_zip_parse_options(HashTable *options, zip_options *opts) } if (Z_STRLEN_P(option) == 0) { - zend_value_error("Option \"remove_path\" cannot be empty"); + zend_value_error("Option \"remove_path\" must not be empty"); return -1; } @@ -437,7 +437,7 @@ static int php_zip_parse_options(HashTable *options, zip_options *opts) } if (Z_STRLEN_P(option) == 0) { - zend_value_error("Option \"add_path\" cannot be empty"); + zend_value_error("Option \"add_path\" must not be empty"); return -1; } @@ -1184,7 +1184,7 @@ PHP_FUNCTION(zip_open) } if (ZSTR_LEN(filename) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1466,7 +1466,7 @@ PHP_METHOD(ZipArchive, open) ze_obj = Z_ZIP_P(self); if (ZSTR_LEN(filename) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1753,7 +1753,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* } if (ZSTR_LEN(pattern) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (options && zend_hash_num_elements(options) > 0 && (php_zip_parse_options(options, &opts) < 0)) { @@ -1871,7 +1871,7 @@ PHP_METHOD(ZipArchive, addFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1904,7 +1904,7 @@ PHP_METHOD(ZipArchive, replaceFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2168,7 +2168,7 @@ PHP_METHOD(ZipArchive, setCommentName) } if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2235,7 +2235,7 @@ PHP_METHOD(ZipArchive, setExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2296,7 +2296,7 @@ PHP_METHOD(ZipArchive, getExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2363,7 +2363,7 @@ PHP_METHOD(ZipArchive, setEncryptionName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2424,7 +2424,7 @@ PHP_METHOD(ZipArchive, getCommentName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2480,7 +2480,7 @@ PHP_METHOD(ZipArchive, setCompressionName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2540,7 +2540,7 @@ PHP_METHOD(ZipArchive, setMtimeName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_cannot_be_empty_error(1); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2654,7 +2654,7 @@ PHP_METHOD(ZipArchive, renameIndex) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -2682,7 +2682,7 @@ PHP_METHOD(ZipArchive, renameName) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_cannot_be_empty_error(2); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/zip/tests/oo_getcomment.phpt b/ext/zip/tests/oo_getcomment.phpt index 0257f99a577f3..a43c5ae38a53b 100644 --- a/ext/zip/tests/oo_getcomment.phpt +++ b/ext/zip/tests/oo_getcomment.phpt @@ -30,4 +30,4 @@ $zip->close(); Zip archive comment string(11) "foo comment" string(11) "foo comment" -ZipArchive::getCommentName(): Argument #1 ($name) cannot be empty +ZipArchive::getCommentName(): Argument #1 ($name) must not be empty diff --git a/ext/zip/tests/oo_getexternalattributesname_error.phpt b/ext/zip/tests/oo_getexternalattributesname_error.phpt index 13f99edabf7c0..175fdc4b7bb86 100644 --- a/ext/zip/tests/oo_getexternalattributesname_error.phpt +++ b/ext/zip/tests/oo_getexternalattributesname_error.phpt @@ -20,4 +20,4 @@ try { } ?> --EXPECT-- -ZipArchive::getExternalAttributesName(): Argument #1 ($name) cannot be empty +ZipArchive::getExternalAttributesName(): Argument #1 ($name) must not be empty diff --git a/ext/zip/tests/oo_open.phpt b/ext/zip/tests/oo_open.phpt index 058e68f9a863f..44fa46a9a6ea5 100644 --- a/ext/zip/tests/oo_open.phpt +++ b/ext/zip/tests/oo_open.phpt @@ -42,5 +42,5 @@ if ($zip->status == ZIPARCHIVE::ER_OK) { --EXPECT-- ER_OPEN: ok create: ok -ZipArchive::open(): Argument #1 ($filename) cannot be empty +ZipArchive::open(): Argument #1 ($filename) must not be empty OK diff --git a/ext/zip/tests/zip_open_error.phpt b/ext/zip/tests/zip_open_error.phpt index 567e2cb2ff7bb..2e43ac29713b4 100644 --- a/ext/zip/tests/zip_open_error.phpt +++ b/ext/zip/tests/zip_open_error.phpt @@ -21,7 +21,7 @@ echo is_resource($zip) ? "OK" : "Failure"; --EXPECTF-- Test case 1: Deprecated: Function zip_open() is deprecated since 8.0, use ZipArchive::open() instead in %s on line %d -zip_open(): Argument #1 ($filename) cannot be empty +zip_open(): Argument #1 ($filename) must not be empty Test case 2: Deprecated: Function zip_open() is deprecated since 8.0, use ZipArchive::open() instead in %s on line %d diff --git a/main/streams/streams.c b/main/streams/streams.c index 0b3e5cc06cb9e..f3fb5e3cda544 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2194,7 +2194,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (!path || !*path) { - zend_value_error("Path cannot be empty"); + zend_value_error("Path must not be empty"); return NULL; } diff --git a/php.ini-development b/php.ini-development index 6f6624b1dd26b..3fd5fd578ee04 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1605,7 +1605,7 @@ zend.assertions = 1 ; With mbstring support this will automatically be converted into the encoding ; given by corresponding encode setting. When empty mbstring.internal_encoding ; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. +; intel byte order. A decode setting must not be empty. ; https://php.net/exif.encode-unicode ;exif.encode_unicode = ISO-8859-15 diff --git a/php.ini-production b/php.ini-production index fa1356e2c24a5..41f1578a2e786 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1607,7 +1607,7 @@ zend.assertions = -1 ; With mbstring support this will automatically be converted into the encoding ; given by corresponding encode setting. When empty mbstring.internal_encoding ; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. +; intel byte order. A decode setting must not be empty. ; https://php.net/exif.encode-unicode ;exif.encode_unicode = ISO-8859-15 From 6b809c8890f983c587f62b8bbf6b7470341f05b3 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 21 Aug 2024 22:50:11 +0200 Subject: [PATCH 135/280] Autotools: Fix stack direction check (#15528) On Solaris 10 and GCC 4.9 check failed with error in config.log: error: missing binary operator before token "(" The __has_builtin must be checked in its own `#ifdef/defined` line above the `#if __has_builtin(....` usage. --- Zend/Zend.m4 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index b7b44fb140872..df75b4c9e9942 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -223,11 +223,17 @@ AC_DEFUN([ZEND_CHECK_STACK_DIRECTION], [AC_RUN_IFELSE([AC_LANG_SOURCE([dnl #include +#ifdef __has_builtin +# if __has_builtin(__builtin_frame_address) +# define builtin_frame_address __builtin_frame_address(0) +# endif +#endif + int (*volatile f)(uintptr_t); int stack_grows_downwards(uintptr_t arg) { -#if defined(__has_builtin) && __has_builtin(__builtin_frame_address) - uintptr_t addr = (uintptr_t)__builtin_frame_address(0); +#ifdef builtin_frame_address + uintptr_t addr = (uintptr_t)builtin_frame_address; #else int local; uintptr_t addr = (uintptr_t)&local; @@ -237,8 +243,8 @@ int stack_grows_downwards(uintptr_t arg) { } int main(void) { -#if defined(__has_builtin) && __has_builtin(__builtin_frame_address) - uintptr_t addr = (uintptr_t)__builtin_frame_address(0); +#ifdef builtin_frame_address + uintptr_t addr = (uintptr_t)builtin_frame_address; #else int local; uintptr_t addr = (uintptr_t)&local; From ff69f334f1143f3bcaf116c2abec94fed0c62c5b Mon Sep 17 00:00:00 2001 From: Jorg Adam Sowa Date: Thu, 22 Aug 2024 02:29:40 +0200 Subject: [PATCH 136/280] ext/session: Warn when providing invalid values for session.gc_probability and session.gc_divisor --- NEWS | 4 ++ ext/session/session.c | 42 +++++++++++- .../tests/session_gc_probability_ini.phpt | 65 +++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 ext/session/tests/session_gc_probability_ini.phpt diff --git a/NEWS b/NEWS index 24a50d2ac795b..a94fef476a74c 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,10 @@ PHP NEWS . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) +- Session: + . Emit warnings for non-positive values of session.gc_divisor and negative values + of session.gc_probability. (Jorg Sowa) + - Standard: . The "allowed_classes" option for unserialize() now throws TypeErrors and ValueErrors if it is not an array of class names. (Girgias) diff --git a/ext/session/session.c b/ext/session/session.c index 32de7c36d7813..6c954a9327831 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -789,6 +789,44 @@ static PHP_INI_MH(OnUpdateSidBits) /* {{{ */ } /* }}} */ +static PHP_INI_MH(OnUpdateSessionGcProbability) /* {{{ */ +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + + if (tmp < 0) { + php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); + return FAILURE; + } + + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = tmp; + + return SUCCESS; +} +/* }}} */ + +static PHP_INI_MH(OnUpdateSessionDivisor) /* {{{ */ +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + + if (tmp <= 0) { + php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); + return FAILURE; + } + + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = tmp; + + return SUCCESS; +} +/* }}} */ + static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */ { int tmp = ZEND_ATOL(ZSTR_VAL(new_value)); @@ -814,8 +852,8 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionLong, gc_probability, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionLong, gc_divisor, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor,gc_divisor, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime,cookie_lifetime, php_ps_globals, ps_globals) diff --git a/ext/session/tests/session_gc_probability_ini.phpt b/ext/session/tests/session_gc_probability_ini.phpt new file mode 100644 index 0000000000000..6d6f7519ba41a --- /dev/null +++ b/ext/session/tests/session_gc_probability_ini.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test session.gc_probability and session.gc_divisor settings for invalid values +--INI-- +session.gc_maxlifetime=1 +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + -1, + 'gc_divisor' => -1 + ], + [ + 'gc_probability' => -1, + 'gc_divisor' => 1 + ], + [ + 'gc_probability' => 1, + 'gc_divisor' => -1 + ], + [ + 'gc_probability' => 1, + 'gc_divisor' => 0 + ], +]; + +ob_start(); +foreach($gc_settings as $gc_setting) { +try { + session_start($gc_setting); + session_write_close(); + } catch (Throwable $e) { + echo $e::class, ': '. $e->getMessage(), "\n"; + } +} +ob_end_flush(); +?> +Done +--EXPECTF-- +Warning: session_start(): session.gc_probability must be greater than or equal to 0 in %s on line %d + +Warning: session_start(): Setting option "gc_probability" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d + +Warning: session_start(): session.gc_probability must be greater than or equal to 0 in %s on line %d + +Warning: session_start(): Setting option "gc_probability" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d +Done From 450740cbb600fb1b26f2a048d312bbf7fb5a9a24 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 22 Aug 2024 11:48:46 +0200 Subject: [PATCH 137/280] [skip ci] Fix typos in XFAIL reasons --- ext/ffi/tests/gh14286_2.phpt | 2 +- ext/intl/tests/dateformat_format_variant3.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ffi/tests/gh14286_2.phpt b/ext/ffi/tests/gh14286_2.phpt index 683929780c053..c3fc0b242a476 100644 --- a/ext/ffi/tests/gh14286_2.phpt +++ b/ext/ffi/tests/gh14286_2.phpt @@ -4,7 +4,7 @@ GH-14286 (ffi enum type (when enum has no name) make memory leak) ffi --SKIPIF-- --INI-- ffi.enable=1 diff --git a/ext/intl/tests/dateformat_format_variant3.phpt b/ext/intl/tests/dateformat_format_variant3.phpt index 4986c2ff37af3..86582d39229ba 100644 --- a/ext/intl/tests/dateformat_format_variant3.phpt +++ b/ext/intl/tests/dateformat_format_variant3.phpt @@ -3,7 +3,7 @@ datefmt_format_code() --EXTENSIONS-- intl --XFAIL-- -This test assumes wrong data wrt to PDT. It is also too big and needs splitting up. +This test assumes wrong data wrt PDT. It is also too big and needs splitting up. --SKIPIF-- = 52.1'); ?> --FILE-- From 15ea82da2b858cd57376098640467b5c02615cfa Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 22 Aug 2024 12:34:57 +0100 Subject: [PATCH 138/280] ext/mysqli: Minor clean-up (#15526) It is likely that more functions should have their return type changed to `enum_func_status` and have the return value checked against `PASS`/`FAIL` rather than assuming the inverse of boolean logic. --- ext/mysqli/mysqli_api.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 6017a2b9ed9ea..1d5dbc26deee7 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -72,10 +72,8 @@ PHP_FUNCTION(mysqli_autocommit) /* }}} */ /* {{{ mysqli_stmt_bind_param_do_bind */ -static -int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *args, const char * const types, unsigned int num_extra_args) +static enum_func_status mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, uint32_t num_vars, zval *args, const char * const types, unsigned int arg_num) { - unsigned int i; MYSQLND_PARAM_BIND *params; enum_func_status ret = FAIL; @@ -87,7 +85,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a if (!params) { goto end; } - for (i = 0; i < num_vars; i++) { + for (uint32_t i = 0; i < num_vars; i++) { uint8_t type; switch (types[i]) { case 'd': /* Double */ @@ -107,7 +105,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a type = MYSQL_TYPE_VAR_STRING; break; default: - zend_argument_value_error(num_extra_args, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers"); + zend_argument_value_error(arg_num, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers"); ret = FAIL; mysqlnd_stmt_free_param_bind(stmt->stmt, params); goto end; @@ -126,7 +124,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a PHP_FUNCTION(mysqli_stmt_bind_param) { zval *args; - int argc; + uint32_t argc; MY_STMT *stmt; zval *mysql_stmt; char *types; @@ -154,19 +152,17 @@ PHP_FUNCTION(mysqli_stmt_bind_param) RETURN_THROWS(); } - RETVAL_BOOL(!mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, hasThis() ? 1 : 2)); + RETVAL_BOOL(mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, ERROR_ARG_POS(2)) == PASS); MYSQLI_REPORT_STMT_ERROR(stmt->stmt); } /* }}} */ /* {{{ mysqli_stmt_bind_result_do_bind */ -static int -mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc) +static enum_func_status mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, uint32_t argc) { - unsigned int i; MYSQLND_RESULT_BIND *params = mysqlnd_stmt_alloc_result_bind(stmt->stmt); if (params) { - for (i = 0; i < argc; i++) { + for (uint32_t i = 0; i < argc; i++) { ZVAL_COPY_VALUE(¶ms[i].zv, &args[i]); } return mysqlnd_stmt_bind_result(stmt->stmt, params); @@ -179,8 +175,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc) PHP_FUNCTION(mysqli_stmt_bind_result) { zval *args; - int argc; - zend_ulong rc; + uint32_t argc; MY_STMT *stmt; zval *mysql_stmt; @@ -190,13 +185,13 @@ PHP_FUNCTION(mysqli_stmt_bind_result) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); - if ((uint32_t)argc != mysql_stmt_field_count(stmt->stmt)) { + if (argc != mysql_stmt_field_count(stmt->stmt)) { zend_argument_count_error("Number of bind variables doesn't match number of fields in prepared statement"); RETURN_THROWS(); } - rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc); - RETURN_BOOL(!rc); + enum_func_status rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc); + RETURN_BOOL(rc == PASS); } /* }}} */ @@ -207,21 +202,16 @@ PHP_FUNCTION(mysqli_change_user) zval *mysql_link = NULL; char *user, *password, *dbname; size_t user_len, password_len, dbname_len; - zend_ulong rc; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osss!", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len); + enum_func_status rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len); MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - if (rc) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(rc == PASS); } /* }}} */ From 35fbb0061d92f41ee028e18ac99b28fffa929e7f Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 22 Aug 2024 12:48:28 +0100 Subject: [PATCH 139/280] main/network: Use more appropriate types (#15511) * main/network: Use more appropriate types And check directly against 0 for success for functions not returning a zend_result * Remove redundant declaration in file.h Not sure why it even is here --- ext/standard/file.h | 1 - main/network.c | 16 ++++++++-------- main/php_network.h | 8 ++++---- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ext/standard/file.h b/ext/standard/file.h index ec5f41c52ad36..eead935848877 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -37,7 +37,6 @@ PHPAPI PHP_FUNCTION(fpassthru); PHP_MINIT_FUNCTION(user_streams); PHPAPI int php_le_stream_context(void); -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block); PHPAPI zend_result php_copy_file(const char *src, const char *dest); PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags); PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx); diff --git a/main/network.c b/main/network.c index f582218d1a1a7..bf34043362dab 100644 --- a/main/network.c +++ b/main/network.c @@ -499,11 +499,11 @@ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned po } /* }}} */ -PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_long addrlen, struct sockaddr *sa, socklen_t *sl) +PHPAPI zend_result php_network_parse_network_address_with_port(const char *addr, size_t addrlen, struct sockaddr *sa, socklen_t *sl) { char *colon; char *tmp; - int ret = FAILURE; + zend_result ret = FAILURE; short port; struct sockaddr_in *in4 = (struct sockaddr_in*)sa; struct sockaddr **psal; @@ -843,7 +843,7 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short struct sockaddr_in6 in6; #endif } local_address = {0}; - int local_address_len = 0; + size_t local_address_len = 0; if (sa->sa_family == AF_INET) { if (inet_pton(AF_INET, bindto, &local_address.in4.sin_addr) == 1) { @@ -974,7 +974,7 @@ PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short /* {{{ php_sockaddr_size * Returns the size of struct sockaddr_xx for the family */ -PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr) +PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr) { switch (((struct sockaddr *)addr)->sa_family) { case AF_INET: @@ -1099,9 +1099,9 @@ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short p return stream; } -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block) +PHPAPI zend_result php_set_sock_blocking(php_socket_t socketd, bool block) { - int ret = SUCCESS; + zend_result ret = SUCCESS; #ifdef PHP_WIN32 u_long flags; @@ -1253,7 +1253,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); } - if (res != SUCCESS) { + if (res != 0) { return NULL; } @@ -1295,7 +1295,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf } memset((void *)(*tmphstbuf),0,*hstbuflen); - if (SUCCESS != gethostbyname_r(host,hostbuf,(struct hostent_data *)*tmphstbuf)) { + if (0 != gethostbyname_r(host,hostbuf,(struct hostent_data *)*tmphstbuf)) { return NULL; } diff --git a/main/php_network.h b/main/php_network.h index a31bc57b76aee..06da95dd68ce6 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -306,7 +306,7 @@ PHPAPI int php_network_get_peer_name(php_socket_t sock, ); PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port); -PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr); +PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr); END_EXTERN_C() struct _php_netstream_data_t { @@ -336,12 +336,12 @@ PHPAPI void php_network_populate_name_from_sockaddr( socklen_t *addrlen ); -PHPAPI int php_network_parse_network_address_with_port(const char *addr, - zend_long addrlen, struct sockaddr *sa, socklen_t *sl); +PHPAPI zend_result php_network_parse_network_address_with_port(const char *addr, + size_t addrlen, struct sockaddr *sa, socklen_t *sl); PHPAPI struct hostent* php_network_gethostbyname(const char *name); -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block); +PHPAPI zend_result php_set_sock_blocking(php_socket_t socketd, bool block); END_EXTERN_C() #define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC) From 6a51062c857a7635e92a444f81e80056f43eaaac Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 22 Aug 2024 14:56:32 +0200 Subject: [PATCH 140/280] Drop unused, but confusing macro definition (GH-15541) `PHP7DLLTS_EXPORTS` is not used throughout php-src, and it's unlikely that it is used by any extension, especially since it still refers to PHP 7. The symbol had been introduced in 2014[1], but is not even used in latest PHP-7.4; probably it was just supposed to be used, or part of phpng. [1] Since CI already ran for the PR, we can now [skip ci]. --- win32/build/confutils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 47fca332a34bc..95a4e5ce3c136 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3241,7 +3241,7 @@ function toolset_setup_common_cflags() var envCFLAGS = WshShell.Environment("PROCESS").Item("CFLAGS"); // CFLAGS for building the PHP dll - DEFINE("CFLAGS_PHP", "/D _USRDLL /D PHP7DLLTS_EXPORTS /D PHP_EXPORTS \ + DEFINE("CFLAGS_PHP", "/D _USRDLL /D PHP_EXPORTS \ /D LIBZEND_EXPORTS /D TSRM_EXPORTS /D SAPI_EXPORTS /D WINVER=" + WINVER); DEFINE('CFLAGS_PHP_OBJ', '$(CFLAGS_PHP) $(STATIC_EXT_CFLAGS)'); From e7874f208959cbbfb635ec659291e08e49b091a0 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 22 Aug 2024 16:26:28 +0200 Subject: [PATCH 141/280] Autotools: Move Zend/zend_config.h to AC_CONFIG_COMMANDS (#15538) Instead of creating Zend/zend_config.h header file in an initialization argument of "default" commands, this creates it in its own wrapper when config.status is called. --- configure.ac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 2ac4cbc08438e..0221a3475fa89 100644 --- a/configure.ac +++ b/configure.ac @@ -1796,6 +1796,12 @@ AC_CONFIG_FILES([ AC_CONFIG_COMMANDS_PRE([PHP_PATCH_CONFIG_HEADERS([main/php_config.h.in])]) +AC_CONFIG_COMMANDS([Zend/zend_config.h], [ +cat >Zend/zend_config.h < +FEO +]) + AC_CONFIG_COMMANDS([main/internal_functions.c], [], [ AWK="$AWK" $SHELL $srcdir/build/genif.sh \ $srcdir/main/internal_functions.c.in \ @@ -1808,7 +1814,7 @@ AC_CONFIG_COMMANDS([main/internal_functions_cli.c], [], [ "$EXT_CLI_STATIC" > main/internal_functions_cli.c ]) -AC_CONFIG_COMMANDS([default],[ +AC_CONFIG_COMMANDS([default], [ cat <Zend/zend_config.h < -FEO ]) AC_OUTPUT From 4e193b41138c4bbf8a843faf62583189588c8cb9 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 22 Aug 2024 16:26:48 +0200 Subject: [PATCH 142/280] Autotools: Move abs_srcdir and abs_builddir to init macro (#15537) This syncs the abs_srcdir and abs_builddir variables assignments between the php-src build and phpize. The `&&` was picked over `;` as it is more rigorous - the pwd command would fail if cd fails for some reason. --- build/php.m4 | 3 +++ configure.ac | 3 --- scripts/phpize.m4 | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/build/php.m4 b/build/php.m4 index da316944f3e2a..8eadfeb509905 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -142,6 +142,9 @@ AS_VAR_IF([CFLAGS],, [auto_cflags=1]) dnl Required programs. PHP_PROG_AWK +abs_srcdir=$(cd $srcdir && pwd) +abs_builddir=$(pwd) + dnl Run at the end of the configuration, before creating the config.status. AC_CONFIG_COMMANDS_PRE( [dnl Directory for storing shared objects of extensions. diff --git a/configure.ac b/configure.ac index 0221a3475fa89..54d26df6336d0 100644 --- a/configure.ac +++ b/configure.ac @@ -100,9 +100,6 @@ dnl ---------------------------------------------------------------------------- PHP_INIT_BUILD_SYSTEM -abs_srcdir=`(cd $srcdir; pwd)` -abs_builddir=`pwd` - dnl Because `make install` is often performed by the superuser, we create the dnl libs subdirectory as the user who configures PHP. Otherwise, the current dnl user will not be able to delete libs or the contents of libs. diff --git a/scripts/phpize.m4 b/scripts/phpize.m4 index a4d71b0e33cf3..09adfa787b54c 100644 --- a/scripts/phpize.m4 +++ b/scripts/phpize.m4 @@ -28,9 +28,6 @@ AC_DEFUN([PHP_ALWAYS_SHARED],[ PHP_INIT_BUILD_SYSTEM -abs_srcdir=`(cd $srcdir && pwd)` -abs_builddir=`pwd` - PKG_PROG_PKG_CONFIG AC_PROG_CC([cc gcc]) PHP_DETECT_ICC From 1b3c204033cc8224ce2d5ecf0dc767badaee6d37 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 22 Aug 2024 17:30:08 +0200 Subject: [PATCH 143/280] Autotools: Add min-version argument to PHP_PROG_PHP macro (#15477) This makes a bit simpler to use this macro by optionally passing the required minimum PHP version. If version is not passed it falls back to 7.4 as before. Minimum version also added to configure.ac. --- UPGRADING.INTERNALS | 2 ++ build/php.m4 | 42 ++++++++++++++++++++---------------------- configure.ac | 3 ++- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index fe4fd258531a5..a23cdcf401c9a 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -181,6 +181,8 @@ PHP 8.4 INTERNALS UPGRADE NOTES anymore. - M4 macro PHP_SETUP_ICONV doesn't define the HAVE_ICONV symbol anymore. - M4 macro PHP_OUTPUT is obsolete (use AC_CONFIG_FILES). + - M4 macro PHP_PROG_SETUP now accepts an argument to set the minimum required + PHP version during the build. - TSRM/tsrm.m4 file and its TSRM_CHECK_PTHREADS M4 macro have been removed. - Added pkg-config support to find libpq for the pdo_pgsql and pgsql extensions. The libpq paths can be customized with the PGSQL_CFLAGS and diff --git a/build/php.m4 b/build/php.m4 index 8eadfeb509905..2d199d5d56c3c 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -1793,28 +1793,26 @@ AC_DEFUN([PHP_PROG_RE2C],[ PHP_SUBST([RE2C_FLAGS]) ]) -AC_DEFUN([PHP_PROG_PHP],[ - AC_CHECK_PROG([PHP], [php], [php]) - - if test -n "$PHP"; then - AC_MSG_CHECKING([for php version]) - php_version=$($PHP -v | head -n1 | cut -d ' ' -f 2 | cut -d '-' -f 1) - if test -z "$php_version"; then - php_version=0.0.0 - fi - ac_IFS=$IFS; IFS="." - set $php_version - IFS=$ac_IFS - php_version_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - dnl Minimum supported version for gen_stub.php is PHP 7.4. - if test "$php_version_num" -lt 70400; then - AC_MSG_RESULT([$php_version (too old)]) - unset PHP - else - AC_MSG_RESULT([$php_version (ok)]) - fi - fi - PHP_SUBST([PHP]) +dnl +dnl PHP_PROG_PHP([min-version]) +dnl +dnl Find PHP command-line interface SAPI on the system and check if version is +dnl greater or equal to "min-version". If suitable version is found, the PHP +dnl variable is set and substituted to a Makefile variable. Used for generating +dnl files and running PHP utilities during the build. +dnl +AC_DEFUN([PHP_PROG_PHP], +[m4_if([$1],, [php_required_version=7.4], [php_required_version=$1]) +AC_CHECK_PROG([PHP], [php], [php]) +AS_VAR_IF([PHP],,, [ +AC_MSG_CHECKING([for php version]) +php_version=$($PHP -v | head -n1 | cut -d ' ' -f 2) +AS_VERSION_COMPARE([$php_version], [$php_required_version], [unset PHP]) +AS_VAR_IF([PHP],, + [AC_MSG_RESULT([$php_version (too old, install $php_required_version or later)])], + [AC_MSG_RESULT([$php_version (ok)])]) +]) +PHP_SUBST([PHP]) ]) dnl ---------------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 54d26df6336d0..904786aca432d 100644 --- a/configure.ac +++ b/configure.ac @@ -148,7 +148,8 @@ PHP_RUNPATH_SWITCH dnl Checks for some support/generator progs. PHP_PROG_BISON([3.0.0]) PHP_PROG_RE2C([1.0.3], [--no-generation-date]) -PHP_PROG_PHP() +dnl Find installed PHP. Minimum supported version for gen_stub.php is PHP 7.4. +PHP_PROG_PHP([7.4]) PHP_ARG_ENABLE([re2c-cgoto], [whether to enable computed goto extension with re2c], From c79e723725083b53002e06c44c7f9b271146385e Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 22 Aug 2024 17:39:03 +0200 Subject: [PATCH 144/280] Autotools: Check re2c version with AS_VERSION_COMPARE (#15465) This simplifies the version check a bit. --- build/php.m4 | 53 +++++++++++++++------------------------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/build/php.m4 b/build/php.m4 index 2d199d5d56c3c..4c4ba44708b7d 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -1739,54 +1739,31 @@ dnl AC_DEFUN([PHP_PROG_RE2C],[ AC_CHECK_PROG([RE2C], [re2c], [re2c]) - ifelse($1,,php_re2c_required_version='',php_re2c_required_version="$1") - - if test -n "$RE2C"; then + php_re2c_check= + AS_VAR_IF([RE2C],,, [ AC_MSG_CHECKING([for re2c version]) php_re2c_version=$($RE2C --version | cut -d ' ' -f 2 2>/dev/null) - if test -z "$php_re2c_version"; then - php_re2c_version=0.0.0 - fi - ac_IFS=$IFS; IFS="." - set $php_re2c_version - IFS=$ac_IFS - php_re2c_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - php_re2c_check=ok - if test -z "$php_re2c_required_version" && test -z "$php_re2c_num"; then - php_re2c_check=invalid - elif test -n "$php_re2c_required_version"; then - ac_IFS=$IFS; IFS="." - set $php_re2c_required_version - IFS=$ac_IFS - php_re2c_required_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - php_re2c_required_version="$php_re2c_required_version or later" - - if test -z "$php_re2c_num" || test "$php_re2c_num" -lt "$php_re2c_required_num"; then - php_re2c_check=invalid - fi - fi + php_re2c_check=ok + AS_VERSION_COMPARE([$php_re2c_version], [$1], + [php_re2c_check=invalid]) - if test "$php_re2c_check" != "invalid"; then - AC_MSG_RESULT([$php_re2c_version (ok)]) - else - AC_MSG_RESULT([$php_re2c_version (too old)]) - fi - fi + AS_VAR_IF([php_re2c_check], [invalid], + [AC_MSG_RESULT([$php_re2c_version (too old)])], + [AC_MSG_RESULT([$php_re2c_version (ok)])]) + ]) - case $php_re2c_check in - ""|invalid[)] - if test ! -f "$abs_srcdir/Zend/zend_language_scanner.c"; then + AS_CASE([$php_re2c_check], + [""|invalid], [ + AS_IF([test ! -f "$abs_srcdir/Zend/zend_language_scanner.c"], [ AC_MSG_ERROR(m4_text_wrap([ - re2c $php_re2c_required_version or newer is required to generate PHP - lexers. + re2c $1 or newer is required to generate PHP lexers. ])) - fi + ]) RE2C="exit 0;" - ;; - esac + ]) PHP_SUBST([RE2C]) AS_VAR_SET([RE2C_FLAGS], m4_normalize(["$2"])) From 0c73553959703a90c623d6102b1d55eb7e4b281c Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Fri, 23 Aug 2024 02:31:06 +0900 Subject: [PATCH 145/280] Update extension skeleton .gitignore (#15542) [ci skip] --- ext/skeleton/.gitignore.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/skeleton/.gitignore.in b/ext/skeleton/.gitignore.in index ae434fef9765c..52fc9c864cf0c 100644 --- a/ext/skeleton/.gitignore.in +++ b/ext/skeleton/.gitignore.in @@ -1,3 +1,4 @@ +*.dep *.lo *.la .libs @@ -39,3 +40,4 @@ tests/**/*.sh tests/**/*.db tests/**/*.mem tmp-php.ini +*~ From f952263bcd699f1067b568f2e17b2f5936efd9a1 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Thu, 22 Aug 2024 20:26:44 +0200 Subject: [PATCH 146/280] Fix Solaris 10 build: missing libproc.h (#15525) The libproc.h header file was added on Solaris as of 11.4. * Also add guard check to the entire function * When libproc.h isn't available also sys/procfs.h is redundant * Move the out of the guard * Exclude more stuff from Solaris 10 --- Zend/Zend.m4 | 5 ++++- Zend/zend_call_stack.c | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index df75b4c9e9942..47ea9c831d524 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -133,7 +133,10 @@ dnl AC_DEFUN([ZEND_INIT], [dnl AC_REQUIRE([AC_PROG_CC]) -AC_CHECK_HEADERS([cpuid.h]) +AC_CHECK_HEADERS(m4_normalize([ + cpuid.h + libproc.h +])) dnl Check for library functions. AC_CHECK_FUNCS(m4_normalize([ diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index f12323d0d9cd3..a2887d164f362 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -64,10 +64,12 @@ typedef int boolean_t; #include #endif #ifdef __sun -#define _STRUCTURED_PROC 1 -#include -#include -#include +# include +# ifdef HAVE_LIBPROC_H +# define _STRUCTURED_PROC 1 +# include +# include +# endif #include #endif @@ -699,6 +701,7 @@ static bool zend_call_stack_get_solaris_pthread(zend_call_stack *stack) return true; } +#ifdef HAVE_LIBPROC_H static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack) { char buffer[4096]; @@ -771,12 +774,15 @@ static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack) close(fd); return r; } +#endif static bool zend_call_stack_get_solaris(zend_call_stack *stack) { +#ifdef HAVE_LIBPROC_H if (_lwp_self() == 1) { return zend_call_stack_get_solaris_proc_maps(stack); } +#endif return zend_call_stack_get_solaris_pthread(stack); } #else From 70c5e366f69c7af5c1d62e435e7c52ec8428c8de Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 22 Aug 2024 23:41:34 +0100 Subject: [PATCH 147/280] Revert fix for GH-14930: truncating readdir output (#15533) --- NEWS | 2 ++ ext/standard/tests/streams/gh14930.phpt | 2 ++ main/php_streams.h | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index 58f0484fac960..b3cd233aed7d7 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ PHP NEWS . Fixed bug GH-15028 (Memory leak in ext/phar/stream.c). (nielsdos) . Fixed bug GH-15034 (Integer overflow on stream_notification_callback byte_max parameter with files bigger than 2GB). (nielsdos) + . Reverted fix for GH-14930 (Custom stream wrapper dir_readdir output + truncated to 255 characters). (Jakub Zelenka) - Tidy: . Fix memory leaks in ext/tidy basedir restriction code. (nielsdos) diff --git a/ext/standard/tests/streams/gh14930.phpt b/ext/standard/tests/streams/gh14930.phpt index 7e034a81235a7..54a187332ab03 100644 --- a/ext/standard/tests/streams/gh14930.phpt +++ b/ext/standard/tests/streams/gh14930.phpt @@ -1,5 +1,7 @@ --TEST-- GH-14930: Custom stream wrapper dir_readdir output truncated to 255 characters in PHP 8.3 +--XFAIL-- +Fix is an ABI break so reverted from 8.3 --FILE-- Date: Thu, 22 Aug 2024 23:50:11 +0100 Subject: [PATCH 148/280] [skip ci] Update NEWS with info about GH-14930 fix which is only in master now --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index a94fef476a74c..e82a54e150b2c 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,10 @@ PHP NEWS . The "allowed_classes" option for unserialize() now throws TypeErrors and ValueErrors if it is not an array of class names. (Girgias) +- Streams: + . Fixed bug GH-14930 (Custom stream wrapper dir_readdir output truncated to + 255 characters in PHP 8.3). (Joe Cai) + 15 Aug 2024, PHP 8.4.0beta3 From 793f6321e792da8c1d948ba411b6b70f5129f63d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 23 Aug 2024 08:56:06 +0200 Subject: [PATCH 149/280] Fix NULL pointer dereference with NULL content in legacy nodes (#15546) --- ext/dom/html5_serializer.c | 8 +++++++- .../html/serializer/legacy_null_content.phpt | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ext/dom/tests/modern/html/serializer/legacy_null_content.phpt diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c index c87d3480a5f3c..3970fb059c1c5 100644 --- a/ext/dom/html5_serializer.c +++ b/ext/dom/html5_serializer.c @@ -42,7 +42,9 @@ static zend_result dom_html5_serialize_doctype(dom_html5_serialize_context *ctx, static zend_result dom_html5_serialize_comment(dom_html5_serialize_context *ctx, const xmlNode *node) { TRY(ctx->write_string_len(ctx->application_data, "", strlen("-->")); } @@ -131,6 +133,10 @@ static zend_result dom_html5_escape_string(dom_html5_serialize_context *ctx, con static zend_result dom_html5_serialize_text_node(dom_html5_serialize_context *ctx, const xmlNode *node) { + if (!node->content) { + return SUCCESS; + } + if (node->parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(node->parent, php_dom_ns_is_html_magic_token)) { const xmlNode *parent = node->parent; size_t name_length = strlen((const char *) parent->name); diff --git a/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt b/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt new file mode 100644 index 0000000000000..eaedfbe23232c --- /dev/null +++ b/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt @@ -0,0 +1,20 @@ +--TEST-- +Serialize legacy nodes with NULL content +--EXTENSIONS-- +dom +--FILE-- +appendChild($dom->createElement('html')); + +$root->appendChild($dom->importLegacyNode(new DOMText)); +$root->appendChild($dom->importLegacyNode(new DOMComment)); +$root->appendChild($dom->importLegacyNode(new DOMProcessingInstruction('target'))); +$root->appendChild($dom->importLegacyNode(new DOMCdataSection(''))); + +echo $dom->saveHTML(), "\n"; +echo $dom->documentElement->innerHTML, "\n"; +?> +--EXPECT-- + + From 7e45e57d8f85f8d1fa2521028f394da30268187d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 23 Aug 2024 10:39:11 +0200 Subject: [PATCH 150/280] Suppress deprecation notices when ext/dom properties are accessed by the get_debug_info handler (#15530) --- ext/dom/document.c | 10 ++-------- ext/dom/entity.c | 15 +++------------ ext/dom/php_dom.c | 20 +++++++++++++++++++- ext/dom/php_dom.h | 17 +++++++++++++++++ ext/dom/tests/domobject_debug_handler.phpt | 4 ---- 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index 2dc6fc9c49beb..9650d0902909a 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -107,10 +107,7 @@ zend_result dom_document_encoding_read(dom_object *obj, zval *retval) zend_result dom_document_actual_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMDocument::$actualEncoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMDocument::$actualEncoding is deprecated"); return dom_document_encoding_read(obj, retval); } @@ -419,10 +416,7 @@ Since: DOM Level 3 */ zend_result dom_document_config_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMDocument::$config is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMDocument::$config is deprecated"); ZVAL_NULL(retval); return SUCCESS; diff --git a/ext/dom/entity.c b/ext/dom/entity.c index 53871cb731f28..3cfcbb5ae8084 100644 --- a/ext/dom/entity.c +++ b/ext/dom/entity.c @@ -104,10 +104,7 @@ Since: DOM Level 3 */ zend_result dom_entity_actual_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$actualEncoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$actualEncoding is deprecated"); ZVAL_NULL(retval); return SUCCESS; @@ -122,10 +119,7 @@ Since: DOM Level 3 */ zend_result dom_entity_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$encoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$encoding is deprecated"); ZVAL_NULL(retval); return SUCCESS; @@ -140,10 +134,7 @@ Since: DOM Level 3 */ zend_result dom_entity_version_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$version is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$version is deprecated"); ZVAL_NULL(retval); return SUCCESS; diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 81fd0a601f31c..e69a2cd20564e 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -203,6 +203,16 @@ static const libxml_doc_props default_doc_props = { .classmap = NULL, }; +ZEND_DECLARE_MODULE_GLOBALS(dom) + +static PHP_GINIT_FUNCTION(dom) +{ +#if defined(COMPILE_DL_DOM) && defined(ZTS) + ZEND_TSRMLS_CACHE_UPDATE(); +#endif + dom_globals->suppress_warnings = false; +} + /* {{{ dom_get_doc_props() */ dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document) { @@ -464,6 +474,8 @@ static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) / return debug_info; } + DOM_G(suppress_warnings) = true; + object_str = ZSTR_INIT_LITERAL("(object value omitted)", false); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(prop_handlers, string_key, entry) { @@ -486,6 +498,8 @@ static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) / zend_string_release_ex(object_str, false); + DOM_G(suppress_warnings) = false; + return debug_info; } /* }}} */ @@ -668,7 +682,11 @@ zend_module_entry dom_module_entry = { /* {{{ */ NULL, PHP_MINFO(dom), DOM_API_VERSION, /* Extension versionnumber */ - STANDARD_MODULE_PROPERTIES + PHP_MODULE_GLOBALS(dom), + PHP_GINIT(dom), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index c86fd2892e385..07137320baf01 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -300,6 +300,23 @@ static zend_always_inline const xmlChar *php_dom_get_content_or_empty(const xmlN return node->content ? node->content : BAD_CAST ""; } +#define PHP_DOM_DEPRECATED_PROPERTY(message) do { \ + if (EXPECTED(!DOM_G(suppress_warnings))) {\ + zend_error(E_DEPRECATED, message); \ + if (UNEXPECTED(EG(exception))) { \ + return FAILURE; \ + } \ + } \ +} while (0) + +ZEND_BEGIN_MODULE_GLOBALS(dom) + bool suppress_warnings; +ZEND_END_MODULE_GLOBALS(dom) + +ZEND_EXTERN_MODULE_GLOBALS(dom) + +#define DOM_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(dom, v) + PHP_MINIT_FUNCTION(dom); PHP_MSHUTDOWN_FUNCTION(dom); PHP_MINFO_FUNCTION(dom); diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt index 542b2fc4733e1..a1cbabffbb239 100644 --- a/ext/dom/tests/domobject_debug_handler.phpt +++ b/ext/dom/tests/domobject_debug_handler.phpt @@ -16,10 +16,6 @@ var_dump($d); ?> --EXPECTF-- Deprecated: Creation of dynamic property DOMDocument::$dynamicProperty is deprecated in %s on line %d - -Deprecated: Property DOMDocument::$actualEncoding is deprecated in %s on line %d - -Deprecated: Property DOMDocument::$config is deprecated in %s on line %d object(DOMDocument)#1 (41) { ["dynamicProperty"]=> object(stdClass)#2 (0) { From 8fcf34d598ce19861c742c011e73a5ade7837978 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 23 Aug 2024 16:13:23 +0200 Subject: [PATCH 151/280] Remove ZEND_ACC_ABSTRACT from prop variance check Abstract properties are now virtual, unless they actually contain concrete hook implementations using the backing field. --- Zend/zend_inheritance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b43544766b848..2d6e0e427738c 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1396,7 +1396,7 @@ static void inherit_property_hook( } static prop_variance prop_get_variance(zend_property_info *prop_info) { - bool unbacked = prop_info->flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_VIRTUAL); + bool unbacked = prop_info->flags & ZEND_ACC_VIRTUAL; if (unbacked && prop_info->hooks) { if (!prop_info->hooks[ZEND_PROPERTY_HOOK_SET]) { return PROP_COVARIANT; From d9695401e439ff08f72d471d3aca3c198025558f Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 23 Aug 2024 15:28:37 +0100 Subject: [PATCH 152/280] Zend: Voidify virtual_cwd_(de)activate() (#15554) It always returned 0 --- Zend/zend_virtual_cwd.c | 6 ++---- Zend/zend_virtual_cwd.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 916f71412cdf7..366e13ce9b6ba 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -230,22 +230,20 @@ CWD_API void virtual_cwd_shutdown(void) /* {{{ */ } /* }}} */ -CWD_API int virtual_cwd_activate(void) /* {{{ */ +CWD_API void virtual_cwd_activate(void) /* {{{ */ { if (CWDG(cwd).cwd == NULL) { CWD_STATE_COPY(&CWDG(cwd), &main_cwd_state); } - return 0; } /* }}} */ -CWD_API int virtual_cwd_deactivate(void) /* {{{ */ +CWD_API void virtual_cwd_deactivate(void) /* {{{ */ { if (CWDG(cwd).cwd != NULL) { CWD_STATE_FREE(&CWDG(cwd)); CWDG(cwd).cwd = NULL; } - return 0; } /* }}} */ diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index 1ccdf79b7870c..0fc2799118692 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -168,8 +168,8 @@ typedef int (*verify_path_func)(const cwd_state *); CWD_API void virtual_cwd_startup(void); CWD_API void virtual_cwd_shutdown(void); -CWD_API int virtual_cwd_activate(void); -CWD_API int virtual_cwd_deactivate(void); +CWD_API void virtual_cwd_activate(void); +CWD_API void virtual_cwd_deactivate(void); CWD_API char *virtual_getcwd_ex(size_t *length); CWD_API char *virtual_getcwd(char *buf, size_t size); CWD_API zend_result virtual_chdir(const char *path); From 062e9f91347522cc43e38c0d81255c2d6b97926c Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 23 Aug 2024 16:40:19 +0200 Subject: [PATCH 153/280] Remove unused buffer variables (#15550) These emit warning: unused variable 'buffer'. --- Zend/zend_call_stack.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index a2887d164f362..ac12b8b7d8716 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -622,7 +622,6 @@ static bool zend_call_stack_get_netbsd_vm(zend_call_stack *stack, void **ptr) char *start, *end; struct kinfo_vmentry *entry; size_t len, max_size; - char buffer[4096]; uintptr_t addr_on_stack = (uintptr_t) zend_call_stack_position(); int mib[5] = { CTL_VM, VM_PROC, VM_PROC_MAP, getpid(), sizeof(struct kinfo_vmentry) }; bool found = false; @@ -704,7 +703,6 @@ static bool zend_call_stack_get_solaris_pthread(zend_call_stack *stack) #ifdef HAVE_LIBPROC_H static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack) { - char buffer[4096]; uintptr_t addr_on_stack = (uintptr_t) zend_call_stack_position(); bool found = false, r = false; struct ps_prochandle *proc; From babf18c52e0515a392bc7c0fedbfabcc1a456974 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 23 Aug 2024 16:54:21 +0200 Subject: [PATCH 154/280] Autotools: Remove obsolete compiler reset (#15549) This was once added via 827ad656cb2585d2b9a9cc2d3bb021e8edf34365 to store the compiler variable when being modified due to using libtool passing pthread_cflags to linker. --- configure.ac | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configure.ac b/configure.ac index 904786aca432d..491963daae227 100644 --- a/configure.ac +++ b/configure.ac @@ -1464,8 +1464,6 @@ PHP_SUBST([PHP_FRAMEWORKS]) PHP_SUBST([PHP_FRAMEWORKPATH]) PHP_SUBST([INSTALL_HEADERS]) -old_CC=$CC - if test "$PHP_THREAD_SAFETY" = "yes" && test -n "$ac_cv_pthreads_cflags"; then CXXFLAGS="$CXXFLAGS $ac_cv_pthreads_cflags" CPPFLAGS="$CPPFLAGS $ac_cv_pthreads_cflags" @@ -1572,8 +1570,6 @@ PHP_SET_LIBTOOL_VARIABLE([--silent]) dnl libtool 1.4.3 needs this. PHP_SET_LIBTOOL_VARIABLE([--preserve-dup-deps]) -CC=$old_CC - PHP_CONFIGURE_PART([Generating files]) CXXFLAGS_CLEAN=$CXXFLAGS From c26e77c4c57aeeea367c16a3e2a53fe9adb74a69 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 14:46:54 +0200 Subject: [PATCH 155/280] ext/hash: Specialize copy function typedef --- ext/hash/hash.c | 4 ++-- ext/hash/hash_adler32.c | 2 +- ext/hash/hash_crc32.c | 2 +- ext/hash/hash_murmur.c | 6 +++--- ext/hash/hash_xxhash.c | 8 ++++---- ext/hash/php_hash.h | 4 ++-- ext/hash/php_hash_adler32.h | 2 +- ext/hash/php_hash_crc32.h | 2 +- ext/hash/php_hash_murmur.h | 6 +++--- ext/hash/php_hash_xxhash.h | 8 ++++---- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 89a3aab26e78b..c6be52c28089c 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -105,7 +105,7 @@ static struct mhash_bc_entry mhash_to_hash[MHASH_NUM_ALGOS] = { PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo) /* {{{ */ { zend_string *lower = zend_string_tolower(algo); - php_hash_ops *ops = zend_hash_find_ptr(&php_hash_hashtable, lower); + const php_hash_ops *ops = zend_hash_find_ptr(&php_hash_hashtable, lower); zend_string_release(lower); return ops; @@ -121,7 +121,7 @@ PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *o } /* }}} */ -PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context) /* {{{ */ +PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context) /* {{{ */ { php_hash_ops *hash_ops = (php_hash_ops *)ops; diff --git a/ext/hash/hash_adler32.c b/ext/hash/hash_adler32.c index 3937853fdc317..3898ea60e8775 100644 --- a/ext/hash/hash_adler32.c +++ b/ext/hash/hash_adler32.c @@ -52,7 +52,7 @@ PHP_HASH_API void PHP_ADLER32Final(unsigned char digest[4], PHP_ADLER32_CTX *con context->state = 0; } -PHP_HASH_API int PHP_ADLER32Copy(const php_hash_ops *ops, PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context) +PHP_HASH_API zend_result PHP_ADLER32Copy(const php_hash_ops *ops, const PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context) { copy_context->state = orig_context->state; return SUCCESS; diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index 1c3b09c3f2b3c..a770d0b554167 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -84,7 +84,7 @@ PHP_HASH_API void PHP_CRC32BEFinal(unsigned char digest[4], PHP_CRC32_CTX *conte context->state = 0; } -PHP_HASH_API int PHP_CRC32Copy(const php_hash_ops *ops, PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context) +PHP_HASH_API zend_result PHP_CRC32Copy(const php_hash_ops *ops, const PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context) { copy_context->state = orig_context->state; return SUCCESS; diff --git a/ext/hash/hash_murmur.c b/ext/hash/hash_murmur.c index 384133b84bd41..0117b2e57d361 100644 --- a/ext/hash/hash_murmur.c +++ b/ext/hash/hash_murmur.c @@ -75,7 +75,7 @@ PHP_HASH_API void PHP_MURMUR3AFinal(unsigned char digest[4], PHP_MURMUR3A_CTX *c digest[3] = (unsigned char)(ctx->h & 0xff); } -PHP_HASH_API int PHP_MURMUR3ACopy(const php_hash_ops *ops, PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3ACopy(const php_hash_ops *ops, const PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context) { copy_context->h = orig_context->h; copy_context->carry = orig_context->carry; @@ -154,7 +154,7 @@ PHP_HASH_API void PHP_MURMUR3CFinal(unsigned char digest[16], PHP_MURMUR3C_CTX * digest[15] = (unsigned char)(h[3] & 0xff); } -PHP_HASH_API int PHP_MURMUR3CCopy(const php_hash_ops *ops, PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3CCopy(const php_hash_ops *ops, const PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context) { memcpy(©_context->h, &orig_context->h, sizeof orig_context->h); memcpy(©_context->carry, &orig_context->carry, sizeof orig_context->carry); @@ -231,7 +231,7 @@ PHP_HASH_API void PHP_MURMUR3FFinal(unsigned char digest[16], PHP_MURMUR3F_CTX * digest[15] = (unsigned char)(h[1] & 0xff); } -PHP_HASH_API int PHP_MURMUR3FCopy(const php_hash_ops *ops, PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3FCopy(const php_hash_ops *ops, const PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context) { memcpy(©_context->h, &orig_context->h, sizeof orig_context->h); memcpy(©_context->carry, &orig_context->carry, sizeof orig_context->carry); diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 07ac801d99e95..3f7be880fc832 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -69,7 +69,7 @@ PHP_HASH_API void PHP_XXH32Final(unsigned char digest[4], PHP_XXH32_CTX *ctx) XXH32_canonicalFromHash((XXH32_canonical_t*)digest, XXH32_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH32Copy(const php_hash_ops *ops, PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -134,7 +134,7 @@ PHP_HASH_API void PHP_XXH64Final(unsigned char digest[8], PHP_XXH64_CTX *ctx) XXH64_canonicalFromHash((XXH64_canonical_t*)digest, XXH64_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH64Copy(const php_hash_ops *ops, PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH64Copy(const php_hash_ops *ops, const PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -225,7 +225,7 @@ PHP_HASH_API void PHP_XXH3_64_Final(unsigned char digest[8], PHP_XXH3_64_CTX *ct XXH64_canonicalFromHash((XXH64_canonical_t*)digest, XXH3_64bits_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH3_64_Copy(const php_hash_ops *ops, PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -275,7 +275,7 @@ PHP_HASH_API void PHP_XXH3_128_Final(unsigned char digest[16], PHP_XXH3_128_CTX XXH128_canonicalFromHash((XXH128_canonical_t*)digest, XXH3_128bits_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH3_128_Copy(const php_hash_ops *ops, PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH3_128_Copy(const php_hash_ops *ops, const PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 0fd2f5d41f25e..2e2852c0eb312 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -34,7 +34,7 @@ typedef struct _php_hashcontext_object php_hashcontext_object; typedef void (*php_hash_init_func_t)(void *context, HashTable *args); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); -typedef int (*php_hash_copy_func_t)(const void *ops, void *orig_context, void *dest_context); +typedef zend_result (*php_hash_copy_func_t)(const void *ops, const void *orig_context, void *dest_context); typedef int (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); @@ -147,7 +147,7 @@ extern zend_module_entry hash_module_entry; extern PHP_HASH_API zend_class_entry *php_hashcontext_ce; PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops); -PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context); +PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context); PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index 091fdeb3488e7..bacb47ff1c916 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -25,6 +25,6 @@ typedef struct { PHP_HASH_API void PHP_ADLER32Init(PHP_ADLER32_CTX *context, ZEND_ATTRIBUTE_UNUSED HashTable *args); PHP_HASH_API void PHP_ADLER32Update(PHP_ADLER32_CTX *context, const unsigned char *input, size_t len); PHP_HASH_API void PHP_ADLER32Final(unsigned char digest[4], PHP_ADLER32_CTX *context); -PHP_HASH_API int PHP_ADLER32Copy(const php_hash_ops *ops, PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context); +PHP_HASH_API zend_result PHP_ADLER32Copy(const php_hash_ops *ops, const PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context); #endif diff --git a/ext/hash/php_hash_crc32.h b/ext/hash/php_hash_crc32.h index 520829387e3b4..b6accea17bb64 100644 --- a/ext/hash/php_hash_crc32.h +++ b/ext/hash/php_hash_crc32.h @@ -30,6 +30,6 @@ PHP_HASH_API void PHP_CRC32BUpdate(PHP_CRC32_CTX *context, const unsigned char * PHP_HASH_API void PHP_CRC32CUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len); PHP_HASH_API void PHP_CRC32LEFinal(unsigned char digest[4], PHP_CRC32_CTX *context); PHP_HASH_API void PHP_CRC32BEFinal(unsigned char digest[4], PHP_CRC32_CTX *context); -PHP_HASH_API int PHP_CRC32Copy(const php_hash_ops *ops, PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context); +PHP_HASH_API zend_result PHP_CRC32Copy(const php_hash_ops *ops, const PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context); #endif diff --git a/ext/hash/php_hash_murmur.h b/ext/hash/php_hash_murmur.h index b1c326ada225b..6180a9b8f3411 100644 --- a/ext/hash/php_hash_murmur.h +++ b/ext/hash/php_hash_murmur.h @@ -27,7 +27,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3AInit(PHP_MURMUR3A_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3AUpdate(PHP_MURMUR3A_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3AFinal(unsigned char digest[4], PHP_MURMUR3A_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3ACopy(const php_hash_ops *ops, PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3ACopy(const php_hash_ops *ops, const PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context); typedef struct { uint32_t h[4]; @@ -39,7 +39,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3CInit(PHP_MURMUR3C_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3CUpdate(PHP_MURMUR3C_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3CFinal(unsigned char digest[16], PHP_MURMUR3C_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3CCopy(const php_hash_ops *ops, PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3CCopy(const php_hash_ops *ops, const PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context); typedef struct { uint64_t h[2]; @@ -51,7 +51,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3FInit(PHP_MURMUR3F_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3FUpdate(PHP_MURMUR3F_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3FFinal(unsigned char digest[16], PHP_MURMUR3F_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3FCopy(const php_hash_ops *ops, PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3FCopy(const php_hash_ops *ops, const PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context); #endif /* PHP_HASH_MURMUR_H */ diff --git a/ext/hash/php_hash_xxhash.h b/ext/hash/php_hash_xxhash.h index ace70deedb008..f099039f37114 100644 --- a/ext/hash/php_hash_xxhash.h +++ b/ext/hash/php_hash_xxhash.h @@ -28,7 +28,7 @@ typedef struct { PHP_HASH_API void PHP_XXH32Init(PHP_XXH32_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH32Update(PHP_XXH32_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH32Final(unsigned char digest[4], PHP_XXH32_CTX *ctx); -PHP_HASH_API int PHP_XXH32Copy(const php_hash_ops *ops, PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context); typedef struct { XXH64_state_t s; @@ -38,7 +38,7 @@ typedef struct { PHP_HASH_API void PHP_XXH64Init(PHP_XXH64_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH64Update(PHP_XXH64_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH64Final(unsigned char digest[8], PHP_XXH64_CTX *ctx); -PHP_HASH_API int PHP_XXH64Copy(const php_hash_ops *ops, PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH64Copy(const php_hash_ops *ops, const PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context); #define PHP_XXH3_SECRET_SIZE_MIN XXH3_SECRET_SIZE_MIN #define PHP_XXH3_SECRET_SIZE_MAX 256 @@ -60,14 +60,14 @@ typedef PHP_XXH3_CTX PHP_XXH3_64_CTX; PHP_HASH_API void PHP_XXH3_64_Init(PHP_XXH3_64_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH3_64_Update(PHP_XXH3_64_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH3_64_Final(unsigned char digest[8], PHP_XXH3_64_CTX *ctx); -PHP_HASH_API int PHP_XXH3_64_Copy(const php_hash_ops *ops, PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context); typedef PHP_XXH3_CTX PHP_XXH3_128_CTX; PHP_HASH_API void PHP_XXH3_128_Init(PHP_XXH3_128_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH3_128_Update(PHP_XXH3_128_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH3_128_Final(unsigned char digest[16], PHP_XXH3_128_CTX *ctx); -PHP_HASH_API int PHP_XXH3_128_Copy(const php_hash_ops *ops, PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH3_128_Copy(const php_hash_ops *ops, const PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context); #endif /* PHP_HASH_XXHASH_H */ From 937c4e4ac6b85459e810242d89d542e70e68eaf0 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 15:10:38 +0200 Subject: [PATCH 156/280] ext/hash: Make return type zend_result for serialize function typedef --- ext/hash/hash.c | 4 ++-- ext/hash/hash_sha3.c | 2 +- ext/hash/php_hash.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/hash/hash.c b/ext/hash/hash.c index c6be52c28089c..9d099c2d50b45 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -229,7 +229,7 @@ static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) { significant bits first. This allows 32-bit and 64-bit architectures to interchange serialized HashContexts. */ -PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ +PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1; unsigned char *buf = (unsigned char *) hash->context; @@ -331,7 +331,7 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z } /* }}} */ -PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ +PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ { if (hash->ops->serialize_spec) { *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 8a0fddba5b4a6..07da2cfd2d016 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -292,7 +292,7 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ #endif #define PHP_KECCAK_SPEC "b200IiIIB" -static int php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) +static zend_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) { *magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK; return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC); diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 2e2852c0eb312..3b058ef48bdb2 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -35,7 +35,7 @@ typedef void (*php_hash_init_func_t)(void *context, HashTable *args); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); typedef zend_result (*php_hash_copy_func_t)(const void *ops, const void *orig_context, void *dest_context); -typedef int (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); +typedef zend_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); typedef struct _php_hash_ops { @@ -148,9 +148,9 @@ extern PHP_HASH_API zend_class_entry *php_hashcontext_ce; PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops); PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context); -PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); +PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); -PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); +PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); static inline void *php_hash_alloc_context(const php_hash_ops *ops) { From 947f72c181223bb514b7581c91503ba86bd91648 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Thu, 15 Aug 2024 12:29:06 +0200 Subject: [PATCH 157/280] ext/phar: Use standard naming for PHP functions --- ext/phar/func_interceptors.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index c52ee805b2b12..53851abee0dcc 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -18,10 +18,7 @@ #include "phar_internal.h" -#define PHAR_FUNC(name) \ - static PHP_NAMED_FUNCTION(name) - -PHAR_FUNC(phar_opendir) /* {{{ */ +PHP_FUNCTION(phar_opendir) /* {{{ */ { char *filename; size_t filename_len; @@ -156,7 +153,7 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool return name; } -PHAR_FUNC(phar_file_get_contents) /* {{{ */ +PHP_FUNCTION(phar_file_get_contents) /* {{{ */ { zend_string *filename; zend_string *contents; @@ -233,7 +230,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_readfile) /* {{{ */ +PHP_FUNCTION(phar_readfile) /* {{{ */ { zend_string *filename; bool use_include_path = 0; @@ -277,7 +274,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_fopen) /* {{{ */ +PHP_FUNCTION(phar_fopen) /* {{{ */ { zend_string *filename; char *mode; @@ -653,7 +650,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ /* }}} */ #define PharFileFunction(fname, funcnum, orig) \ -ZEND_NAMED_FUNCTION(fname) { \ +PHP_FUNCTION(fname) { \ if (!PHAR_G(intercepted)) { \ PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \ } else { \ @@ -725,7 +722,7 @@ PharFileFunction(phar_file_exists, FS_EXISTS, orig_file_exists) PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir) /* }}} */ -PHAR_FUNC(phar_is_file) /* {{{ */ +PHP_FUNCTION(phar_is_file) /* {{{ */ { char *filename; size_t filename_len; @@ -791,7 +788,7 @@ PHAR_FUNC(phar_is_file) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_is_link) /* {{{ */ +PHP_FUNCTION(phar_is_link) /* {{{ */ { char *filename; size_t filename_len; @@ -886,7 +883,7 @@ void phar_release_functions(void) PHAR_G(orig_##func) = NULL; \ if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \ PHAR_G(orig_##func) = orig->internal_function.handler; \ - orig->internal_function.handler = phar_##func; \ + orig->internal_function.handler = PHP_FN(phar_##func); \ } void phar_intercept_functions_init(void) From 009039d447709dbb3df0ee6ba93c3b164a8e6792 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Thu, 15 Aug 2024 12:49:06 +0200 Subject: [PATCH 158/280] ext/phar: Use size_t for string lenghts And remove useless casts --- ext/phar/dirstream.c | 12 ++++-------- ext/phar/phar.c | 8 ++++---- ext/phar/phar_object.c | 20 ++++++++++---------- ext/phar/stream.c | 16 ++++++---------- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 4674d868f4905..41f45bd17f185 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -295,7 +295,6 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, zend_ulong unused; phar_archive_data *phar; phar_entry_info *entry = NULL; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path); @@ -320,7 +319,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, return NULL; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ @@ -401,7 +400,6 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo char *error, *arch, *entry2; size_t arch_len, entry_len; php_url *resource = NULL; - uint32_t host_len; /* pre-readonly check, we need to know if this is a data phar */ if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { @@ -438,7 +436,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), host_len, NULL, 0, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); @@ -533,10 +531,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options char *error, *arch, *entry2; size_t arch_len, entry_len; php_url *resource = NULL; - uint32_t host_len; zend_string *str_key; zend_ulong unused; - uint32_t path_len; /* pre-readonly check, we need to know if this is a data phar */ if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { @@ -573,7 +569,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), host_len, NULL, 0, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); @@ -582,7 +578,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - path_len = ZSTR_LEN(resource->path) - 1; + size_t path_len = ZSTR_LEN(resource->path) - 1; if (!(entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, 1))) { if (error) { diff --git a/ext/phar/phar.c b/ext/phar/phar.c index ff103e11686d2..22fbdcf04cbf1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2023,11 +2023,11 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const zend_string *str_key; ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&PHAR_G(phar_fname_map), str_key, pphar) { - if (ZSTR_LEN(str_key) > (uint32_t) filename_len) { + if (ZSTR_LEN(str_key) > filename_len) { continue; } - if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && ((uint32_t)filename_len == ZSTR_LEN(str_key) + if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && (filename_len == ZSTR_LEN(str_key) || filename[ZSTR_LEN(str_key)] == '/' || filename[ZSTR_LEN(str_key)] == '\0')) { *ext_str = filename + (ZSTR_LEN(str_key) - pphar->ext_len); goto woohoo; @@ -2036,11 +2036,11 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const if (PHAR_G(manifest_cached)) { ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&cached_phars, str_key, pphar) { - if (ZSTR_LEN(str_key) > (uint32_t) filename_len) { + if (ZSTR_LEN(str_key) > filename_len) { continue; } - if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && ((uint32_t)filename_len == ZSTR_LEN(str_key) + if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && (filename_len == ZSTR_LEN(str_key) || filename[ZSTR_LEN(str_key)] == '/' || filename[ZSTR_LEN(str_key)] == '\0')) { *ext_str = filename + (ZSTR_LEN(str_key) - pphar->ext_len); goto woohoo; diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 688e3981e67d9..3feab9d16080e 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2621,7 +2621,7 @@ PHP_METHOD(Phar, delete) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_TRUE; @@ -3440,13 +3440,13 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } - if (NULL == (oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, (uint32_t) oldfile_len)) || oldentry->is_deleted) { + if (NULL == (oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, oldfile_len)) || oldentry->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", oldfile, newfile, phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (temp = zend_hash_str_find_ptr(&phar_obj->archive->manifest, newfile, (uint32_t) newfile_len)) && !temp->is_deleted) { + if (NULL != (temp = zend_hash_str_find_ptr(&phar_obj->archive->manifest, newfile, newfile_len)) && !temp->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", oldfile, newfile, phar_obj->archive->fname); RETURN_THROWS(); @@ -3466,7 +3466,7 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } /* re-populate with copied-on-write entry */ - oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, (uint32_t) oldfile_len); + oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, oldfile_len); } memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info)); @@ -3513,8 +3513,8 @@ PHP_METHOD(Phar, offsetExists) PHAR_ARCHIVE_OBJECT(); - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint32_t) fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, fname_len)) { + if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_FALSE; @@ -3527,7 +3527,7 @@ PHP_METHOD(Phar, offsetExists) } RETURN_TRUE; } else { - if (zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, (uint32_t) fname_len)) { + if (zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, fname_len)) { RETURN_TRUE; } RETURN_FALSE; @@ -3772,8 +3772,8 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint32_t) fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, fname_len)) { + if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return; @@ -3785,7 +3785,7 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } /* re-populate entry after copy on write */ - entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len); + entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len); } entry->is_modified = 0; entry->is_deleted = 1; diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 79f02ff70db5e..f5e1d9514c724 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -168,7 +168,6 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha php_url *resource = NULL; php_stream *fpf; zval *pzoption, *metadata; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { return NULL; @@ -187,7 +186,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha return NULL; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); /* strip leading "/" */ @@ -565,7 +564,6 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f char *internal_file, *error; phar_archive_data *phar; phar_entry_info *entry; - uint32_t host_len; size_t internal_file_len; if ((resource = phar_parse_url(wrapper, url, "r", flags|PHP_STREAM_URL_STAT_QUIET)) == NULL) { @@ -583,7 +581,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f return FAILURE; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ @@ -674,7 +672,6 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int int internal_file_len; phar_entry_data *idata; phar_archive_data *pphar; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, url, "rb", options)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "phar error: unlink failed"); @@ -694,7 +691,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); @@ -747,7 +744,6 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from char *error; phar_archive_data *phar, *pfrom, *pto; phar_entry_info *entry; - uint32_t host_len; int is_dir = 0; int is_modified = 0; @@ -823,7 +819,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from return 0; } - host_len = ZSTR_LEN(resource_from->host); + size_t host_len = ZSTR_LEN(resource_from->host); if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), host_len, NULL, 0, &error)) { php_url_free(resource_from); @@ -893,8 +889,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from Bucket *b; zend_string *str_key; zend_string *new_str_key; - uint32_t from_len = ZSTR_LEN(resource_from->path) - 1; - uint32_t to_len = ZSTR_LEN(resource_to->path) - 1; + size_t from_len = ZSTR_LEN(resource_from->path) - 1; + size_t to_len = ZSTR_LEN(resource_to->path) - 1; ZEND_HASH_MAP_FOREACH_BUCKET(&phar->manifest, b) { str_key = b->key; From 03be1ac0ada67d55b9a74ef153ab760604d56399 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Fri, 16 Aug 2024 23:59:01 +0200 Subject: [PATCH 159/280] ext/phar: Refactor part of tar.c --- ext/phar/phar.c | 2 +- ext/phar/phar_internal.h | 6 +++--- ext/phar/tar.c | 38 ++++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 22fbdcf04cbf1..13ef2c3fef5f1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1772,7 +1772,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char if (got > 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, is_data, compression, error); + return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); } } } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 625b8f1f16f90..402e2f7d8c2e3 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -564,9 +564,9 @@ int phar_open_archive_fp(phar_archive_data *phar); int phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ -int phar_is_tar(char *buf, char *fname); -int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error); -int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); +bool phar_is_tar(char *buf, char *fname); +zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); +zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int defaultstub, char **error); /* zip functions in zip.c */ diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 0b1de03c33f7b..722a34b2300f4 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -62,10 +62,10 @@ static uint32_t phar_tar_number(const char *buf, size_t len) /* {{{ */ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -static int phar_tar_octal(char *buf, uint32_t val, int len) /* {{{ */ +static zend_result phar_tar_octal(char *buf, uint32_t val, size_t len) /* {{{ */ { char *p = buf; - int s = len; + size_t s = len; p += len; /* Start at the end and work backwards. */ while (s-- > 0) { @@ -73,12 +73,14 @@ static int phar_tar_octal(char *buf, uint32_t val, int len) /* {{{ */ val >>= 3; } - if (val == 0) + if (val == 0) { return SUCCESS; + } /* If it overflowed, fill field with max value. */ - while (len-- > 0) + while (len-- > 0) { *p++ = '7'; + } return FAILURE; } @@ -97,37 +99,37 @@ static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ } /* }}} */ -int phar_is_tar(char *buf, char *fname) /* {{{ */ +bool phar_is_tar(char *buf, char *fname) /* {{{ */ { tar_header *header = (tar_header *) buf; uint32_t checksum = phar_tar_number(header->checksum, sizeof(header->checksum)); - uint32_t ret; + bool is_tar; char save[sizeof(header->checksum)], *bname; /* assume that the first filename in a tar won't begin with checksum, sizeof(header->checksum)); memset(header->checksum, ' ', sizeof(header->checksum)); - ret = (checksum == phar_tar_checksum(buf, 512)); + is_tar = (checksum == phar_tar_checksum(buf, 512)); memcpy(header->checksum, save, sizeof(header->checksum)); if ((bname = strrchr(fname, PHP_DIR_SEPARATOR))) { fname = bname; } - if (!ret && (bname = strstr(fname, ".tar")) && (bname[4] == '\0' || bname[4] == '.')) { + if (!is_tar && (bname = strstr(fname, ".tar")) && (bname[4] == '\0' || bname[4] == '.')) { /* probably a corrupted tar - so we will pretend it is one */ - return 1; + return true; } - return ret; + return is_tar; } /* }}} */ -int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; - int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -157,7 +159,7 @@ int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t a } /* }}} */ -static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ +static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ { char *metadata; size_t save = php_stream_tell(fp), read; @@ -199,7 +201,7 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* } /* }}} */ -int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error) /* {{{ */ +zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char buf[512], *actual_alias = NULL, *p; phar_entry_info entry = {0}; @@ -699,8 +701,8 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia struct _phar_pass_tar_info { php_stream *old; php_stream *new; - int free_fp; - int free_ufp; + bool free_fp; + bool free_ufp; char **error; }; @@ -863,7 +865,7 @@ static int phar_tar_writeheaders(zval *zv, void *argument) /* {{{ */ } /* }}} */ -int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ +static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ { /* Copy the metadata from tracker to the new entry being written out to temporary files */ const zend_string *serialized_str; From d015af60df3ab9b6ab068ecaa94338016fb44a7a Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:04:16 +0200 Subject: [PATCH 160/280] ext/phar: Adjust return types for methods that always return true --- ext/phar/phar_object.stub.php | 4 ++-- ext/phar/phar_object_arginfo.h | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ext/phar/phar_object.stub.php b/ext/phar/phar_object.stub.php index e20b575d87a5c..ae5bd69c32f48 100644 --- a/ext/phar/phar_object.stub.php +++ b/ext/phar/phar_object.stub.php @@ -187,10 +187,10 @@ public function offsetSet($localName, $value): void {} public function offsetUnset($localName): void {} /** @tentative-return-type */ - public function setAlias(string $alias): bool {} + public function setAlias(string $alias): true {} /** @tentative-return-type */ - public function setDefaultStub(?string $index = null, ?string $webIndex = null): bool {} + public function setDefaultStub(?string $index = null, ?string $webIndex = null): true {} /** @tentative-return-type */ public function setMetadata(mixed $metadata): void {} diff --git a/ext/phar/phar_object_arginfo.h b/ext/phar/phar_object_arginfo.h index 16482611560b7..3111bc260f4aa 100644 --- a/ext/phar/phar_object_arginfo.h +++ b/ext/phar/phar_object_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4182a1159f6cf8a0d71a7814d0435b5e2be29276 */ + * Stub hash: 031dc8f07d2d9bac4a5f82f4ac2c5b3da5995405 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -133,11 +133,11 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_offsetUnset ZEND_ARG_INFO(0, localName) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setAlias, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setAlias, 0, 1, IS_TRUE, 0) ZEND_ARG_TYPE_INFO(0, alias, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setDefaultStub, 0, 0, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setDefaultStub, 0, 0, IS_TRUE, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, webIndex, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -302,9 +302,14 @@ ZEND_END_ARG_INFO() #define arginfo_class_PharData_offsetUnset arginfo_class_Phar_offsetUnset -#define arginfo_class_PharData_setAlias arginfo_class_Phar_setAlias +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PharData_setAlias, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, alias, IS_STRING, 0) +ZEND_END_ARG_INFO() -#define arginfo_class_PharData_setDefaultStub arginfo_class_Phar_setDefaultStub +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PharData_setDefaultStub, 0, 0, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, webIndex, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() #define arginfo_class_PharData_setMetadata arginfo_class_Phar_setMetadata From 81d232fed5795a2a229fc3e9255a3f68fe0f70f2 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:11:11 +0200 Subject: [PATCH 161/280] ext/phar: Move some header functions into util.c They were only used there, therefore mark them static --- ext/phar/phar_internal.h | 83 ---------------------------------------- ext/phar/util.c | 55 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 83 deletions(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 402e2f7d8c2e3..d447994acd971 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -339,34 +339,6 @@ static inline php_stream *phar_get_entrypfp(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].fp; } -static inline php_stream *phar_get_entrypufp(phar_entry_info *entry) -{ - if (!entry->is_persistent) { - return entry->phar->ufp; - } - return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp; -} - -static inline void phar_set_entrypfp(phar_entry_info *entry, php_stream *fp) -{ - if (!entry->phar->is_persistent) { - entry->phar->fp = fp; - return; - } - - PHAR_G(cached_fp)[entry->phar->phar_pos].fp = fp; -} - -static inline void phar_set_entrypufp(phar_entry_info *entry, php_stream *fp) -{ - if (!entry->phar->is_persistent) { - entry->phar->ufp = fp; - return; - } - - PHAR_G(cached_fp)[entry->phar->phar_pos].ufp = fp; -} - static inline php_stream *phar_get_pharfp(phar_archive_data *phar) { if (!phar->is_persistent) { @@ -375,48 +347,6 @@ static inline php_stream *phar_get_pharfp(phar_archive_data *phar) return PHAR_G(cached_fp)[phar->phar_pos].fp; } -static inline php_stream *phar_get_pharufp(phar_archive_data *phar) -{ - if (!phar->is_persistent) { - return phar->ufp; - } - return PHAR_G(cached_fp)[phar->phar_pos].ufp; -} - -static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) -{ - if (!phar->is_persistent) { - phar->fp = fp; - return; - } - - PHAR_G(cached_fp)[phar->phar_pos].fp = fp; -} - -static inline void phar_set_pharufp(phar_archive_data *phar, php_stream *fp) -{ - if (!phar->is_persistent) { - phar->ufp = fp; - return; - } - - PHAR_G(cached_fp)[phar->phar_pos].ufp = fp; -} - -static inline void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zend_off_t offset) -{ - phar_entry_fp_info *data; - - if (!entry->is_persistent) { - entry->fp_type = type; - entry->offset = offset; - return; - } - data = &(PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos]); - data->fp_type = type; - data->offset = offset; -} - static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) { if (!entry->is_persistent) { @@ -425,19 +355,6 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type; } -static inline zend_off_t phar_get_fp_offset(phar_entry_info *entry) -{ - if (!entry->is_persistent) { - return entry->offset; - } - if (PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) { - if (!PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) { - PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset; - } - } - return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset; -} - #define PHAR_MIME_PHP '\0' #define PHAR_MIME_PHPS '\1' #define PHAR_MIME_OTHER '\2' diff --git a/ext/phar/util.c b/ext/phar/util.c index 3a366216650a2..7c2446d485255 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -82,6 +82,14 @@ phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */ } /* }}} */ +static php_stream *phar_get_entrypufp(const phar_entry_info *entry) +{ + if (!entry->is_persistent) { + return entry->phar->ufp; + } + return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp; +} + /* retrieve a phar_entry_info's current file pointer for reading contents */ php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */ { @@ -113,6 +121,19 @@ php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */ } /* }}} */ +static zend_off_t phar_get_fp_offset(const phar_entry_info *entry) +{ + if (!entry->is_persistent) { + return entry->offset; + } + if (PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) { + if (!PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) { + PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset; + } + } + return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset; +} + int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */ { php_stream *fp = phar_get_efp(entry, follow_links); @@ -616,6 +637,16 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch } /* }}} */ +static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) +{ + if (!phar->is_persistent) { + phar->fp = fp; + return; + } + + PHAR_G(cached_fp)[phar->phar_pos].fp = fp; +} + /* initialize a phar_archive_data's read-only fp for existing phar data */ int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ { @@ -680,6 +711,30 @@ int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **er } /* }}} */ +static void phar_set_entrypufp(const phar_entry_info *entry, php_stream *fp) +{ + if (!entry->phar->is_persistent) { + entry->phar->ufp = fp; + return; + } + + PHAR_G(cached_fp)[entry->phar->phar_pos].ufp = fp; +} + +static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zend_off_t offset) +{ + phar_entry_fp_info *data; + + if (!entry->is_persistent) { + entry->fp_type = type; + entry->offset = offset; + return; + } + data = &(PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos]); + data->fp_type = type; + data->offset = offset; +} + /* open and decompress a compressed phar entry */ int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ From 20f7e08687f56a9fccbeed025216e4387f08a0ee Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:00:07 +0200 Subject: [PATCH 162/280] ext/phar: Use more specialized types instead of int --- ext/phar/phar.c | 51 ++++----- ext/phar/phar_internal.h | 58 +++++----- ext/phar/phar_object.c | 8 +- ext/phar/php_phar.h | 2 +- ext/phar/util.c | 228 +++++++++++++++++++-------------------- 5 files changed, 171 insertions(+), 176 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 13ef2c3fef5f1..540e9302fb9cc 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -238,7 +238,7 @@ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ /** * Delete refcount and destruct if needed. On destruct return 1 else 0. */ -int phar_archive_delref(phar_archive_data *phar) /* {{{ */ +bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ { if (phar->is_persistent) { return 0; @@ -481,7 +481,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ /** * Open an already loaded phar */ -int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; #ifdef PHP_WIN32 @@ -559,7 +559,7 @@ int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t ali * Attempt to serialize the data. * Callers are responsible for handling EG(exception) if one occurs. */ -void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker *tracker, int persistent) /* {{{ */ +void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { php_serialize_data_t metadata_hash; smart_str metadata_str = {0}; @@ -585,7 +585,7 @@ void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker * * Precondition: phar_metadata_tracker_has_data is true */ -int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zval *metadata, int persistent, HashTable *unserialize_options, const char* method_name) /* {{{ */ +zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zval *metadata, bool persistent, HashTable *unserialize_options, const char* method_name) /* {{{ */ { const bool has_unserialize_options = unserialize_options != NULL && zend_hash_num_elements(unserialize_options) > 0; /* It should be impossible to create a zval in a persistent phar/entry. */ @@ -626,7 +626,7 @@ int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zv /** * Check if this has any data, serialized or as a raw value. */ -bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, int persistent) /* {{{ */ +bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { ZEND_ASSERT(!persistent || Z_ISUNDEF(tracker->val)); return !Z_ISUNDEF(tracker->val) || tracker->str != NULL; @@ -636,7 +636,7 @@ bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, int pe /** * Free memory used to track the metadata and set all fields to be null/undef. */ -void phar_metadata_tracker_free(phar_metadata_tracker *tracker, int persistent) /* {{{ */ +void phar_metadata_tracker_free(phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { /* Free the string before the zval in case the zval's destructor modifies the metadata */ if (tracker->str) { @@ -658,7 +658,7 @@ void phar_metadata_tracker_free(phar_metadata_tracker *tracker, int persistent) /** * Free memory used to track the metadata and set all fields to be null/undef. */ -void phar_metadata_tracker_copy(phar_metadata_tracker *dest, const phar_metadata_tracker *source, int persistent) /* {{{ */ +void phar_metadata_tracker_copy(phar_metadata_tracker *dest, const phar_metadata_tracker *source, bool persistent) /* {{{ */ { ZEND_ASSERT(dest != source); phar_metadata_tracker_free(dest, persistent); @@ -694,7 +694,7 @@ void phar_metadata_tracker_clone(phar_metadata_tracker *tracker) /* {{{ */ * * data is the serialized zval */ -void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, int persistent) /* {{{ */ +void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent) /* {{{ */ { phar_metadata_tracker_free(tracker, persistent); if (zip_metadata_len) { @@ -1302,7 +1302,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch /** * Create or open a phar for writing */ -int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { const char *ext_str, *z; char *my_error; @@ -1379,7 +1379,9 @@ int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, siz } /* }}} */ -int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); + +zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *mydata; php_stream *fp; @@ -1402,7 +1404,7 @@ int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, si } if (fp) { - if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, is_data, error) == SUCCESS) { + if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error) == SUCCESS) { if ((*pphar)->is_data || !PHAR_G(readonly)) { (*pphar)->is_writeable = 1; } @@ -1532,18 +1534,18 @@ int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, si * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual; - int ret, is_data = 0; + bool is_data = false; if (error) { *error = NULL; } if (!strstr(fname, ".phar")) { - is_data = 1; + is_data = true; } if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { @@ -1574,7 +1576,7 @@ int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t a fname_len = ZSTR_LEN(actual); } - ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, is_data, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -1618,7 +1620,7 @@ static inline char *phar_strnstr(const char *buf, int buf_len, const char *searc * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, int is_data, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; @@ -1956,7 +1958,7 @@ static int phar_check_str(const char *fname, const char *ext_str, size_t ext_len * the last parameter should be set to tell the thing to assume that filename is the full path, and only to check the * extension rules, not to iterate. */ -int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete) /* {{{ */ +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete) /* {{{ */ { const char *pos, *slash; @@ -2101,7 +2103,7 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const } /* }}} */ -static int php_check_dots(const char *element, size_t n) /* {{{ */ +static bool php_check_dots(const char *element, size_t n) /* {{{ */ { for(n-- ; n != SIZE_MAX; --n) { if (element[n] != '.') { @@ -2237,7 +2239,7 @@ char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ * * This is used by phar_parse_url() */ -int phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ +zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ { const char *ext_str; #ifdef PHP_WIN32 @@ -2314,7 +2316,7 @@ int phar_split_fname(const char *filename, size_t filename_len, char **arch, siz * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ { if (error) { *error = NULL; @@ -2362,7 +2364,7 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* fname = actual; } - int ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, 0, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2375,10 +2377,8 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* /** * Validate the CRC32 of a file opened from within the phar */ -int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ +zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ { - uint32_t crc = php_crc32_bulk_init(); - int len = idata->internal_file->uncompressed_filesize, ret; php_stream *fp = idata->fp; phar_entry_info *entry = idata->internal_file; @@ -2443,7 +2443,8 @@ int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, php_stream_seek(fp, idata->zero, SEEK_SET); - ret = php_crc32_stream_bulk_update(&crc, fp, len); + uint32_t crc = php_crc32_bulk_init(); + zend_result ret = php_crc32_stream_bulk_update(&crc, fp, idata->internal_file->uncompressed_filesize); php_stream_seek(fp, idata->zero, SEEK_SET); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index d447994acd971..a94d6c40ce36a 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -404,10 +404,8 @@ static inline void phar_unixify_path_separators(char *path, size_t path_len) } } #endif -/** - * validate an alias, returns 1 for success, 0 for failure - */ -static inline int phar_validate_alias(const char *alias, size_t alias_len) /* {{{ */ + +static inline bool phar_validate_alias(const char *alias, size_t alias_len) /* {{{ */ { return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) || memchr(alias, ';', alias_len) || memchr(alias, '\n', alias_len) || memchr(alias, '\r', alias_len)); @@ -439,16 +437,15 @@ void phar_request_initialize(void); void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); -int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_open_executed_filename(char *alias, size_t alias_len, char **error); -int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); -int phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); -int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); -int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); +zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); +zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); +zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); +zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); +zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); /* utility functions */ zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error); @@ -457,28 +454,26 @@ char *phar_compress_filter(phar_entry_info * entry, int return_unknown); /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); -int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); +zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar); char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd); phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error); -void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, int persistent); -bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, int persistent); +void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent); +bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, bool persistent); /* If this has data, free it and set all values to undefined. */ -void phar_metadata_tracker_free(phar_metadata_tracker* val, int persistent); -void phar_metadata_tracker_copy(phar_metadata_tracker* dest, const phar_metadata_tracker *source, int persistent); +void phar_metadata_tracker_free(phar_metadata_tracker* val, bool persistent); +void phar_metadata_tracker_copy(phar_metadata_tracker* dest, const phar_metadata_tracker *source, bool persistent); void phar_metadata_tracker_clone(phar_metadata_tracker* tracker); -void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker* tracker, int persistent); -int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tracker, zval *value, int persistent, HashTable *unserialize_options, const char* method_name); +void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker* tracker, bool persistent); +zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tracker, zval *value, bool persistent, HashTable *unserialize_options, const char* method_name); void destroy_phar_manifest_entry(zval *zv); int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links); php_stream *phar_get_efp(phar_entry_info *entry, int follow_links); -int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); -int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links); +zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); +zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links); phar_entry_info *phar_get_link_source(phar_entry_info *entry); -int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error); -int phar_separate_entry_fp(phar_entry_info *entry, char **error); -int phar_open_archive_fp(phar_archive_data *phar); -int phar_copy_on_write(phar_archive_data **pphar); +zend_result phar_open_archive_fp(phar_archive_data *phar); +zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ bool phar_is_tar(char *buf, char *fname); @@ -492,23 +487,22 @@ int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t a int phar_zip_flush(phar_archive_data *archive, char *user_stub, zend_long len, int defaultstub, char **error); #ifdef PHAR_MAIN -static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, int is_data, char **error); extern const php_stream_wrapper php_stream_phar_wrapper; #else extern HashTable cached_phars; extern HashTable cached_alias; #endif -int phar_archive_delref(phar_archive_data *phar); +bool phar_archive_delref(phar_archive_data *phar); void phar_entry_delref(phar_entry_data *idata); phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security); phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security); phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); -int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); +zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); int phar_flush(phar_archive_data *archive, char *user_stub, zend_long len, int convert, char **error); -int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete); -int phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete); +zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); typedef enum { pcr_use_query, diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 3feab9d16080e..ed4b7e969ee6d 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1922,7 +1922,7 @@ PHP_METHOD(Phar, isFileFormat) } /* }}} */ -static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp) /* {{{ */ +static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *fp) /* {{{ */ { char *error; zend_off_t offset; @@ -4004,7 +4004,7 @@ PHP_METHOD(Phar, getMetadata) /* }}} */ /* {{{ Modifies the phar metadata or throws */ -static int serialize_metadata_or_throw(phar_metadata_tracker *tracker, int persistent, zval *metadata) +static zend_result serialize_metadata_or_throw(phar_metadata_tracker *tracker, int persistent, zval *metadata) { php_serialize_data_t metadata_hash; smart_str main_metadata_str = {0}; @@ -4105,7 +4105,7 @@ PHP_METHOD(Phar, delMetadata) } /* }}} */ -static int phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */ +static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */ { php_stream_statbuf ssb; size_t len; @@ -4259,7 +4259,7 @@ static int phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, } } - if (FAILURE == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to seek internal file pointer", entry->filename, fullpath); efree(fullpath); php_stream_close(fp); diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index 9825909ee22fc..66db4c06829c0 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -32,6 +32,6 @@ extern zend_module_entry phar_module_entry; #define PHP_PHAR_API PHPAPI #endif -PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len); +PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len); #endif /* PHP_PHAR_H */ diff --git a/ext/phar/util.c b/ext/phar/util.c index 7c2446d485255..0db5b1ae76f3c 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -184,7 +184,7 @@ int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_of /* }}} */ /* mount an absolute path or uri to a path internal to the phar archive */ -int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ +zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ { phar_entry_info entry = {0}; php_stream_statbuf ssb; @@ -361,6 +361,105 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data } /* }}} */ +static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ +{ + if (entry->fp_type == PHAR_MOD) { + /* already newly created, truncate */ + php_stream_truncate_set_size(entry->fp, 0); + + entry->old_flags = entry->flags; + entry->is_modified = 1; + phar->is_modified = 1; + /* reset file size */ + entry->uncompressed_filesize = 0; + entry->compressed_filesize = 0; + entry->crc32 = 0; + entry->flags = PHAR_ENT_PERM_DEF_FILE; + entry->fp_type = PHAR_MOD; + entry->offset = 0; + return SUCCESS; + } + + if (error) { + *error = NULL; + } + + /* open a new temp file for writing */ + if (entry->link) { + efree(entry->link); + entry->link = NULL; + entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); + } + + entry->fp = php_stream_fopen_tmpfile(); + + if (!entry->fp) { + if (error) { + spprintf(error, 0, "phar error: unable to create temporary file"); + } + return FAILURE; + } + + entry->old_flags = entry->flags; + entry->is_modified = 1; + phar->is_modified = 1; + /* reset file size */ + entry->uncompressed_filesize = 0; + entry->compressed_filesize = 0; + entry->crc32 = 0; + entry->flags = PHAR_ENT_PERM_DEF_FILE; + entry->fp_type = PHAR_MOD; + entry->offset = 0; + return SUCCESS; +} +/* }}} */ + +static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ +{ + php_stream *fp; + phar_entry_info *link; + + if (FAILURE == phar_open_entry_fp(entry, error, 1)) { + return FAILURE; + } + + if (entry->fp_type == PHAR_MOD) { + return SUCCESS; + } + + fp = php_stream_fopen_tmpfile(); + if (fp == NULL) { + spprintf(error, 0, "phar error: unable to create temporary file"); + return FAILURE; + } + phar_seek_efp(entry, 0, SEEK_SET, 0, 1); + link = phar_get_link_source(entry); + + if (!link) { + link = entry; + } + + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { + if (error) { + spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname); + } + return FAILURE; + } + + if (entry->link) { + efree(entry->link); + entry->link = NULL; + entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); + } + + entry->offset = 0; + entry->fp = fp; + entry->fp_type = PHAR_MOD; + entry->is_modified = 1; + return SUCCESS; +} +/* }}} */ + /** * Retrieve a copy of the file information on a single file within a phar, or null. * This also transfers the open file pointer, if any, to the entry. @@ -369,14 +468,14 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data * appended, truncated, or read. For read, if the entry is marked unmodified, it is * assumed that the file pointer, if present, is opened for reading */ -int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ +zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ { phar_archive_data *phar; phar_entry_info *entry; - int for_write = mode[0] != 'r' || mode[1] == '+'; - int for_append = mode[0] == 'a'; - int for_create = mode[0] != 'r'; - int for_trunc = mode[0] == 'w'; + bool for_write = mode[0] != 'r' || mode[1] == '+'; + bool for_append = mode[0] == 'a'; + bool for_create = mode[0] != 'r'; + bool for_trunc = mode[0] == 'w'; if (!ret) { return FAILURE; @@ -648,7 +747,7 @@ static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) } /* initialize a phar_archive_data's read-only fp for existing phar data */ -int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ +zend_result phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ { if (phar_get_pharfp(phar)) { return SUCCESS; @@ -669,7 +768,7 @@ int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ /* }}} */ /* copy file data from an existing to a new phar_entry_info that is not in the manifest */ -int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ +zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ { phar_entry_info *link; @@ -737,7 +836,7 @@ static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zen /* open and decompress a compressed phar entry */ -int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ +zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ { php_stream_filter *filter; phar_archive_data *phar = entry->phar; @@ -853,105 +952,6 @@ int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) / } /* }}} */ -int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ -{ - if (entry->fp_type == PHAR_MOD) { - /* already newly created, truncate */ - php_stream_truncate_set_size(entry->fp, 0); - - entry->old_flags = entry->flags; - entry->is_modified = 1; - phar->is_modified = 1; - /* reset file size */ - entry->uncompressed_filesize = 0; - entry->compressed_filesize = 0; - entry->crc32 = 0; - entry->flags = PHAR_ENT_PERM_DEF_FILE; - entry->fp_type = PHAR_MOD; - entry->offset = 0; - return SUCCESS; - } - - if (error) { - *error = NULL; - } - - /* open a new temp file for writing */ - if (entry->link) { - efree(entry->link); - entry->link = NULL; - entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); - } - - entry->fp = php_stream_fopen_tmpfile(); - - if (!entry->fp) { - if (error) { - spprintf(error, 0, "phar error: unable to create temporary file"); - } - return FAILURE; - } - - entry->old_flags = entry->flags; - entry->is_modified = 1; - phar->is_modified = 1; - /* reset file size */ - entry->uncompressed_filesize = 0; - entry->compressed_filesize = 0; - entry->crc32 = 0; - entry->flags = PHAR_ENT_PERM_DEF_FILE; - entry->fp_type = PHAR_MOD; - entry->offset = 0; - return SUCCESS; -} -/* }}} */ - -int phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ -{ - php_stream *fp; - phar_entry_info *link; - - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { - return FAILURE; - } - - if (entry->fp_type == PHAR_MOD) { - return SUCCESS; - } - - fp = php_stream_fopen_tmpfile(); - if (fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return FAILURE; - } - phar_seek_efp(entry, 0, SEEK_SET, 0, 1); - link = phar_get_link_source(entry); - - if (!link) { - link = entry; - } - - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { - if (error) { - spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname); - } - return FAILURE; - } - - if (entry->link) { - efree(entry->link); - entry->link = NULL; - entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); - } - - entry->offset = 0; - entry->fp = fp; - entry->fp_type = PHAR_MOD; - entry->is_modified = 1; - return SUCCESS; -} -/* }}} */ - /** * helper function to open an internal file's fp just-in-time */ @@ -972,7 +972,7 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, } /* }}} */ -PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ { +PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ { phar_archive_data *fd_ptr; if (HT_IS_INITIALIZED(&PHAR_G(phar_alias_map)) && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { @@ -984,7 +984,7 @@ PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filena } /* }}} */ -int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ +zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ { if (phar->refcount || phar->is_persistent) { return FAILURE; @@ -1007,7 +1007,7 @@ int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* { * Looks up a phar archive in the filename map, connecting it to the alias * (if any) or returns null */ -int phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ { phar_archive_data *fd, *fd_ptr; char *my_realpath, *save; @@ -1537,7 +1537,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t /* }}} */ #endif /* #ifndef PHAR_HAVE_OPENSSL */ -int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ { size_t read_size, len; zend_off_t read_len; @@ -1851,7 +1851,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, } /* }}} */ -int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ +zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ { unsigned char buf[1024]; size_t sig_len; @@ -2134,7 +2134,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ } /* }}} */ -int phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ +zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ { zval zv, *pzv; phar_archive_data *newpphar; From 6f986837ec5245d942a55140741dad7b1cfec64c Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:16:25 +0200 Subject: [PATCH 163/280] ext/phar: Simplify a return condition in Phar::offsetExists() --- ext/phar/phar_object.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index ed4b7e969ee6d..1196d2e419ec4 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3527,10 +3527,7 @@ PHP_METHOD(Phar, offsetExists) } RETURN_TRUE; } else { - if (zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, fname_len)) { - RETURN_TRUE; - } - RETURN_FALSE; + RETURN_BOOL(zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, fname_len)); } } /* }}} */ From 51bb8cfcb563bd16df425b14cc6a2c94e6236650 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:18:10 +0200 Subject: [PATCH 164/280] ext/phar: Add some const qualifiers --- ext/phar/phar_internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index a94d6c40ce36a..1226de191542a 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -331,7 +331,7 @@ struct _phar_entry_fp { phar_entry_fp_info *manifest; }; -static inline php_stream *phar_get_entrypfp(phar_entry_info *entry) +static inline php_stream *phar_get_entrypfp(const phar_entry_info *entry) { if (!entry->is_persistent) { return entry->phar->fp; @@ -339,7 +339,7 @@ static inline php_stream *phar_get_entrypfp(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].fp; } -static inline php_stream *phar_get_pharfp(phar_archive_data *phar) +static inline php_stream *phar_get_pharfp(const phar_archive_data *phar) { if (!phar->is_persistent) { return phar->fp; @@ -347,7 +347,7 @@ static inline php_stream *phar_get_pharfp(phar_archive_data *phar) return PHAR_G(cached_fp)[phar->phar_pos].fp; } -static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) +static inline enum phar_fp_type phar_get_fp_type(const phar_entry_info *entry) { if (!entry->is_persistent) { return entry->fp_type; From d55074ede49252a052bc40007ffdada6367058e0 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:24:53 +0200 Subject: [PATCH 165/280] ext/phar: Use zend_string instead of char* len pair --- ext/phar/phar_object.c | 211 ++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 106 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 1196d2e419ec4..5232649d7fed9 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2600,12 +2600,11 @@ PHP_METHOD(Phar, isWritable) /* {{{ Deletes a named file within the archive. */ PHP_METHOD(Phar, delete) { - char *fname; - size_t fname_len; + zend_string *file_name; char *error; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } @@ -2621,7 +2620,7 @@ PHP_METHOD(Phar, delete) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_TRUE; @@ -2631,7 +2630,7 @@ PHP_METHOD(Phar, delete) phar_obj->archive->is_modified = 1; } } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be deleted", fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be deleted", ZSTR_VAL(file_name)); RETURN_THROWS(); } @@ -2679,12 +2678,13 @@ PHP_METHOD(Phar, getPath) */ PHP_METHOD(Phar, setAlias) { - char *alias, *error, *oldalias; + zend_string *new_alias = NULL; + char *error, *oldalias; phar_archive_data *fd_ptr; - size_t alias_len, oldalias_len; + size_t oldalias_len; int old_temp, readd = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_alias) == FAILURE) { RETURN_THROWS(); } @@ -2711,12 +2711,12 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - if (alias_len == phar_obj->archive->alias_len && memcmp(phar_obj->archive->alias, alias, alias_len) == 0) { + if (zend_string_equals_cstr(new_alias, phar_obj->archive->alias, phar_obj->archive->alias_len)) { RETURN_TRUE; } - if (alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, fd_ptr->fname); - if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), new_alias))) { + spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), fd_ptr->fname); + if (SUCCESS == phar_free_alias(fd_ptr, ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { efree(error); goto valid_alias; } @@ -2724,9 +2724,9 @@ PHP_METHOD(Phar, setAlias) efree(error); RETURN_THROWS(); } - if (!phar_validate_alias(alias, alias_len)) { + if (!phar_validate_alias(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->archive->fname); + "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), phar_obj->archive->fname); RETURN_THROWS(); } valid_alias: @@ -2743,13 +2743,8 @@ PHP_METHOD(Phar, setAlias) oldalias_len = phar_obj->archive->alias_len; old_temp = phar_obj->archive->is_temporary_alias; - if (alias_len) { - phar_obj->archive->alias = estrndup(alias, alias_len); - } else { - phar_obj->archive->alias = NULL; - } - - phar_obj->archive->alias_len = alias_len; + phar_obj->archive->alias = estrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias)); + phar_obj->archive->alias_len = ZSTR_LEN(new_alias); phar_obj->archive->is_temporary_alias = 0; phar_flush(phar_obj->archive, NULL, 0, 0, &error); @@ -2765,7 +2760,7 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, phar_obj->archive); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), new_alias, phar_obj->archive); if (oldalias) { efree(oldalias); @@ -3408,13 +3403,13 @@ PHP_METHOD(Phar, decompressFiles) /* {{{ copy a file internal to the phar archive to another new file within the phar */ PHP_METHOD(Phar, copy) { - char *oldfile, *newfile, *error; + char *error; const char *pcr_error; - size_t oldfile_len, newfile_len; phar_entry_info *oldentry, newentry = {0}, *temp; - size_t tmp_len = 0; + zend_string *new_file = NULL; + zend_string *old_file = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &oldfile, &oldfile_len, &newfile, &newfile_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "PP", &old_file, &new_file) == FAILURE) { RETURN_THROWS(); } @@ -3422,43 +3417,43 @@ PHP_METHOD(Phar, copy) if (PHAR_G(readonly) && !phar_obj->archive->is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot copy \"%s\" to \"%s\", phar is read-only", oldfile, newfile); + "Cannot copy \"%s\" to \"%s\", phar is read-only", ZSTR_VAL(old_file), ZSTR_VAL(new_file)); RETURN_THROWS(); } - if (oldfile_len >= sizeof(".phar")-1 && !memcmp(oldfile, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(old_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (newfile_len >= sizeof(".phar")-1 && !memcmp(newfile, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(new_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL == (oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, oldfile_len)) || oldentry->is_deleted) { + if (NULL == (oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file)) || oldentry->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (temp = zend_hash_str_find_ptr(&phar_obj->archive->manifest, newfile, newfile_len)) && !temp->is_deleted) { + if (NULL != (temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file)) && !temp->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - tmp_len = newfile_len; - if (phar_path_check(&newfile, &tmp_len, &pcr_error) > pcr_is_ok) { + size_t tmp_len = ZSTR_LEN(new_file); + char *tmp_new_file = ZSTR_VAL(new_file); + if (phar_path_check(&tmp_new_file, &tmp_len, &pcr_error) > pcr_is_ok) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", newfile, pcr_error, oldfile, phar_obj->archive->fname); + "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), phar_obj->archive->fname); RETURN_THROWS(); } - newfile_len = tmp_len; if (phar_obj->archive->is_persistent) { if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { @@ -3466,15 +3461,15 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } /* re-populate with copied-on-write entry */ - oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, oldfile_len); + oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file); } memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info)); phar_metadata_tracker_clone(&newentry.metadata_tracker); - newentry.filename = estrndup(newfile, newfile_len); - newentry.filename_len = newfile_len; + newentry.filename = estrndup(tmp_new_file, tmp_len); + newentry.filename_len = tmp_len; newentry.fp_refcount = 0; if (oldentry->fp_type != PHAR_FP) { @@ -3487,7 +3482,7 @@ PHP_METHOD(Phar, copy) } } - zend_hash_str_add_mem(&oldentry->phar->manifest, newfile, newfile_len, &newentry, sizeof(phar_entry_info)); + zend_hash_str_add_mem(&oldentry->phar->manifest, ZSTR_VAL(new_file), tmp_len, &newentry, sizeof(phar_entry_info)); phar_obj->archive->is_modified = 1; phar_flush(phar_obj->archive, 0, 0, 0, &error); @@ -3503,31 +3498,30 @@ PHP_METHOD(Phar, copy) /* {{{ determines whether a file exists in the phar */ PHP_METHOD(Phar, offsetExists) { - char *fname; - size_t fname_len; + zend_string *file_name; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { + if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_FALSE; } } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { /* none of these are real files, so they don't exist */ RETURN_FALSE; } RETURN_TRUE; } else { - RETURN_BOOL(zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, fname_len)); + RETURN_BOOL(zend_hash_exists(&phar_obj->archive->virtual_dirs, file_name)); } } /* }}} */ @@ -3535,31 +3529,31 @@ PHP_METHOD(Phar, offsetExists) /* {{{ get a PharFileInfo object for a specific file */ PHP_METHOD(Phar, offsetGet) { - char *fname, *error; - size_t fname_len; + char *error; phar_entry_info *entry; + zend_string *file_name = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); /* security is 0 here so that we can get a better error message than "entry doesn't exist" */ - if (!(entry = phar_get_entry_info_dir(phar_obj->archive, fname, fname_len, 1, &error, 0))) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", fname, error?", ":"", error?error:""); + if (!(entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, 0))) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", ZSTR_VAL(file_name), error?", ":"", error?error:""); } else { - if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { + if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot directly get any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3569,7 +3563,7 @@ PHP_METHOD(Phar, offsetGet) efree(entry); } - zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, fname); + zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, ZSTR_VAL(file_name)); zval zfname; ZVAL_NEW_STR(&zfname, sfname); @@ -3584,11 +3578,9 @@ PHP_METHOD(Phar, offsetGet) /* }}} */ /* {{{ add a file within the phar archive from a string or resource */ -static void phar_add_file(phar_archive_data **pphar, char *filename, size_t filename_len, char *cont_str, size_t cont_len, zval *zresource) +static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, const zend_string *content, zval *zresource) { - size_t start_pos=0; char *error; - size_t contents_len; phar_entry_data *data; php_stream *contents_file = NULL; php_stream_statbuf ssb; @@ -3597,14 +3589,21 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, size_t file ALLOCA_FLAG(filename_use_heap) #endif - if (filename_len >= sizeof(".phar")-1) { - start_pos = '/' == filename[0]; /* account for any leading slash: multiple-leads handled elsewhere */ - if (!memcmp(&filename[start_pos], ".phar", sizeof(".phar")-1) && (filename[start_pos+5] == '/' || filename[start_pos+5] == '\\' || filename[start_pos+5] == '\0')) { + if ( + zend_string_starts_with_literal(file_name, ".phar") + || zend_string_starts_with_literal(file_name, "/.phar") + ) { + size_t prefix_len = (ZSTR_VAL(file_name)[0] == '/') + sizeof(".phar")-1; + char next_char = ZSTR_VAL(file_name)[prefix_len]; + if (next_char == '/' || next_char == '\\' || next_char == '\0') { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); return; } } + /* TODO How to handle Windows path normalisation with zend_string ? */ + char *filename = ZSTR_VAL(file_name); + size_t filename_len = ZSTR_LEN(file_name); #ifdef PHP_WIN32 save_filename = filename; if (memchr(filename, '\\', filename_len)) { @@ -3628,9 +3627,11 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, size_t file } if (!data->internal_file->is_dir) { - if (cont_str) { - contents_len = php_stream_write(data->fp, cont_str, cont_len); - if (contents_len != cont_len) { + size_t contents_len = 0; + if (content) { + contents_len = ZSTR_LEN(content); + size_t written_len = php_stream_write(data->fp, ZSTR_VAL(content), ZSTR_LEN(content)); + if (written_len != contents_len) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); goto finish; } @@ -3679,17 +3680,17 @@ finish: ; /* }}} */ /* {{{ create a directory within the phar archive */ -static void phar_mkdir(phar_archive_data **pphar, char *dirname, size_t dirname_len) +static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) { char *error; phar_entry_data *data; - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, dirname, dirname_len, "w+b", 2, &error, 1))) { + if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), "w+b", 2, &error, 1))) { if (error) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", dirname, error); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", ZSTR_VAL(dir_name), error); efree(error); } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created", dirname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created", ZSTR_VAL(dir_name)); } return; @@ -3716,12 +3717,12 @@ static void phar_mkdir(phar_archive_data **pphar, char *dirname, size_t dirname_ /* {{{ set the contents of an internal file to those of an external file */ PHP_METHOD(Phar, offsetSet) { - char *fname, *cont_str = NULL; - size_t fname_len, cont_len; zval *zresource = NULL; + zend_string *file_name = NULL; + zend_string *file_content = NULL; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "pr", &fname, &fname_len, &zresource) == FAILURE - && zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &fname, &fname_len, &cont_str, &cont_len) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "Pr", &file_name, &zresource) == FAILURE + && zend_parse_parameters(ZEND_NUM_ARGS(), "PS", &file_name, &file_content) == FAILURE) { RETURN_THROWS(); } @@ -3732,33 +3733,33 @@ PHP_METHOD(Phar, offsetSet) RETURN_THROWS(); } - if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { + if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } - phar_add_file(&(phar_obj->archive), fname, fname_len, cont_str, cont_len, zresource); + phar_add_file(&(phar_obj->archive), file_name, file_content, zresource); } /* }}} */ /* {{{ remove a file from a phar */ PHP_METHOD(Phar, offsetUnset) { - char *fname, *error; - size_t fname_len; + char *error; + zend_string *file_name; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } @@ -3769,8 +3770,8 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len))) { + if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return; @@ -3782,7 +3783,7 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } /* re-populate entry after copy on write */ - entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, fname_len); + entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); } entry->is_modified = 0; entry->is_deleted = 1; @@ -3801,55 +3802,53 @@ PHP_METHOD(Phar, offsetUnset) /* {{{ Adds an empty directory to the phar archive */ PHP_METHOD(Phar, addEmptyDir) { - char *dirname; - size_t dirname_len; + zend_string *dir_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &dirname, &dirname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &dir_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (dirname_len >= sizeof(".phar")-1 && !memcmp(dirname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(dir_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); RETURN_THROWS(); } - phar_mkdir(&phar_obj->archive, dirname, dirname_len); + phar_mkdir(&phar_obj->archive, dir_name); } /* }}} */ /* {{{ Adds a file to the archive using the filename, or the second parameter as the name within the archive */ PHP_METHOD(Phar, addFile) { - char *fname, *localname = NULL; - size_t fname_len, localname_len = 0; + zend_string *file_name; + zend_string *local_name = NULL; php_stream *resource; zval zresource; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &localname, &localname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &file_name, &local_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (!strstr(fname, "://") && php_check_open_basedir(fname)) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive, open_basedir restrictions prevent this", fname); + if (!strstr(ZSTR_VAL(file_name), "://") && php_check_open_basedir(ZSTR_VAL(file_name))) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive, open_basedir restrictions prevent this", ZSTR_VAL(file_name)); RETURN_THROWS(); } - if (!(resource = php_stream_open_wrapper(fname, "rb", 0, NULL))) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", fname); + if (!(resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL))) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", ZSTR_VAL(file_name)); RETURN_THROWS(); } - if (localname) { - fname = localname; - fname_len = localname_len; + if (local_name) { + file_name = local_name; } php_stream_to_zval(resource, &zresource); - phar_add_file(&(phar_obj->archive), fname, fname_len, NULL, 0, &zresource); + phar_add_file(&(phar_obj->archive), file_name, NULL, &zresource); zval_ptr_dtor(&zresource); } /* }}} */ @@ -3857,16 +3856,16 @@ PHP_METHOD(Phar, addFile) /* {{{ Adds a file to the archive using its contents as a string */ PHP_METHOD(Phar, addFromString) { - char *localname, *cont_str; - size_t localname_len, cont_len; + zend_string *local_name = NULL; + zend_string *file_content = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &localname, &localname_len, &cont_str, &cont_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "PS", &local_name, &file_content) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - phar_add_file(&(phar_obj->archive), localname, localname_len, cont_str, cont_len, NULL); + phar_add_file(&(phar_obj->archive), local_name, file_content, NULL); } /* }}} */ From f9c69bc39272d4ddff995e1e94e60b0c7b68458a Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sat, 17 Aug 2024 00:17:50 +0200 Subject: [PATCH 166/280] ext/phar: Reorganise some headers --- ext/phar/dirstream.h | 2 ++ ext/phar/func_interceptors.c | 2 ++ ext/phar/phar.c | 5 +++++ ext/phar/phar_internal.h | 34 +--------------------------------- ext/phar/phar_object.c | 8 ++++++++ ext/phar/stream.h | 1 + ext/phar/tar.c | 1 + ext/phar/util.c | 3 +++ ext/phar/zip.c | 2 ++ 9 files changed, 25 insertions(+), 33 deletions(-) diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index 4859c69fbe022..4debfecde41a1 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -22,6 +22,8 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); #ifdef PHAR_DIRSTREAM +#include "ext/standard/url.h" + php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); /* directory handlers */ diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 53851abee0dcc..f1b2b0eba1e63 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -17,6 +17,8 @@ */ #include "phar_internal.h" +#include "ext/standard/php_filestat.h" +#include "ext/standard/file.h" /* For php_le_stream_context() */ PHP_FUNCTION(phar_opendir) /* {{{ */ { diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 540e9302fb9cc..99767468ee71c 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -19,9 +19,14 @@ #define PHAR_MAIN 1 #include "phar_internal.h" +#include "php_phar.h" #include "SAPI.h" #include "func_interceptors.h" +#include "ext/standard/crc32.h" #include "ext/standard/php_var.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ +#include "ext/standard/info.h" +#include "zend_smart_str.h" static void destroy_phar_data(zval *zv); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 1226de191542a..eb836ac691adc 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -24,39 +24,9 @@ #include #include "php.h" #include "tar.h" -#include "php_ini.h" -#include "zend_constants.h" -#include "zend_execute.h" -#include "zend_exceptions.h" +#include "pharzip.h" #include "zend_hash.h" -#include "zend_interfaces.h" -#include "zend_operators.h" -#include "zend_sort.h" -#include "zend_vm.h" -#include "zend_smart_str.h" -#include "main/php_streams.h" -#include "main/streams/php_stream_plain_wrapper.h" -#include "main/SAPI.h" -#include "main/php_main.h" -#include "main/php_open_temporary_file.h" -#include "ext/standard/info.h" -#include "ext/standard/basic_functions.h" -#include "ext/standard/file.h" -#include "ext/standard/php_string.h" -#include "ext/standard/url.h" -#include "ext/standard/crc32.h" -#include "ext/standard/md5.h" -#include "ext/standard/sha1.h" -#include "ext/standard/php_var.h" -#include "ext/standard/php_versioning.h" -#include "Zend/zend_virtual_cwd.h" -#include "ext/spl/spl_array.h" #include "ext/spl/spl_directory.h" -#include "ext/spl/spl_exceptions.h" -#include "ext/spl/spl_iterators.h" -#include "php_phar.h" -#include "ext/hash/php_hash.h" -#include "ext/hash/php_hash_sha.h" /* PHP_ because this is public information via MINFO */ #define PHP_PHAR_API_VERSION "1.1.1" @@ -193,8 +163,6 @@ ZEND_EXTERN_MODULE_GLOBALS(phar) ZEND_TSRMLS_CACHE_EXTERN() #endif -#include "pharzip.h" - typedef union _phar_archive_object phar_archive_object; typedef union _phar_entry_object phar_entry_object; diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 5232649d7fed9..e23a3eabc2a0f 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -20,6 +20,14 @@ #include "phar_internal.h" #include "func_interceptors.h" #include "phar_object_arginfo.h" +#include "ext/spl/spl_array.h" +#include "ext/spl/spl_exceptions.h" +#include "ext/spl/spl_iterators.h" +#include "ext/standard/php_var.h" +#include "main/SAPI.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" +#include "zend_exceptions.h" static zend_class_entry *phar_ce_archive; static zend_class_entry *phar_ce_data; diff --git a/ext/phar/stream.h b/ext/phar/stream.h index 732da3a0b3f2c..ce75b70dcba00 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -18,6 +18,7 @@ */ BEGIN_EXTERN_C() +#include "ext/standard/url.h" php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); void phar_entry_remove(phar_entry_data *idata, char **error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 722a34b2300f4..44a8e127e233d 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -18,6 +18,7 @@ */ #include "phar_internal.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ static uint32_t phar_tar_number(const char *buf, size_t len) /* {{{ */ { diff --git a/ext/phar/util.c b/ext/phar/util.c index 0db5b1ae76f3c..e49e15aee9cc2 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -19,7 +19,10 @@ */ #include "phar_internal.h" +#include "php_phar.h" +#include "ext/hash/php_hash.h" /* Needed for PHP_HASH_API in ext/hash/php_hash_sha.h */ #include "ext/hash/php_hash_sha.h" +#include "ext/standard/md5.h" #ifdef PHAR_HAVE_OPENSSL /* OpenSSL includes */ diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 9faf6054aff06..70cdfc9cc1b50 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -17,6 +17,8 @@ */ #include "phar_internal.h" +#include "ext/standard/crc32.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ #define PHAR_GET_16(var) ((uint16_t)((((uint16_t)var[0]) & 0xff) | \ (((uint16_t)var[1]) & 0xff) << 8)) From 7ae7b4e388952c0cf1e7cefb1a47646f9d02e639 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:37:57 +0200 Subject: [PATCH 167/280] Correctly specify secret instead of seed in ext/hash deprecation message (#15557) Reference: https://github.com/php/php-src/commit/74eff98c84b26a8088fb56b5be748a3e0e1da419#r145528001 --- ext/hash/hash_xxhash.c | 2 +- ext/hash/tests/xxh3_convert_secret_to_string.phpt | 2 +- ext/hash/tests/xxhash_secret.phpt | 4 ++-- ext/hash/tests/xxhash_seed_deprecation.phpt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 3f7be880fc832..203f3c7d2d9eb 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -183,7 +183,7 @@ zend_always_inline static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *a return; } else if (_secret) { if (IS_STRING != Z_TYPE_P(_secret)) { - php_error_docref(NULL, E_DEPRECATED, "Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs"); + php_error_docref(NULL, E_DEPRECATED, "Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs"); } zend_string *secret_string = zval_try_get_string(_secret); if (UNEXPECTED(!secret_string)) { diff --git a/ext/hash/tests/xxh3_convert_secret_to_string.phpt b/ext/hash/tests/xxh3_convert_secret_to_string.phpt index a68c4a1422336..a06555e7f73ba 100644 --- a/ext/hash/tests/xxh3_convert_secret_to_string.phpt +++ b/ext/hash/tests/xxh3_convert_secret_to_string.phpt @@ -8,7 +8,7 @@ try { var_dump($x); ?> --EXPECTF-- -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d array(1) { ["secret"]=> int(4) diff --git a/ext/hash/tests/xxhash_secret.phpt b/ext/hash/tests/xxhash_secret.phpt index d450d05786736..4cd6798ef769c 100644 --- a/ext/hash/tests/xxhash_secret.phpt +++ b/ext/hash/tests/xxhash_secret.phpt @@ -49,13 +49,13 @@ foreach (["xxh3", "xxh128"] as $a) { --EXPECTF-- string(67) "xxh3: Only one of seed or secret is to be passed for initialization" -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d string(23) "exception in __toString" string(57) "xxh3: Secret length must be >= 136 bytes, 17 bytes passed" 8028aa834c03557a == 8028aa834c03557a == true string(69) "xxh128: Only one of seed or secret is to be passed for initialization" -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d string(23) "exception in __toString" string(59) "xxh128: Secret length must be >= 136 bytes, 17 bytes passed" 54279097795e7218093a05d4d781cbb9 == 54279097795e7218093a05d4d781cbb9 == true diff --git a/ext/hash/tests/xxhash_seed_deprecation.phpt b/ext/hash/tests/xxhash_seed_deprecation.phpt index 6c9634cade249..773f20a4747bc 100644 --- a/ext/hash/tests/xxhash_seed_deprecation.phpt +++ b/ext/hash/tests/xxhash_seed_deprecation.phpt @@ -23,6 +23,6 @@ Deprecated: hash_init(): Passing a seed of a type other than int is deprecated b Deprecated: hash_init(): Passing a seed of a type other than int is deprecated because it is ignored in %s on line %d -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d From d32b97a1c76c2ac563611cdcd16967b5fe292396 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:38:13 +0200 Subject: [PATCH 168/280] Fix NULL pointer dereference with NULL content in legacy nodes in title getting (#15558) --- ext/dom/html_document.c | 2 +- ext/dom/tests/modern/common/Document_title_getter.phpt | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 18c6c909ad672..55d9fdfe45028 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -1467,7 +1467,7 @@ static zend_string *dom_get_child_text_content(const xmlNode *node) const xmlNode *text = node->children; while (text != NULL) { - if (text->type == XML_TEXT_NODE || text->type == XML_CDATA_SECTION_NODE) { + if ((text->type == XML_TEXT_NODE || text->type == XML_CDATA_SECTION_NODE) && text->content != NULL) { smart_str_appends(&content, (const char *) text->content); } text = text->next; diff --git a/ext/dom/tests/modern/common/Document_title_getter.phpt b/ext/dom/tests/modern/common/Document_title_getter.phpt index eb4f4b7cdb5fd..7aeb95d0efd67 100644 --- a/ext/dom/tests/modern/common/Document_title_getter.phpt +++ b/ext/dom/tests/modern/common/Document_title_getter.phpt @@ -43,6 +43,10 @@ var_dump($dom->title); $dom = Dom\XMLDocument::createFromString("title\nhere"); var_dump($dom->title); +$dom = Dom\XMLDocument::createFromString("</root>"); +$dom->getElementsByTagName('title')[0]->appendChild($dom->importLegacyNode(new DOMText)); +var_dump($dom->title); + echo "=== SVG namespaced root ===\n"; $dom = Dom\XMLDocument::createFromString("<root xmlns=\"http://www.w3.org/1999/xhtml\"><title>title"); @@ -72,6 +76,7 @@ string(0) "" string(2) "xz" string(2) "yw" string(10) "title here" +string(0) "" === SVG namespaced root === string(5) "title" string(5) "title" From 9af574c26e034e5f83cc2a677692b13ba2557904 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:39:06 +0200 Subject: [PATCH 169/280] Fix GH-15551: Segmentation fault (access null pointer) in ext/dom/xml_common.h Closes GH-15556. --- NEWS | 4 ++++ ext/dom/dom_iterators.c | 6 ++++-- ext/dom/tests/gh15551.phpt | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 ext/dom/tests/gh15551.phpt diff --git a/NEWS b/NEWS index 3dfc4308841ec..4653280876c04 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ PHP NEWS . Fixed bug GH-15515 (Configure error grep illegal option q). (Peter Kokot) . Fixed bug GH-15514 (Configure error: genif.sh: syntax error). (Peter Kokot) +- DOM: + . Fixed bug GH-15551 (Segmentation fault (access null pointer) in + ext/dom/xml_common.h). (nielsdos) + - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 866cb5a07e99f..d22cb0699fe59 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -184,13 +184,15 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ bool do_curobj_undef = 1; php_dom_iterator *iterator = (php_dom_iterator *)iter; + if (Z_ISUNDEF(iterator->curobj)) { + return; + } + intern = Z_DOMOBJ_P(&iterator->curobj); object = &iterator->intern.data; nnmap = Z_DOMOBJ_P(object); objmap = (dom_nnodemap_object *)nnmap->ptr; - intern = Z_DOMOBJ_P(&iterator->curobj); - if (intern != NULL && intern->ptr != NULL) { if (objmap->nodetype != XML_ENTITY_NODE && objmap->nodetype != XML_NOTATION_NODE) { diff --git a/ext/dom/tests/gh15551.phpt b/ext/dom/tests/gh15551.phpt new file mode 100644 index 0000000000000..3b4b7d4e85793 --- /dev/null +++ b/ext/dom/tests/gh15551.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h) +--EXTENSIONS-- +dom +--FILE-- +childNodes; +$iter = $nodes->getIterator(); +$iter->next(); +var_dump($iter->valid()); +?> +--EXPECT-- +bool(false) From 01c6b48e319aac9a31456f050bd522b5ffda15f5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 23 Aug 2024 21:06:28 +0100 Subject: [PATCH 170/280] Phar offset exist issue with entry classes not based on PharFileInfo (#14503) * ext/phar: expand test to cover issue with offsetGet * ext/phar: offsetExists should return false when file entry is not based on PharFileInfo --- ext/phar/phar_object.c | 4 ++++ ext/phar/tests/phar_oo_011.phpt | 26 ++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index e23a3eabc2a0f..0d992a6dd7f6a 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3529,6 +3529,10 @@ PHP_METHOD(Phar, offsetExists) } RETURN_TRUE; } else { + /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ + if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { + RETURN_FALSE; + } RETURN_BOOL(zend_hash_exists(&phar_obj->archive->virtual_dirs, file_name)); } } diff --git a/ext/phar/tests/phar_oo_011.phpt b/ext/phar/tests/phar_oo_011.phpt index 85c7575bcc085..98b4c34bd1539 100644 --- a/ext/phar/tests/phar_oo_011.phpt +++ b/ext/phar/tests/phar_oo_011.phpt @@ -13,10 +13,22 @@ $pharconfig = 0; require_once 'files/phar_oo_test.inc'; $phar = new Phar($fname); -$phar->setInfoClass('SplFileObject'); $phar['hi/f.php'] = 'hi'; var_dump(isset($phar['hi'])); +var_dump($phar['hi']); +var_dump(isset($phar['hi/f.php'])); +echo $phar['hi/f.php']; +echo "\n"; + +$phar->setInfoClass('SplFileObject'); +$phar['hi/f.php'] = 'hi'; +var_dump(isset($phar['hi'])); +try { + var_dump($phar['hi']); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} var_dump(isset($phar['hi/f.php'])); echo $phar['hi/f.php']; echo "\n"; @@ -27,7 +39,17 @@ echo "\n"; unlink(__DIR__ . '/files/phar_oo_011.phar.php'); __halt_compiler(); ?> ---EXPECT-- +--EXPECTF-- +bool(true) +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%s/phar_oo_011.phar.php/hi" + ["fileName":"SplFileInfo":private]=> + string(2) "hi" +} bool(true) +phar://%s/phar_oo_011.phar.php/hi/f.php +bool(false) +LogicException: Cannot use SplFileObject with directories bool(true) hi From 2e3132b3fd1cea68871b863deea30cfda23726ef Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 23 Aug 2024 22:30:09 +0200 Subject: [PATCH 171/280] Autotools: Sync CS in ext/standard (#15560) - Overquoted arguments reduced - Added missing quotes in algorithms checks - Synced indentations for algorithms checks --- ext/standard/config.m4 | 103 +++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 60 deletions(-) diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 5975cc2936c11..90a3cbd3166ab 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -104,8 +104,8 @@ AC_SEARCH_LIBS([crypt_r], [crypt], PHP_CRYPT_R_STYLE AC_CHECK_HEADERS([crypt.h]) - AC_CACHE_CHECK(for standard DES crypt, ac_cv_crypt_des,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +AC_CACHE_CHECK([for standard DES crypt], [ac_cv_crypt_des], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifdef HAVE_UNISTD_H #include #endif @@ -120,16 +120,13 @@ AC_CHECK_HEADERS([crypt.h]) int main(void) { char *encrypted = crypt("rasmuslerdorf","rl"); return !encrypted || strcmp(encrypted,"rl.3StKT.4T8M"); -}]])],[ - ac_cv_crypt_des=yes -],[ - ac_cv_crypt_des=no -],[ - ac_cv_crypt_des=yes -])]) - - AC_CACHE_CHECK(for extended DES crypt, ac_cv_crypt_ext_des,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}])], + [ac_cv_crypt_des=yes], + [ac_cv_crypt_des=no], + [ac_cv_crypt_des=yes])]) + +AC_CACHE_CHECK([for extended DES crypt], [ac_cv_crypt_ext_des], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifdef HAVE_UNISTD_H #include #endif @@ -144,16 +141,13 @@ int main(void) { int main(void) { char *encrypted = crypt("rasmuslerdorf","_J9..rasm"); return !encrypted || strcmp(encrypted,"_J9..rasmBYk8r9AiWNc"); -}]])],[ - ac_cv_crypt_ext_des=yes - ],[ - ac_cv_crypt_ext_des=no - ],[ - ac_cv_crypt_ext_des=no - ])]) - - AC_CACHE_CHECK(for MD5 crypt, ac_cv_crypt_md5,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}])], + [ac_cv_crypt_ext_des=yes], + [ac_cv_crypt_ext_des=no], + [ac_cv_crypt_ext_des=no])]) + +AC_CACHE_CHECK([for MD5 crypt], [ac_cv_crypt_md5], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -178,16 +172,13 @@ int main(void) { strcat(answer,"rISCgZzpwk3UhDidwXvin0"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_md5=yes - ],[ - ac_cv_crypt_md5=no - ],[ - ac_cv_crypt_md5=no - ])]) - - AC_CACHE_CHECK(for Blowfish crypt, ac_cv_crypt_blowfish,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_md5=yes], + [ac_cv_crypt_md5=no], + [ac_cv_crypt_md5=no])]) + +AC_CACHE_CHECK([for Blowfish crypt], [ac_cv_crypt_blowfish], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -203,22 +194,20 @@ int main(void) { char salt[30], answer[70]; char *encrypted; - salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0'; + salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; + salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0'; strcat(salt,"rasmuslerd............"); strcpy(answer,salt); strcpy(&answer[29],"nIdrcHdxcUxWomQX9j6kvERCFjTg7Ra"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_blowfish=yes - ],[ - ac_cv_crypt_blowfish=no - ],[ - ac_cv_crypt_blowfish=no - ])]) - - AC_CACHE_CHECK(for SHA512 crypt, ac_cv_crypt_sha512,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_blowfish=yes], + [ac_cv_crypt_blowfish=no], + [ac_cv_crypt_blowfish=no])]) + +AC_CACHE_CHECK([for SHA512 crypt], [ac_cv_crypt_sha512], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -239,16 +228,13 @@ int main(void) { strcat(answer, "EeHCRjm0bljalWuALHSTs1NB9ipEiLEXLhYeXdOpx22gmlmVejnVXFhd84cEKbYxCo.XuUTrW.RLraeEnsvWs/"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); - }]])],[ - ac_cv_crypt_sha512=yes - ],[ - ac_cv_crypt_sha512=no - ],[ - ac_cv_crypt_sha512=no - ])]) - - AC_CACHE_CHECK(for SHA256 crypt, ac_cv_crypt_sha256,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_sha512=yes], + [ac_cv_crypt_sha512=no], + [ac_cv_crypt_sha512=no])]) + +AC_CACHE_CHECK([for SHA256 crypt], [ac_cv_crypt_sha256], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -269,13 +255,10 @@ int main(void) { strcat(answer, "cFAm2puLCujQ9t.0CxiFIIvFi4JyQx5UncCt/xRIX23"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_sha256=yes - ],[ - ac_cv_crypt_sha256=no - ],[ - ac_cv_crypt_sha256=no - ])]) +}]])], + [ac_cv_crypt_sha256=yes], + [ac_cv_crypt_sha256=no], + [ac_cv_crypt_sha256=no])]) if test "$ac_cv_crypt_blowfish" = "no" || test "$ac_cv_crypt_des" = "no" || test "$ac_cv_crypt_ext_des" = "no" || test "$ac_cv_crypt_md5" = "no" || test "$ac_cv_crypt_sha512" = "no" || test "$ac_cv_crypt_sha256" = "no"; then AC_MSG_FAILURE([Cannot use external libcrypt as some algo are missing.]) From 2cbde5ae775f4dfaf5ef96aa39e0f8b754370baa Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 23 Aug 2024 22:35:59 +0200 Subject: [PATCH 172/280] Autotools: Use a no-op command in PKG_CHECK_MODULES (#15562) Instead of using a space for the "do nothing" command in the PKG_CHECK_MODULES 2nd argument when libexslt is not found, the no-op command ":" is perhaps a bit clearer and is in most cases used in such scenarios and macro arguments. --- ext/xsl/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4 index 2b8c851b3add8..ac52dc8c1ce95 100644 --- a/ext/xsl/config.m4 +++ b/ext/xsl/config.m4 @@ -15,7 +15,7 @@ if test "$PHP_XSL" != "no"; then PHP_EVAL_LIBLINE([$EXSLT_LIBS], [XSL_SHARED_LIBADD]) AC_DEFINE([HAVE_XSL_EXSLT], [1], [Define to 1 if the system has the EXSLT extension library for XSLT.]) - ], [ ]) + ], [:]) AC_DEFINE([HAVE_XSL], [1], [Define to 1 if the PHP extension 'xsl' is available.]) From dc8f18af0b1b88aac423833b9d48605828113020 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 23 Aug 2024 23:14:38 +0200 Subject: [PATCH 173/280] Fix GH-15534: Bump minimum libxml2 version to 2.9.4 (#15536) The xmlDictPtr was moved before the includes in libxml2 2.9.4 so the can be included directly but for earlier versions the needs to be included before. Since PHP requires libxml2 2.9.0 or later and this also fixes builds on Solaris 10. As earlier 2.9.0-2.9.3 libxml2 versions also include several security issues, this change bumps the required minimum libxml2 version to 2.9.4 On Windows, a check for minimum libxml2 version is also added. Co-authored-by: Christoph M. Becker --- UPGRADING | 3 +++ UPGRADING.INTERNALS | 2 +- build/php.m4 | 2 +- ext/libxml/config.w32 | 18 ++++++++++++------ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/UPGRADING b/UPGRADING index e284abc970944..2107a07472584 100644 --- a/UPGRADING +++ b/UPGRADING @@ -871,6 +871,9 @@ PHP 8.4 UPGRADE NOTES $domain name is empty or too long, and if $variant is not INTL_IDNA_VARIANT_UTS46. +- LibXML: + . The libxml extension now requires at least libxml2 2.9.4. + - MBString: . Unicode data tables have been updated to Unicode 15.1. diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index a23cdcf401c9a..85b0da4cf00cc 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -178,7 +178,7 @@ PHP 8.4 INTERNALS UPGRADE NOTES - M4 macro PHP_EVAL_LIBLINE got a new 3rd argument to override the ext_shared checks. - M4 macro PHP_SETUP_LIBXML doesn't define the redundant HAVE_LIBXML symbol - anymore. + anymore and requires at least libxml2 2.9.4. - M4 macro PHP_SETUP_ICONV doesn't define the HAVE_ICONV symbol anymore. - M4 macro PHP_OUTPUT is obsolete (use AC_CONFIG_FILES). - M4 macro PHP_PROG_SETUP now accepts an argument to set the minimum required diff --git a/build/php.m4 b/build/php.m4 index 4c4ba44708b7d..442779ba734b4 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -1912,7 +1912,7 @@ dnl dnl Common setup macro for libxml. dnl AC_DEFUN([PHP_SETUP_LIBXML], [ - PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.9.0]) + PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.9.4]) PHP_EVAL_INCLINE([$LIBXML_CFLAGS]) PHP_EVAL_LIBLINE([$LIBXML_LIBS], [$1]) $2 diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index 416ae1f136637..d836f0efcba7f 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -9,13 +9,19 @@ if (PHP_LIBXML == "yes") { CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && ADD_EXTENSION_DEP('libxml', 'iconv')) { - EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); - ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); - if (!PHP_LIBXML_SHARED) { - ADD_DEF_FILE("ext\\libxml\\php_libxml2.def"); + if (GREP_HEADER("libxml/xmlversion.h", "#define\\s+LIBXML_VERSION\\s+(\\d+)", PHP_PHP_BUILD + "\\include\\libxml2") && + +RegExp.$1 >= 20904) { + + EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); + ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); + if (!PHP_LIBXML_SHARED) { + ADD_DEF_FILE("ext\\libxml\\php_libxml2.def"); + } + PHP_INSTALL_HEADERS("ext/libxml", "php_libxml.h"); + } else { + WARNING("libxml support can't be enabled, libxml version >= 2.9.4 required"); } - PHP_INSTALL_HEADERS("ext/libxml", "php_libxml.h"); } else { WARNING("libxml support can't be enabled, iconv or libxml are missing") PHP_LIBXML = "no" From 6351468a5e58ecf31824f8f68473de43958f5d0b Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 24 Aug 2024 00:49:13 +0200 Subject: [PATCH 174/280] Autotools: Replace break 2 with break (#15563) As there is not nested loop here, a single break can do as well. --- ext/mysqli/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index 631005b64c9be..9f534f29d26ad 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -13,7 +13,7 @@ AC_DEFUN([PHP_MYSQL_SOCKET_SEARCH], [ ; do if test -r $i; then MYSQL_SOCK=$i - break 2 + break fi done From 8d12f666ae4ca5f9506c58ae8428a0eb11b8cd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sat, 24 Aug 2024 12:36:54 +0200 Subject: [PATCH 175/280] Fix registration of internal readonly child classes (#15459) Currently, internal classes are registered with the following code: INIT_CLASS_ENTRY(ce, "InternalClass", class_InternalClass_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ...; This has worked well so far, except if InternalClass is readonly. It is because some inheritance checks are run by zend_register_internal_class_ex before ZEND_ACC_READONLY_CLASS is added to ce_flags. The issue is fixed by adding a zend_register_internal_class_with_flags() zend API function that stubs can use from now on. This function makes sure to add the flags before running any checks. Since the new API is not available in lower PHP versions, gen_stub.php has to keep support for the existing API for PHP 8.3 and below. --- Zend/zend_API.c | 12 ++- Zend/zend_API.h | 1 + Zend/zend_attributes_arginfo.h | 21 ++-- Zend/zend_builtin_functions_arginfo.h | 3 +- Zend/zend_closures_arginfo.h | 3 +- Zend/zend_exceptions_arginfo.h | 24 ++--- Zend/zend_fibers_arginfo.h | 6 +- Zend/zend_generators_arginfo.h | 5 +- Zend/zend_interfaces_arginfo.h | 3 +- Zend/zend_weakrefs_arginfo.h | 6 +- build/gen_stub.php | 29 ++++- ext/com_dotnet/com_extension_arginfo.h | 13 +-- ext/com_dotnet/com_persist_arginfo.h | 3 +- ext/curl/curl_arginfo.h | 9 +- ext/curl/curl_file_arginfo.h | 5 +- ext/date/php_date_arginfo.h | 37 +++---- ext/dba/dba_arginfo.h | 3 +- ext/dom/php_dom_arginfo.h | 100 ++++++++---------- ext/enchant/enchant_arginfo.h | 6 +- ext/ffi/ffi_arginfo.h | 14 +-- ext/fileinfo/fileinfo_arginfo.h | 3 +- ext/ftp/ftp_arginfo.h | 3 +- ext/gd/gd_arginfo.h | 6 +- ext/gmp/gmp_arginfo.h | 3 +- ext/hash/hash_arginfo.h | 3 +- .../breakiterator/breakiterator_arginfo.h | 9 +- .../breakiterator_iterators_arginfo.h | 3 +- ext/intl/calendar/calendar_arginfo.h | 6 +- ext/intl/collator/collator_arginfo.h | 3 +- ext/intl/common/common_arginfo.h | 3 +- ext/intl/converter/converter_arginfo.h | 3 +- ext/intl/dateformat/dateformat_arginfo.h | 3 +- .../dateformat/datepatterngenerator_arginfo.h | 3 +- ext/intl/formatter/formatter_arginfo.h | 3 +- ext/intl/locale/locale_arginfo.h | 2 +- ext/intl/msgformat/msgformat_arginfo.h | 3 +- ext/intl/normalizer/normalizer_arginfo.h | 2 +- ext/intl/php_intl_arginfo.h | 2 +- .../resourcebundle/resourcebundle_arginfo.h | 3 +- ext/intl/spoofchecker/spoofchecker_arginfo.h | 3 +- ext/intl/timezone/timezone_arginfo.h | 3 +- .../transliterator/transliterator_arginfo.h | 3 +- ext/intl/uchar/uchar_arginfo.h | 2 +- ext/json/json_arginfo.h | 2 +- ext/ldap/ldap_arginfo.h | 9 +- ext/libxml/libxml_arginfo.h | 2 +- ext/mysqli/mysqli_arginfo.h | 15 ++- ext/odbc/odbc_arginfo.h | 6 +- ext/openssl/openssl_arginfo.h | 9 +- ext/pdo/pdo_arginfo.h | 2 +- ext/pdo/pdo_dbh_arginfo.h | 3 +- ext/pdo/pdo_stmt_arginfo.h | 6 +- ext/pdo_dblib/pdo_dblib_arginfo.h | 3 +- ext/pdo_firebird/pdo_firebird_arginfo.h | 3 +- ext/pdo_mysql/pdo_mysql_arginfo.h | 3 +- ext/pdo_odbc/pdo_odbc_arginfo.h | 3 +- ext/pdo_pgsql/pdo_pgsql_arginfo.h | 3 +- ext/pdo_sqlite/pdo_sqlite_arginfo.h | 3 +- ext/pgsql/pgsql_arginfo.h | 9 +- ext/phar/phar_object_arginfo.h | 8 +- ext/random/random_arginfo.h | 24 ++--- ext/reflection/php_reflection_arginfo.h | 61 +++++------ ext/session/session_arginfo.h | 2 +- ext/shmop/shmop_arginfo.h | 3 +- ext/simplexml/simplexml_arginfo.h | 5 +- ext/snmp/snmp_arginfo.h | 4 +- ext/soap/soap_arginfo.h | 18 ++-- ext/sockets/sockets_arginfo.h | 6 +- ext/sodium/libsodium_arginfo.h | 2 +- ext/spl/spl_array_arginfo.h | 6 +- ext/spl/spl_directory_arginfo.h | 15 ++- ext/spl/spl_dllist_arginfo.h | 6 +- ext/spl/spl_exceptions_arginfo.h | 26 ++--- ext/spl/spl_fixedarray_arginfo.h | 2 +- ext/spl/spl_heap_arginfo.h | 9 +- ext/spl/spl_iterators_arginfo.h | 36 +++---- ext/spl/spl_observer_arginfo.h | 4 +- ext/sqlite3/sqlite3_arginfo.h | 12 +-- ext/standard/basic_functions_arginfo.h | 5 +- ext/standard/dir_arginfo.h | 2 +- ext/standard/user_filters_arginfo.h | 5 +- ext/sysvmsg/sysvmsg_arginfo.h | 3 +- ext/sysvsem/sysvsem_arginfo.h | 3 +- ext/sysvshm/sysvshm_arginfo.h | 3 +- ext/tidy/tidy_arginfo.h | 5 +- ext/tokenizer/tokenizer_arginfo.h | 2 +- ext/xml/xml_arginfo.h | 3 +- ext/xmlreader/php_xmlreader_arginfo.h | 2 +- ext/xmlwriter/php_xmlwriter_arginfo.h | 2 +- ext/xsl/php_xsl_arginfo.h | 2 +- ext/zend_test/fiber_arginfo.h | 3 +- ext/zend_test/iterators_arginfo.h | 3 +- ext/zend_test/object_handlers_arginfo.h | 14 +-- ext/zend_test/test_arginfo.h | 76 +++++++++++++ ext/zip/php_zip_arginfo.h | 2 +- ext/zlib/zlib_arginfo.h | 6 +- 96 files changed, 405 insertions(+), 446 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b5ca938865893..27a914aab9e6b 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3493,9 +3493,16 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class */ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */ { - zend_class_entry *register_class; + return zend_register_internal_class_with_flags(class_entry, parent_ce, 0); +} +/* }}} */ - register_class = zend_register_internal_class(class_entry); +ZEND_API zend_class_entry *zend_register_internal_class_with_flags( + zend_class_entry *class_entry, + zend_class_entry *parent_ce, + uint32_t ce_flags +) { + zend_class_entry *register_class = do_register_internal_class(class_entry, ce_flags); if (parent_ce) { zend_do_inheritance(register_class, parent_ce); @@ -3504,7 +3511,6 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla return register_class; } -/* }}} */ ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...) /* {{{ */ { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index cbb9ec163f3c4..f9fe81d50dd4f 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -390,6 +390,7 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry); ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce); +ZEND_API zend_class_entry *zend_register_internal_class_with_flags(zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t flags); ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry); ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...); diff --git a/Zend/zend_attributes_arginfo.h b/Zend/zend_attributes_arginfo.h index 2a8022d0bd181..817dacbd44d50 100644 --- a/Zend/zend_attributes_arginfo.h +++ b/Zend/zend_attributes_arginfo.h @@ -81,8 +81,7 @@ static zend_class_entry *register_class_Attribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Attribute", class_Attribute_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval const_TARGET_CLASS_value; ZVAL_LONG(&const_TARGET_CLASS_value, ZEND_ATTRIBUTE_TARGET_CLASS); @@ -153,8 +152,7 @@ static zend_class_entry *register_class_ReturnTypeWillChange(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReturnTypeWillChange", class_ReturnTypeWillChange_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_string *attribute_name_Attribute_class_ReturnTypeWillChange_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ReturnTypeWillChange_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ReturnTypeWillChange_0, 1); @@ -171,8 +169,7 @@ static zend_class_entry *register_class_AllowDynamicProperties(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AllowDynamicProperties", class_AllowDynamicProperties_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_string *attribute_name_Attribute_class_AllowDynamicProperties_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_AllowDynamicProperties_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_AllowDynamicProperties_0, 1); @@ -189,8 +186,7 @@ static zend_class_entry *register_class_SensitiveParameter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SensitiveParameter", class_SensitiveParameter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_string *attribute_name_Attribute_class_SensitiveParameter_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_SensitiveParameter_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_SensitiveParameter_0, 1); @@ -207,8 +203,7 @@ static zend_class_entry *register_class_SensitiveParameterValue(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SensitiveParameterValue", class_SensitiveParameterValue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); @@ -224,8 +219,7 @@ static zend_class_entry *register_class_Override(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Override", class_Override_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_Override_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Override_0, 1); @@ -242,8 +236,7 @@ static zend_class_entry *register_class_Deprecated(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Deprecated", class_Deprecated_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval property_message_default_value; ZVAL_UNDEF(&property_message_default_value); diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index b6b9b8753a450..612fd1d275d55 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -373,8 +373,7 @@ static zend_class_entry *register_class_stdClass(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "stdClass", class_stdClass_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); zend_string *attribute_name_AllowDynamicProperties_class_stdClass_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class_stdClass_0, 0); diff --git a/Zend/zend_closures_arginfo.h b/Zend/zend_closures_arginfo.h index dfd70418620bd..57066078a8821 100644 --- a/Zend/zend_closures_arginfo.h +++ b/Zend/zend_closures_arginfo.h @@ -44,8 +44,7 @@ static zend_class_entry *register_class_Closure(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Closure", class_Closure_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index 7899877f53046..5dc7d7ac3f45f 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -194,7 +194,7 @@ static zend_class_entry *register_class_Exception(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Throwable); zval property_message_default_value; @@ -248,7 +248,7 @@ static zend_class_entry *register_class_ErrorException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); zval property_severity_default_value; ZVAL_LONG(&property_severity_default_value, E_ERROR); @@ -264,7 +264,7 @@ static zend_class_entry *register_class_Error(zend_class_entry *class_entry_Thro zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Error", class_Error_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Throwable); zval property_message_default_value; @@ -318,7 +318,7 @@ static zend_class_entry *register_class_CompileError(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -328,7 +328,7 @@ static zend_class_entry *register_class_ParseError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CompileError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CompileError, 0); return class_entry; } @@ -338,7 +338,7 @@ static zend_class_entry *register_class_TypeError(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -348,7 +348,7 @@ static zend_class_entry *register_class_ArgumentCountError(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_TypeError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_TypeError, 0); return class_entry; } @@ -358,7 +358,7 @@ static zend_class_entry *register_class_ValueError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -368,7 +368,7 @@ static zend_class_entry *register_class_ArithmeticError(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -378,7 +378,7 @@ static zend_class_entry *register_class_DivisionByZeroError(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ArithmeticError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ArithmeticError, 0); return class_entry; } @@ -388,7 +388,7 @@ static zend_class_entry *register_class_UnhandledMatchError(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnhandledMatchError", class_UnhandledMatchError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -398,7 +398,7 @@ static zend_class_entry *register_class_RequestParseBodyException(zend_class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RequestParseBodyException", class_RequestParseBodyException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/Zend/zend_fibers_arginfo.h b/Zend/zend_fibers_arginfo.h index 950dbd26ed60f..9db4db8d802af 100644 --- a/Zend/zend_fibers_arginfo.h +++ b/Zend/zend_fibers_arginfo.h @@ -75,8 +75,7 @@ static zend_class_entry *register_class_Fiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Fiber", class_Fiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -86,8 +85,7 @@ static zend_class_entry *register_class_FiberError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FiberError", class_FiberError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_FINAL); return class_entry; } diff --git a/Zend/zend_generators_arginfo.h b/Zend/zend_generators_arginfo.h index be7131fc8ff26..dd8200d4719af 100644 --- a/Zend/zend_generators_arginfo.h +++ b/Zend/zend_generators_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_Generator(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Generator", class_Generator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; @@ -71,7 +70,7 @@ static zend_class_entry *register_class_ClosedGeneratorException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ClosedGeneratorException", class_ClosedGeneratorException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/Zend/zend_interfaces_arginfo.h b/Zend/zend_interfaces_arginfo.h index bcdc8dd87c473..27af62825f90a 100644 --- a/Zend/zend_interfaces_arginfo.h +++ b/Zend/zend_interfaces_arginfo.h @@ -198,8 +198,7 @@ static zend_class_entry *register_class_InternalIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InternalIterator", class_InternalIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; diff --git a/Zend/zend_weakrefs_arginfo.h b/Zend/zend_weakrefs_arginfo.h index 25c137c9d76b6..eba02f03fb13c 100644 --- a/Zend/zend_weakrefs_arginfo.h +++ b/Zend/zend_weakrefs_arginfo.h @@ -66,8 +66,7 @@ static zend_class_entry *register_class_WeakReference(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "WeakReference", class_WeakReference_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -77,8 +76,7 @@ static zend_class_entry *register_class_WeakMap(zend_class_entry *class_entry_Ar zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "WeakMap", class_WeakMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 3, class_entry_ArrayAccess, class_entry_Countable, class_entry_IteratorAggregate); return class_entry; diff --git a/build/gen_stub.php b/build/gen_stub.php index 1d92ddd46b9ee..2b6af02e190f2 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -3274,11 +3274,18 @@ public function getRegistration(array $allConstInfos): string $code .= "static zend_class_entry *register_class_$escapedName(" . (empty($params) ? "void" : implode(", ", $params)) . ")\n"; $code .= "{\n"; + + $flagCodes = generateVersionDependentFlagCode("%s", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); + $flags = implode("", $flagCodes); + if ($this->type === "enum") { $name = addslashes((string) $this->name); $backingType = $this->enumBackingType ? $this->enumBackingType->toTypeCode() : "IS_UNDEF"; $code .= "\tzend_class_entry *class_entry = zend_register_internal_enum(\"$name\", $backingType, class_{$escapedName}_methods);\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags\n"; + } } else { $code .= "\tzend_class_entry ce, *class_entry;\n\n"; if (count($this->name->getParts()) > 1) { @@ -3291,15 +3298,29 @@ public function getRegistration(array $allConstInfos): string } if ($this->type === "class" || $this->type === "trait") { - $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; + if (!$php84MinimumCompatibility) { + $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; + } + + $code .= "\tclass_entry = zend_register_internal_class_with_flags(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ", " . ($flags ?: 0) . ");\n"; + + if (!$php84MinimumCompatibility) { + $code .= "#else\n"; + + $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags;\n"; + } + $code .= "#endif\n"; + } } else { $code .= "\tclass_entry = zend_register_internal_interface(&ce);\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags\n"; + } } } - $flagCodes = generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); - $code .= implode("", $flagCodes); - if ($this->exposedDocComment) { if (!$php84MinimumCompatibility) { $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; diff --git a/ext/com_dotnet/com_extension_arginfo.h b/ext/com_dotnet/com_extension_arginfo.h index 1f9fd27b6d164..c86ca50d99e84 100644 --- a/ext/com_dotnet/com_extension_arginfo.h +++ b/ext/com_dotnet/com_extension_arginfo.h @@ -300,8 +300,7 @@ static zend_class_entry *register_class_variant(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "variant", class_variant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -311,7 +310,7 @@ static zend_class_entry *register_class_com(zend_class_entry *class_entry_varian zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com", class_com_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_variant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_variant, 0); return class_entry; } @@ -322,7 +321,7 @@ static zend_class_entry *register_class_dotnet(zend_class_entry *class_entry_var zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "dotnet", class_dotnet_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_variant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_variant, 0); return class_entry; } @@ -333,8 +332,7 @@ static zend_class_entry *register_class_com_safearray_proxy(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com_safearray_proxy", class_com_safearray_proxy_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } @@ -344,8 +342,7 @@ static zend_class_entry *register_class_com_exception(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com_exception", class_com_exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/com_dotnet/com_persist_arginfo.h b/ext/com_dotnet/com_persist_arginfo.h index 6867cff30a41b..4449396e9ccef 100644 --- a/ext/com_dotnet/com_persist_arginfo.h +++ b/ext/com_dotnet/com_persist_arginfo.h @@ -56,8 +56,7 @@ static zend_class_entry *register_class_COMPersistHelper(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "COMPersistHelper", class_COMPersistHelper_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index 3bb825af8d146..c1cedaa6acb36 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1099,8 +1099,7 @@ static zend_class_entry *register_class_CurlHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlHandle", class_CurlHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1110,8 +1109,7 @@ static zend_class_entry *register_class_CurlMultiHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlMultiHandle", class_CurlMultiHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1121,8 +1119,7 @@ static zend_class_entry *register_class_CurlShareHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlShareHandle", class_CurlShareHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/curl/curl_file_arginfo.h b/ext/curl/curl_file_arginfo.h index 3f7d20466dbc9..bbf6900546a15 100644 --- a/ext/curl/curl_file_arginfo.h +++ b/ext/curl/curl_file_arginfo.h @@ -56,8 +56,7 @@ static zend_class_entry *register_class_CURLFile(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CURLFile", class_CURLFile_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval property_name_default_value; ZVAL_EMPTY_STRING(&property_name_default_value); @@ -85,7 +84,7 @@ static zend_class_entry *register_class_CURLStringFile(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CURLStringFile", class_CURLStringFile_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 9f7fd234dc647..8f92080015f9e 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1011,7 +1011,7 @@ static zend_class_entry *register_class_DateTime(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTime", class_DateTime_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_DateTimeInterface); return class_entry; @@ -1022,7 +1022,7 @@ static zend_class_entry *register_class_DateTimeImmutable(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTimeImmutable", class_DateTimeImmutable_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_DateTimeInterface); return class_entry; @@ -1033,7 +1033,7 @@ static zend_class_entry *register_class_DateTimeZone(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTimeZone", class_DateTimeZone_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_AFRICA_value; ZVAL_LONG(&const_AFRICA_value, PHP_DATE_TIMEZONE_GROUP_AFRICA); @@ -1127,7 +1127,7 @@ static zend_class_entry *register_class_DateInterval(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInterval", class_DateInterval_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -1137,7 +1137,7 @@ static zend_class_entry *register_class_DatePeriod(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DatePeriod", class_DatePeriod_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval const_EXCLUDE_START_DATE_value; @@ -1206,8 +1206,7 @@ static zend_class_entry *register_class_DateError(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateError", class_DateError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1217,8 +1216,7 @@ static zend_class_entry *register_class_DateObjectError(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateObjectError", class_DateObjectError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1228,8 +1226,7 @@ static zend_class_entry *register_class_DateRangeError(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateRangeError", class_DateRangeError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1239,8 +1236,7 @@ static zend_class_entry *register_class_DateException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateException", class_DateException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1250,8 +1246,7 @@ static zend_class_entry *register_class_DateInvalidTimeZoneException(zend_class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInvalidTimeZoneException", class_DateInvalidTimeZoneException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1261,8 +1256,7 @@ static zend_class_entry *register_class_DateInvalidOperationException(zend_class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInvalidOperationException", class_DateInvalidOperationException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1272,8 +1266,7 @@ static zend_class_entry *register_class_DateMalformedStringException(zend_class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedStringException", class_DateMalformedStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1283,8 +1276,7 @@ static zend_class_entry *register_class_DateMalformedIntervalStringException(zen zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedIntervalStringException", class_DateMalformedIntervalStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1294,8 +1286,7 @@ static zend_class_entry *register_class_DateMalformedPeriodStringException(zend_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedPeriodStringException", class_DateMalformedPeriodStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } diff --git a/ext/dba/dba_arginfo.h b/ext/dba/dba_arginfo.h index 0d703289de1a8..15b30978fcbc9 100644 --- a/ext/dba/dba_arginfo.h +++ b/ext/dba/dba_arginfo.h @@ -114,8 +114,7 @@ static zend_class_entry *register_class_Dba_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dba", "Connection", class_Dba_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index 08bc3ad1f645c..c87020e700942 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -2006,7 +2006,7 @@ static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocumentType", class_DOMDocumentType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -2054,7 +2054,7 @@ static zend_class_entry *register_class_DOMCdataSection(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMCdataSection", class_DOMCdataSection_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMText); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMText, 0); return class_entry; } @@ -2064,7 +2064,7 @@ static zend_class_entry *register_class_DOMComment(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMComment", class_DOMComment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMCharacterData, 0); return class_entry; } @@ -2094,7 +2094,7 @@ static zend_class_entry *register_class_DOMNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNode", class_DOMNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_DOCUMENT_POSITION_DISCONNECTED_value; ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1); @@ -2257,7 +2257,7 @@ static zend_class_entry *register_class_DOMNameSpaceNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNameSpaceNode", class_DOMNameSpaceNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); @@ -2330,7 +2330,7 @@ static zend_class_entry *register_class_DOMImplementation(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMImplementation", class_DOMImplementation_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -2340,7 +2340,7 @@ static zend_class_entry *register_class_DOMDocumentFragment(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocumentFragment", class_DOMDocumentFragment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMParentNode); zval property_firstElementChild_default_value; @@ -2371,7 +2371,7 @@ static zend_class_entry *register_class_DOMNodeList(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNodeList", class_DOMNodeList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -2388,7 +2388,7 @@ static zend_class_entry *register_class_DOMCharacterData(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMCharacterData", class_DOMCharacterData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMChildNode); zval property_data_default_value; @@ -2425,7 +2425,7 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMAttr", class_DOMAttr_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -2466,7 +2466,7 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMElement", class_DOMElement_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 2, class_entry_DOMParentNode, class_entry_DOMChildNode); zval property_tagName_default_value; @@ -2535,7 +2535,7 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocument", class_DOMDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMParentNode); zval property_doctype_default_value; @@ -2683,8 +2683,7 @@ static zend_class_entry *register_class_DOMException(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMException", class_DOMException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_FINAL); zend_register_class_alias("Dom\\DOMException", class_entry); zval property_code_default_value; @@ -2701,7 +2700,7 @@ static zend_class_entry *register_class_DOMText(zend_class_entry *class_entry_DO zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMText", class_DOMText_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMCharacterData, 0); zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); @@ -2717,7 +2716,7 @@ static zend_class_entry *register_class_DOMNamedNodeMap(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", class_DOMNamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -2734,7 +2733,7 @@ static zend_class_entry *register_class_DOMEntity(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMEntity", class_DOMEntity_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); @@ -2780,7 +2779,7 @@ static zend_class_entry *register_class_DOMEntityReference(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMEntityReference", class_DOMEntityReference_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); return class_entry; } @@ -2790,7 +2789,7 @@ static zend_class_entry *register_class_DOMNotation(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNotation", class_DOMNotation_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); @@ -2812,7 +2811,7 @@ static zend_class_entry *register_class_DOMProcessingInstruction(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMProcessingInstruction", class_DOMProcessingInstruction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); @@ -2835,8 +2834,7 @@ static zend_class_entry *register_class_DOMXPath(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMXPath", class_DOMXPath_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval property_document_default_value; ZVAL_UNDEF(&property_document_default_value); @@ -2880,8 +2878,7 @@ static zend_class_entry *register_class_Dom_Implementation(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Implementation", class_Dom_Implementation_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -2891,8 +2888,7 @@ static zend_class_entry *register_class_Dom_Node(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Node", class_Dom_Node_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval const_DOCUMENT_POSITION_DISCONNECTED_value; ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1); @@ -3030,7 +3026,7 @@ static zend_class_entry *register_class_Dom_NodeList(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NodeList", class_Dom_NodeList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -3047,7 +3043,7 @@ static zend_class_entry *register_class_Dom_NamedNodeMap(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NamedNodeMap", class_Dom_NamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -3064,7 +3060,7 @@ static zend_class_entry *register_class_Dom_DtdNamedNodeMap(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DtdNamedNodeMap", class_Dom_DtdNamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -3081,7 +3077,7 @@ static zend_class_entry *register_class_Dom_HTMLCollection(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLCollection", class_Dom_HTMLCollection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; @@ -3125,7 +3121,7 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Element", class_Dom_Element_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 2, class_entry_Dom_ParentNode, class_entry_Dom_ChildNode); zval property_namespaceURI_default_value; @@ -3232,7 +3228,7 @@ static zend_class_entry *register_class_Dom_HTMLElement(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLElement", class_Dom_HTMLElement_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Element); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Element, 0); return class_entry; } @@ -3242,7 +3238,7 @@ static zend_class_entry *register_class_Dom_Attr(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Attr", class_Dom_Attr_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); @@ -3295,7 +3291,7 @@ static zend_class_entry *register_class_Dom_CharacterData(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "CharacterData", class_Dom_CharacterData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ChildNode); zval property_previousElementSibling_default_value; @@ -3332,7 +3328,7 @@ static zend_class_entry *register_class_Dom_Text(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Text", class_Dom_Text_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); @@ -3348,7 +3344,7 @@ static zend_class_entry *register_class_Dom_CDATASection(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "CDATASection", class_Dom_CDATASection_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Text); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Text, 0); return class_entry; } @@ -3358,7 +3354,7 @@ static zend_class_entry *register_class_Dom_ProcessingInstruction(zend_class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "ProcessingInstruction", class_Dom_ProcessingInstruction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); @@ -3374,7 +3370,7 @@ static zend_class_entry *register_class_Dom_Comment(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Comment", class_Dom_Comment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); return class_entry; } @@ -3384,7 +3380,7 @@ static zend_class_entry *register_class_Dom_DocumentType(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DocumentType", class_Dom_DocumentType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ChildNode); zval property_name_default_value; @@ -3433,7 +3429,7 @@ static zend_class_entry *register_class_Dom_DocumentFragment(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DocumentFragment", class_Dom_DocumentFragment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); zval property_firstElementChild_default_value; @@ -3464,7 +3460,7 @@ static zend_class_entry *register_class_Dom_Entity(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Entity", class_Dom_Entity_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); @@ -3492,7 +3488,7 @@ static zend_class_entry *register_class_Dom_EntityReference(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "EntityReference", class_Dom_EntityReference_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); return class_entry; } @@ -3502,7 +3498,7 @@ static zend_class_entry *register_class_Dom_Notation(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Notation", class_Dom_Notation_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); @@ -3524,8 +3520,7 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Document", class_Dom_Document_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); zval property_implementation_default_value; @@ -3627,8 +3622,7 @@ static zend_class_entry *register_class_Dom_HTMLDocument(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLDocument", class_Dom_HTMLDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Document); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Document, ZEND_ACC_FINAL); return class_entry; } @@ -3638,8 +3632,7 @@ static zend_class_entry *register_class_Dom_XMLDocument(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "XMLDocument", class_Dom_XMLDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Document); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Document, ZEND_ACC_FINAL); zval property_xmlEncoding_default_value; ZVAL_UNDEF(&property_xmlEncoding_default_value); @@ -3673,8 +3666,7 @@ static zend_class_entry *register_class_Dom_TokenList(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "TokenList", class_Dom_TokenList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 2, class_entry_Dom_IteratorAggregate, class_entry_Dom_Countable); zval property_length_default_value; @@ -3697,8 +3689,7 @@ static zend_class_entry *register_class_Dom_NamespaceInfo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NamespaceInfo", class_Dom_NamespaceInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE|ZEND_ACC_READONLY_CLASS; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE|ZEND_ACC_READONLY_CLASS); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); @@ -3728,8 +3719,7 @@ static zend_class_entry *register_class_Dom_XPath(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "XPath", class_Dom_XPath_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval property_document_default_value; ZVAL_UNDEF(&property_document_default_value); diff --git a/ext/enchant/enchant_arginfo.h b/ext/enchant/enchant_arginfo.h index d1f0d56ddb025..cc722e18d0681 100644 --- a/ext/enchant/enchant_arginfo.h +++ b/ext/enchant/enchant_arginfo.h @@ -231,8 +231,7 @@ static zend_class_entry *register_class_EnchantBroker(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EnchantBroker", class_EnchantBroker_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -242,8 +241,7 @@ static zend_class_entry *register_class_EnchantDictionary(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EnchantDictionary", class_EnchantDictionary_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index aca7a8d25637c..56f1444bd7ab6 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -213,8 +213,7 @@ static zend_class_entry *register_class_FFI(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FFI", class_FFI_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval const___BIGGEST_ALIGNMENT___value; ZVAL_LONG(&const___BIGGEST_ALIGNMENT___value, __BIGGEST_ALIGNMENT__); @@ -230,8 +229,7 @@ static zend_class_entry *register_class_FFI_CData(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "CData", class_FFI_CData_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -241,8 +239,7 @@ static zend_class_entry *register_class_FFI_CType(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "CType", class_FFI_CType_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval const_TYPE_VOID_value; ZVAL_LONG(&const_TYPE_VOID_value, ZEND_FFI_TYPE_VOID); @@ -482,7 +479,7 @@ static zend_class_entry *register_class_FFI_Exception(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "Exception", class_FFI_Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -492,8 +489,7 @@ static zend_class_entry *register_class_FFI_ParserException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "ParserException", class_FFI_ParserException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FFI_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FFI_Exception, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/fileinfo/fileinfo_arginfo.h b/ext/fileinfo/fileinfo_arginfo.h index 2ae8a2316e57b..36b9351ea1387 100644 --- a/ext/fileinfo/fileinfo_arginfo.h +++ b/ext/fileinfo/fileinfo_arginfo.h @@ -103,8 +103,7 @@ static zend_class_entry *register_class_finfo(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "finfo", class_finfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/ftp/ftp_arginfo.h b/ext/ftp/ftp_arginfo.h index 9aa6fcb48b352..0187ee325c615 100644 --- a/ext/ftp/ftp_arginfo.h +++ b/ext/ftp/ftp_arginfo.h @@ -300,8 +300,7 @@ static zend_class_entry *register_class_FTP_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FTP", "Connection", class_FTP_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index f68b34d5e101b..6cc6da64c9bbd 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -996,8 +996,7 @@ static zend_class_entry *register_class_GdImage(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GdImage", class_GdImage_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1007,8 +1006,7 @@ static zend_class_entry *register_class_GdFont(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GdFont", class_GdFont_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h index 43d6944036888..31927d3e482bc 100644 --- a/ext/gmp/gmp_arginfo.h +++ b/ext/gmp/gmp_arginfo.h @@ -333,8 +333,7 @@ static zend_class_entry *register_class_GMP(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GMP", class_GMP_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index e86ee61b656a2..92a3c40129554 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -282,8 +282,7 @@ static zend_class_entry *register_class_HashContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "HashContext", class_HashContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_arginfo.h b/ext/intl/breakiterator/breakiterator_arginfo.h index 8135a9cace64d..9475f5e987fc6 100644 --- a/ext/intl/breakiterator/breakiterator_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_arginfo.h @@ -156,8 +156,7 @@ static zend_class_entry *register_class_IntlBreakIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlBreakIterator", class_IntlBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval const_DONE_value; @@ -282,8 +281,7 @@ static zend_class_entry *register_class_IntlRuleBasedBreakIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlRuleBasedBreakIterator", class_IntlRuleBasedBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlBreakIterator, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -293,8 +291,7 @@ static zend_class_entry *register_class_IntlCodePointBreakIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlCodePointBreakIterator", class_IntlCodePointBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlBreakIterator, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h index 4642e09c36624..f83c0accf6bf4 100644 --- a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h @@ -21,8 +21,7 @@ static zend_class_entry *register_class_IntlPartsIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlPartsIterator", class_IntlPartsIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlIterator, ZEND_ACC_NOT_SERIALIZABLE); zval const_KEY_SEQUENTIAL_value; ZVAL_LONG(&const_KEY_SEQUENTIAL_value, PARTS_ITERATOR_KEY_SEQUENTIAL); diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 44c5cc16b21c0..9e050539b2e87 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -325,8 +325,7 @@ static zend_class_entry *register_class_IntlCalendar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlCalendar", class_IntlCalendar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FIELD_ERA_value; ZVAL_LONG(&const_FIELD_ERA_value, UCAL_ERA); @@ -570,8 +569,7 @@ static zend_class_entry *register_class_IntlGregorianCalendar(zend_class_entry * zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlGregorianCalendar", class_IntlGregorianCalendar_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlCalendar); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlCalendar, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/collator/collator_arginfo.h b/ext/intl/collator/collator_arginfo.h index 451d23eb0a238..3f469b02facd4 100644 --- a/ext/intl/collator/collator_arginfo.h +++ b/ext/intl/collator/collator_arginfo.h @@ -99,8 +99,7 @@ static zend_class_entry *register_class_Collator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Collator", class_Collator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_DEFAULT_VALUE_value; ZVAL_LONG(&const_DEFAULT_VALUE_value, UCOL_DEFAULT); diff --git a/ext/intl/common/common_arginfo.h b/ext/intl/common/common_arginfo.h index dcdf8434b4e70..c5e023ecb8883 100644 --- a/ext/intl/common/common_arginfo.h +++ b/ext/intl/common/common_arginfo.h @@ -179,8 +179,7 @@ static zend_class_entry *register_class_IntlIterator(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlIterator", class_IntlIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index 92c00af50ba95..4e02daf9478ad 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -122,8 +122,7 @@ static zend_class_entry *register_class_UConverter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UConverter", class_UConverter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_REASON_UNASSIGNED_value; ZVAL_LONG(&const_REASON_UNASSIGNED_value, UCNV_UNASSIGNED); diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index df1de7d6895f4..b57cb79468f2b 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -145,8 +145,7 @@ static zend_class_entry *register_class_IntlDateFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlDateFormatter", class_IntlDateFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FULL_value; ZVAL_LONG(&const_FULL_value, UDAT_FULL); diff --git a/ext/intl/dateformat/datepatterngenerator_arginfo.h b/ext/intl/dateformat/datepatterngenerator_arginfo.h index fd00ab845df62..14327b0d69f88 100644 --- a/ext/intl/dateformat/datepatterngenerator_arginfo.h +++ b/ext/intl/dateformat/datepatterngenerator_arginfo.h @@ -29,8 +29,7 @@ static zend_class_entry *register_class_IntlDatePatternGenerator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlDatePatternGenerator", class_IntlDatePatternGenerator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 0f067ee73c697..9b2874da05ac6 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -123,8 +123,7 @@ static zend_class_entry *register_class_NumberFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NumberFormatter", class_NumberFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_PATTERN_DECIMAL_value; ZVAL_LONG(&const_PATTERN_DECIMAL_value, UNUM_PATTERN_DECIMAL); diff --git a/ext/intl/locale/locale_arginfo.h b/ext/intl/locale/locale_arginfo.h index b03c552225298..7bba882d20457 100644 --- a/ext/intl/locale/locale_arginfo.h +++ b/ext/intl/locale/locale_arginfo.h @@ -108,7 +108,7 @@ static zend_class_entry *register_class_Locale(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Locale", class_Locale_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_ACTUAL_LOCALE_value; ZVAL_LONG(&const_ACTUAL_LOCALE_value, ULOC_ACTUAL_LOCALE); diff --git a/ext/intl/msgformat/msgformat_arginfo.h b/ext/intl/msgformat/msgformat_arginfo.h index bc45b5b535de5..74353fbf93ae2 100644 --- a/ext/intl/msgformat/msgformat_arginfo.h +++ b/ext/intl/msgformat/msgformat_arginfo.h @@ -78,8 +78,7 @@ static zend_class_entry *register_class_MessageFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "MessageFormatter", class_MessageFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/normalizer/normalizer_arginfo.h b/ext/intl/normalizer/normalizer_arginfo.h index a7a870a60d55e..5b8d80e3573f8 100644 --- a/ext/intl/normalizer/normalizer_arginfo.h +++ b/ext/intl/normalizer/normalizer_arginfo.h @@ -38,7 +38,7 @@ static zend_class_entry *register_class_Normalizer(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Normalizer", class_Normalizer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_FORM_D_value; ZVAL_LONG(&const_FORM_D_value, NORMALIZER_FORM_D); diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 702412125e594..a4fa30644258c 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1250,7 +1250,7 @@ static zend_class_entry *register_class_IntlException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlException", class_IntlException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/intl/resourcebundle/resourcebundle_arginfo.h b/ext/intl/resourcebundle/resourcebundle_arginfo.h index bfbb3511e62bc..f52de6314aa5d 100644 --- a/ext/intl/resourcebundle/resourcebundle_arginfo.h +++ b/ext/intl/resourcebundle/resourcebundle_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_ResourceBundle(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ResourceBundle", class_ResourceBundle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); return class_entry; diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index d0ba891ea958e..cee17335dcd40 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -62,8 +62,7 @@ static zend_class_entry *register_class_Spoofchecker(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Spoofchecker", class_Spoofchecker_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_SINGLE_SCRIPT_CONFUSABLE_value; ZVAL_LONG(&const_SINGLE_SCRIPT_CONFUSABLE_value, USPOOF_SINGLE_SCRIPT_CONFUSABLE); diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index 023346526a00e..b26e594cf930f 100644 --- a/ext/intl/timezone/timezone_arginfo.h +++ b/ext/intl/timezone/timezone_arginfo.h @@ -178,8 +178,7 @@ static zend_class_entry *register_class_IntlTimeZone(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlTimeZone", class_IntlTimeZone_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_DISPLAY_SHORT_value; ZVAL_LONG(&const_DISPLAY_SHORT_value, TimeZone::SHORT); diff --git a/ext/intl/transliterator/transliterator_arginfo.h b/ext/intl/transliterator/transliterator_arginfo.h index ee39917117172..0a53fe9a6b9c4 100644 --- a/ext/intl/transliterator/transliterator_arginfo.h +++ b/ext/intl/transliterator/transliterator_arginfo.h @@ -58,8 +58,7 @@ static zend_class_entry *register_class_Transliterator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Transliterator", class_Transliterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FORWARD_value; ZVAL_LONG(&const_FORWARD_value, TRANSLITERATOR_FORWARD); diff --git a/ext/intl/uchar/uchar_arginfo.h b/ext/intl/uchar/uchar_arginfo.h index d6217c7f8f8dc..ea70f17658867 100644 --- a/ext/intl/uchar/uchar_arginfo.h +++ b/ext/intl/uchar/uchar_arginfo.h @@ -314,7 +314,7 @@ static zend_class_entry *register_class_IntlChar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlChar", class_IntlChar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_UNICODE_VERSION_value; zend_string *const_UNICODE_VERSION_value_str = zend_string_init(U_UNICODE_VERSION, strlen(U_UNICODE_VERSION), 1); diff --git a/ext/json/json_arginfo.h b/ext/json/json_arginfo.h index a02cfd4a78105..e81a78d2b712b 100644 --- a/ext/json/json_arginfo.h +++ b/ext/json/json_arginfo.h @@ -101,7 +101,7 @@ static zend_class_entry *register_class_JsonException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "JsonException", class_JsonException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 369909889be90..0e5409ef53025 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -892,8 +892,7 @@ static zend_class_entry *register_class_LDAP_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "Connection", class_LDAP_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -903,8 +902,7 @@ static zend_class_entry *register_class_LDAP_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "Result", class_LDAP_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -914,8 +912,7 @@ static zend_class_entry *register_class_LDAP_ResultEntry(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "ResultEntry", class_LDAP_ResultEntry_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/libxml/libxml_arginfo.h b/ext/libxml/libxml_arginfo.h index 90db5d10d4e06..816d780173c17 100644 --- a/ext/libxml/libxml_arginfo.h +++ b/ext/libxml/libxml_arginfo.h @@ -109,7 +109,7 @@ static zend_class_entry *register_class_LibXMLError(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LibXMLError", class_LibXMLError_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_level_default_value; ZVAL_UNDEF(&property_level_default_value); diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 223fe9b7f8cef..827589c7b2ddf 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1212,8 +1212,7 @@ static zend_class_entry *register_class_mysqli_driver(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_driver", class_mysqli_driver_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_client_info_default_value; ZVAL_UNDEF(&property_client_info_default_value); @@ -1247,7 +1246,7 @@ static zend_class_entry *register_class_mysqli(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli", class_mysqli_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); @@ -1434,7 +1433,7 @@ static zend_class_entry *register_class_mysqli_result(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_result", class_mysqli_result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval property_current_field_default_value; @@ -1475,7 +1474,7 @@ static zend_class_entry *register_class_mysqli_stmt(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_stmt", class_mysqli_stmt_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); @@ -1545,8 +1544,7 @@ static zend_class_entry *register_class_mysqli_warning(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_warning", class_mysqli_warning_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_message_default_value; ZVAL_UNDEF(&property_message_default_value); @@ -1574,8 +1572,7 @@ static zend_class_entry *register_class_mysqli_sql_exception(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_sql_exception", class_mysqli_sql_exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, ZEND_ACC_FINAL); zval property_sqlstate_default_value; zend_string *property_sqlstate_default_value_str = zend_string_init("00000", strlen("00000"), 1); diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index f3480033a0918..4bed0ccb7e6c8 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -510,8 +510,7 @@ static zend_class_entry *register_class_Odbc_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Odbc", "Connection", class_Odbc_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -521,8 +520,7 @@ static zend_class_entry *register_class_Odbc_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Odbc", "Result", class_Odbc_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index 45a0593cf966e..e634f92f73d00 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -766,8 +766,7 @@ static zend_class_entry *register_class_OpenSSLCertificate(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLCertificate", class_OpenSSLCertificate_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -777,8 +776,7 @@ static zend_class_entry *register_class_OpenSSLCertificateSigningRequest(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLCertificateSigningRequest", class_OpenSSLCertificateSigningRequest_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -788,8 +786,7 @@ static zend_class_entry *register_class_OpenSSLAsymmetricKey(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLAsymmetricKey", class_OpenSSLAsymmetricKey_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index e6beb57bd23e5..eb42a1c9d0d73 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -20,7 +20,7 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDOException", class_PDOException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); zval property_code_default_value; ZVAL_LONG(&property_code_default_value, 0); diff --git a/ext/pdo/pdo_dbh_arginfo.h b/ext/pdo/pdo_dbh_arginfo.h index ecb21b3e4d917..71df4c519e1a7 100644 --- a/ext/pdo/pdo_dbh_arginfo.h +++ b/ext/pdo/pdo_dbh_arginfo.h @@ -107,8 +107,7 @@ static zend_class_entry *register_class_PDO(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDO", class_PDO_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_PARAM_NULL_value; ZVAL_LONG(&const_PARAM_NULL_value, LONG_CONST(PDO_PARAM_NULL)); diff --git a/ext/pdo/pdo_stmt_arginfo.h b/ext/pdo/pdo_stmt_arginfo.h index d0d90899125f4..4d8c1fa4715e4 100644 --- a/ext/pdo/pdo_stmt_arginfo.h +++ b/ext/pdo/pdo_stmt_arginfo.h @@ -141,8 +141,7 @@ static zend_class_entry *register_class_PDOStatement(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDOStatement", class_PDOStatement_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval property_queryString_default_value; @@ -159,8 +158,7 @@ static zend_class_entry *register_class_PDORow(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDORow", class_PDORow_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval property_queryString_default_value; ZVAL_UNDEF(&property_queryString_default_value); diff --git a/ext/pdo_dblib/pdo_dblib_arginfo.h b/ext/pdo_dblib/pdo_dblib_arginfo.h index 3c9e306f3042c..a5105e3da6443 100644 --- a/ext/pdo_dblib/pdo_dblib_arginfo.h +++ b/ext/pdo_dblib/pdo_dblib_arginfo.h @@ -10,8 +10,7 @@ static zend_class_entry *register_class_Pdo_Dblib(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Dblib", class_Pdo_Dblib_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_CONNECTION_TIMEOUT_value; ZVAL_LONG(&const_ATTR_CONNECTION_TIMEOUT_value, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); diff --git a/ext/pdo_firebird/pdo_firebird_arginfo.h b/ext/pdo_firebird/pdo_firebird_arginfo.h index a751751edb635..a5a9c562c9c12 100644 --- a/ext/pdo_firebird/pdo_firebird_arginfo.h +++ b/ext/pdo_firebird/pdo_firebird_arginfo.h @@ -16,8 +16,7 @@ static zend_class_entry *register_class_Pdo_Firebird(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Firebird", class_Pdo_Firebird_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_DATE_FORMAT_value; ZVAL_LONG(&const_ATTR_DATE_FORMAT_value, PDO_FB_ATTR_DATE_FORMAT); diff --git a/ext/pdo_mysql/pdo_mysql_arginfo.h b/ext/pdo_mysql/pdo_mysql_arginfo.h index 1ae005d849103..1e6fd32751fe5 100644 --- a/ext/pdo_mysql/pdo_mysql_arginfo.h +++ b/ext/pdo_mysql/pdo_mysql_arginfo.h @@ -16,8 +16,7 @@ static zend_class_entry *register_class_Pdo_Mysql(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Mysql", class_Pdo_Mysql_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_USE_BUFFERED_QUERY_value; ZVAL_LONG(&const_ATTR_USE_BUFFERED_QUERY_value, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); diff --git a/ext/pdo_odbc/pdo_odbc_arginfo.h b/ext/pdo_odbc/pdo_odbc_arginfo.h index b74ed6f2917a6..2f281e6922f5b 100644 --- a/ext/pdo_odbc/pdo_odbc_arginfo.h +++ b/ext/pdo_odbc/pdo_odbc_arginfo.h @@ -15,8 +15,7 @@ static zend_class_entry *register_class_Pdo_Odbc(zend_class_entry *class_entry_P zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Odbc", class_Pdo_Odbc_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_USE_CURSOR_LIBRARY_value; ZVAL_LONG(&const_ATTR_USE_CURSOR_LIBRARY_value, PDO_ODBC_ATTR_USE_CURSOR_LIBRARY); diff --git a/ext/pdo_pgsql/pdo_pgsql_arginfo.h b/ext/pdo_pgsql/pdo_pgsql_arginfo.h index 4f70e79f8d5d4..f7f54cb600c72 100644 --- a/ext/pdo_pgsql/pdo_pgsql_arginfo.h +++ b/ext/pdo_pgsql/pdo_pgsql_arginfo.h @@ -86,8 +86,7 @@ static zend_class_entry *register_class_Pdo_Pgsql(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Pgsql", class_Pdo_Pgsql_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_DISABLE_PREPARES_value; ZVAL_LONG(&const_ATTR_DISABLE_PREPARES_value, PDO_PGSQL_ATTR_DISABLE_PREPARES); diff --git a/ext/pdo_sqlite/pdo_sqlite_arginfo.h b/ext/pdo_sqlite/pdo_sqlite_arginfo.h index d0c006ac2d989..4abbc0bb625c6 100644 --- a/ext/pdo_sqlite/pdo_sqlite_arginfo.h +++ b/ext/pdo_sqlite/pdo_sqlite_arginfo.h @@ -58,8 +58,7 @@ static zend_class_entry *register_class_Pdo_Sqlite(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Sqlite", class_Pdo_Sqlite_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); #if defined(SQLITE_DETERMINISTIC) zval const_DETERMINISTIC_value; diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index a164584eb3add..85ca35b6a5a10 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1147,8 +1147,7 @@ static zend_class_entry *register_class_PgSql_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Connection", class_PgSql_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1158,8 +1157,7 @@ static zend_class_entry *register_class_PgSql_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Result", class_PgSql_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1169,8 +1167,7 @@ static zend_class_entry *register_class_PgSql_Lob(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Lob", class_PgSql_Lob_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/phar/phar_object_arginfo.h b/ext/phar/phar_object_arginfo.h index 3111bc260f4aa..6fe081fe4dbe8 100644 --- a/ext/phar/phar_object_arginfo.h +++ b/ext/phar/phar_object_arginfo.h @@ -613,7 +613,7 @@ static zend_class_entry *register_class_PharException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharException", class_PharException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -623,7 +623,7 @@ static zend_class_entry *register_class_Phar(zend_class_entry *class_entry_Recur zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Phar", class_Phar_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveDirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveDirectoryIterator, 0); zend_class_implements(class_entry, 2, class_entry_Countable, class_entry_ArrayAccess); zval const_BZ2_value; @@ -730,7 +730,7 @@ static zend_class_entry *register_class_PharData(zend_class_entry *class_entry_R zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharData", class_PharData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveDirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveDirectoryIterator, 0); zend_class_implements(class_entry, 2, class_entry_Countable, class_entry_ArrayAccess); return class_entry; @@ -741,7 +741,7 @@ static zend_class_entry *register_class_PharFileInfo(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharFileInfo", class_PharFileInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); return class_entry; } diff --git a/ext/random/random_arginfo.h b/ext/random/random_arginfo.h index fcb96380c6f0e..7f684271f7bab 100644 --- a/ext/random/random_arginfo.h +++ b/ext/random/random_arginfo.h @@ -267,8 +267,7 @@ static zend_class_entry *register_class_Random_Engine_Mt19937(zend_class_entry * zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Mt19937", class_Random_Engine_Mt19937_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -279,8 +278,7 @@ static zend_class_entry *register_class_Random_Engine_PcgOneseq128XslRr64(zend_c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "PcgOneseq128XslRr64", class_Random_Engine_PcgOneseq128XslRr64_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -291,8 +289,7 @@ static zend_class_entry *register_class_Random_Engine_Xoshiro256StarStar(zend_cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Xoshiro256StarStar", class_Random_Engine_Xoshiro256StarStar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -303,8 +300,7 @@ static zend_class_entry *register_class_Random_Engine_Secure(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Secure", class_Random_Engine_Secure_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Random_CryptoSafeEngine); return class_entry; @@ -336,8 +332,7 @@ static zend_class_entry *register_class_Random_Randomizer(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "Randomizer", class_Random_Randomizer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval property_engine_default_value; ZVAL_UNDEF(&property_engine_default_value); @@ -369,8 +364,7 @@ static zend_class_entry *register_class_Random_RandomError(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "RandomError", class_Random_RandomError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -380,8 +374,7 @@ static zend_class_entry *register_class_Random_BrokenRandomEngineError(zend_clas zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "BrokenRandomEngineError", class_Random_BrokenRandomEngineError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Random_RandomError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Random_RandomError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -391,8 +384,7 @@ static zend_class_entry *register_class_Random_RandomException(zend_class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "RandomException", class_Random_RandomException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index a35bdd766ef7b..2f0a513044c5d 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1269,7 +1269,7 @@ static zend_class_entry *register_class_ReflectionException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionException", class_ReflectionException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -1279,7 +1279,7 @@ static zend_class_entry *register_class_Reflection(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Reflection", class_Reflection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -1300,8 +1300,7 @@ static zend_class_entry *register_class_ReflectionFunctionAbstract(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFunctionAbstract", class_ReflectionFunctionAbstract_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1318,7 +1317,7 @@ static zend_class_entry *register_class_ReflectionFunction(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFunction", class_ReflectionFunction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionFunctionAbstract); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionFunctionAbstract, 0); zval const_IS_DEPRECATED_value; ZVAL_LONG(&const_IS_DEPRECATED_value, ZEND_ACC_DEPRECATED); @@ -1347,8 +1346,7 @@ static zend_class_entry *register_class_ReflectionGenerator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionGenerator", class_ReflectionGenerator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1358,7 +1356,7 @@ static zend_class_entry *register_class_ReflectionMethod(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionMethod", class_ReflectionMethod_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionFunctionAbstract); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionFunctionAbstract, 0); zval const_IS_STATIC_value; ZVAL_LONG(&const_IS_STATIC_value, ZEND_ACC_STATIC); @@ -1410,8 +1408,7 @@ static zend_class_entry *register_class_ReflectionClass(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionClass", class_ReflectionClass_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_IMPLICIT_ABSTRACT_value; @@ -1452,7 +1449,7 @@ static zend_class_entry *register_class_ReflectionObject(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionObject", class_ReflectionObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClass); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClass, 0); return class_entry; } @@ -1479,8 +1476,7 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionProperty", class_ReflectionProperty_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_STATIC_value; @@ -1539,8 +1535,7 @@ static zend_class_entry *register_class_ReflectionClassConstant(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionClassConstant", class_ReflectionClassConstant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_PUBLIC_value; @@ -1587,8 +1582,7 @@ static zend_class_entry *register_class_ReflectionParameter(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionParameter", class_ReflectionParameter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1642,8 +1636,7 @@ static zend_class_entry *register_class_ReflectionType(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionType", class_ReflectionType_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Stringable); return class_entry; @@ -1654,7 +1647,7 @@ static zend_class_entry *register_class_ReflectionNamedType(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionNamedType", class_ReflectionNamedType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1664,7 +1657,7 @@ static zend_class_entry *register_class_ReflectionUnionType(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionUnionType", class_ReflectionUnionType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1674,7 +1667,7 @@ static zend_class_entry *register_class_ReflectionIntersectionType(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionIntersectionType", class_ReflectionIntersectionType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1684,8 +1677,7 @@ static zend_class_entry *register_class_ReflectionExtension(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionExtension", class_ReflectionExtension_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1702,8 +1694,7 @@ static zend_class_entry *register_class_ReflectionZendExtension(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionZendExtension", class_ReflectionZendExtension_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1720,8 +1711,7 @@ static zend_class_entry *register_class_ReflectionReference(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionReference", class_ReflectionReference_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1731,8 +1721,7 @@ static zend_class_entry *register_class_ReflectionAttribute(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionAttribute", class_ReflectionAttribute_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_INSTANCEOF_value; @@ -1755,7 +1744,7 @@ static zend_class_entry *register_class_ReflectionEnum(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnum", class_ReflectionEnum_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClass); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClass, 0); return class_entry; } @@ -1765,7 +1754,7 @@ static zend_class_entry *register_class_ReflectionEnumUnitCase(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnumUnitCase", class_ReflectionEnumUnitCase_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClassConstant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClassConstant, 0); return class_entry; } @@ -1775,7 +1764,7 @@ static zend_class_entry *register_class_ReflectionEnumBackedCase(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnumBackedCase", class_ReflectionEnumBackedCase_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionEnumUnitCase); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionEnumUnitCase, 0); return class_entry; } @@ -1785,8 +1774,7 @@ static zend_class_entry *register_class_ReflectionFiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFiber", class_ReflectionFiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1796,8 +1784,7 @@ static zend_class_entry *register_class_ReflectionConstant(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionConstant", class_ReflectionConstant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h index a1fe34cfde3e8..3e0c889ae3c55 100644 --- a/ext/session/session_arginfo.h +++ b/ext/session/session_arginfo.h @@ -266,7 +266,7 @@ static zend_class_entry *register_class_SessionHandler(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SessionHandler", class_SessionHandler_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_SessionHandlerInterface, class_entry_SessionIdInterface); return class_entry; diff --git a/ext/shmop/shmop_arginfo.h b/ext/shmop/shmop_arginfo.h index 455d326fa3a72..79eaee3283379 100644 --- a/ext/shmop/shmop_arginfo.h +++ b/ext/shmop/shmop_arginfo.h @@ -74,8 +74,7 @@ static zend_class_entry *register_class_Shmop(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Shmop", class_Shmop_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 285df20813f07..1048fe443017a 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -165,8 +165,7 @@ static zend_class_entry *register_class_SimpleXMLElement(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SimpleXMLElement", class_SimpleXMLElement_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 3, class_entry_Stringable, class_entry_Countable, class_entry_RecursiveIterator); return class_entry; @@ -177,7 +176,7 @@ static zend_class_entry *register_class_SimpleXMLIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SimpleXMLIterator", class_SimpleXMLIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SimpleXMLElement); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SimpleXMLElement, 0); return class_entry; } diff --git a/ext/snmp/snmp_arginfo.h b/ext/snmp/snmp_arginfo.h index 307c22ecb8d8e..97046c88b61c2 100644 --- a/ext/snmp/snmp_arginfo.h +++ b/ext/snmp/snmp_arginfo.h @@ -270,7 +270,7 @@ static zend_class_entry *register_class_SNMP(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SNMP", class_SNMP_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_VERSION_1_value; ZVAL_LONG(&const_VERSION_1_value, SNMP_VERSION_1); @@ -400,7 +400,7 @@ static zend_class_entry *register_class_SNMPException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SNMPException", class_SNMPException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index 63e5a01910c48..23af99aa3946c 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -323,8 +323,7 @@ static zend_class_entry *register_class_Soap_Url(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Soap", "Url", class_Soap_Url_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -334,8 +333,7 @@ static zend_class_entry *register_class_Soap_Sdl(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Soap", "Sdl", class_Soap_Sdl_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -345,7 +343,7 @@ static zend_class_entry *register_class_SoapParam(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapParam", class_SoapParam_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_param_name_default_value; ZVAL_UNDEF(&property_param_name_default_value); @@ -367,7 +365,7 @@ static zend_class_entry *register_class_SoapHeader(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapHeader", class_SoapHeader_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_namespace_default_value; ZVAL_UNDEF(&property_namespace_default_value); @@ -407,7 +405,7 @@ static zend_class_entry *register_class_SoapFault(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapFault", class_SoapFault_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); zval property_faultstring_default_value; ZVAL_UNDEF(&property_faultstring_default_value); @@ -459,7 +457,7 @@ static zend_class_entry *register_class_SoapVar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapVar", class_SoapVar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_enc_type_default_value; ZVAL_UNDEF(&property_enc_type_default_value); @@ -505,7 +503,7 @@ static zend_class_entry *register_class_SoapServer(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapServer", class_SoapServer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property___soap_fault_default_value; ZVAL_NULL(&property___soap_fault_default_value); @@ -522,7 +520,7 @@ static zend_class_entry *register_class_SoapClient(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapClient", class_SoapClient_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_uri_default_value; ZVAL_NULL(&property_uri_default_value); diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index 348c62d2eb4ae..3faa4d1f43063 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1090,8 +1090,7 @@ static zend_class_entry *register_class_Socket(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Socket", class_Socket_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1101,8 +1100,7 @@ static zend_class_entry *register_class_AddressInfo(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AddressInfo", class_AddressInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index ebc5fadae6452..f1f0ce58ef81c 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1383,7 +1383,7 @@ static zend_class_entry *register_class_SodiumException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SodiumException", class_SodiumException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/spl/spl_array_arginfo.h b/ext/spl/spl_array_arginfo.h index e846943c3cbfe..24dcadac661c8 100644 --- a/ext/spl/spl_array_arginfo.h +++ b/ext/spl/spl_array_arginfo.h @@ -259,7 +259,7 @@ static zend_class_entry *register_class_ArrayObject(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArrayObject", class_ArrayObject_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_IteratorAggregate, class_entry_ArrayAccess, class_entry_Serializable, class_entry_Countable); zval const_STD_PROP_LIST_value; @@ -282,7 +282,7 @@ static zend_class_entry *register_class_ArrayIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArrayIterator", class_ArrayIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_SeekableIterator, class_entry_ArrayAccess, class_entry_Serializable, class_entry_Countable); zval const_STD_PROP_LIST_value; @@ -305,7 +305,7 @@ static zend_class_entry *register_class_RecursiveArrayIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveArrayIterator", class_RecursiveArrayIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ArrayIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ArrayIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); zval const_CHILD_ARRAYS_ONLY_value; diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 4534970dc492c..b8d197aa941b8 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -487,8 +487,7 @@ static zend_class_entry *register_class_SplFileInfo(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFileInfo", class_SplFileInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Stringable); @@ -507,7 +506,7 @@ static zend_class_entry *register_class_DirectoryIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DirectoryIterator", class_DirectoryIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); zend_class_implements(class_entry, 1, class_entry_SeekableIterator); return class_entry; @@ -518,7 +517,7 @@ static zend_class_entry *register_class_FilesystemIterator(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FilesystemIterator", class_FilesystemIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DirectoryIterator, 0); zval const_CURRENT_MODE_MASK_value; ZVAL_LONG(&const_CURRENT_MODE_MASK_value, SPL_FILE_DIR_CURRENT_MODE_MASK); @@ -600,7 +599,7 @@ static zend_class_entry *register_class_RecursiveDirectoryIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveDirectoryIterator", class_RecursiveDirectoryIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilesystemIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilesystemIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -612,7 +611,7 @@ static zend_class_entry *register_class_GlobIterator(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GlobIterator", class_GlobIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilesystemIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilesystemIterator, 0); zend_class_implements(class_entry, 1, class_entry_Countable); return class_entry; @@ -624,7 +623,7 @@ static zend_class_entry *register_class_SplFileObject(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFileObject", class_SplFileObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); zend_class_implements(class_entry, 2, class_entry_RecursiveIterator, class_entry_SeekableIterator); zval const_DROP_NEW_LINE_value; @@ -659,7 +658,7 @@ static zend_class_entry *register_class_SplTempFileObject(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplTempFileObject", class_SplTempFileObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileObject); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileObject, 0); return class_entry; } diff --git a/ext/spl/spl_dllist_arginfo.h b/ext/spl/spl_dllist_arginfo.h index aa87f686bb70d..024fa6dc6e836 100644 --- a/ext/spl/spl_dllist_arginfo.h +++ b/ext/spl/spl_dllist_arginfo.h @@ -155,7 +155,7 @@ static zend_class_entry *register_class_SplDoublyLinkedList(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplDoublyLinkedList", class_SplDoublyLinkedList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Iterator, class_entry_Countable, class_entry_ArrayAccess, class_entry_Serializable); zval const_IT_MODE_LIFO_value; @@ -190,7 +190,7 @@ static zend_class_entry *register_class_SplQueue(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplQueue", class_SplQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplDoublyLinkedList); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplDoublyLinkedList, 0); return class_entry; } @@ -200,7 +200,7 @@ static zend_class_entry *register_class_SplStack(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplStack", class_SplStack_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplDoublyLinkedList); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplDoublyLinkedList, 0); return class_entry; } diff --git a/ext/spl/spl_exceptions_arginfo.h b/ext/spl/spl_exceptions_arginfo.h index f2594f1238d72..7165074b4aece 100644 --- a/ext/spl/spl_exceptions_arginfo.h +++ b/ext/spl/spl_exceptions_arginfo.h @@ -58,7 +58,7 @@ static zend_class_entry *register_class_LogicException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LogicException", class_LogicException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -68,7 +68,7 @@ static zend_class_entry *register_class_BadFunctionCallException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "BadFunctionCallException", class_BadFunctionCallException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -78,7 +78,7 @@ static zend_class_entry *register_class_BadMethodCallException(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "BadMethodCallException", class_BadMethodCallException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_BadFunctionCallException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_BadFunctionCallException, 0); return class_entry; } @@ -88,7 +88,7 @@ static zend_class_entry *register_class_DomainException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DomainException", class_DomainException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -98,7 +98,7 @@ static zend_class_entry *register_class_InvalidArgumentException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InvalidArgumentException", class_InvalidArgumentException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -108,7 +108,7 @@ static zend_class_entry *register_class_LengthException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LengthException", class_LengthException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -118,7 +118,7 @@ static zend_class_entry *register_class_OutOfRangeException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OutOfRangeException", class_OutOfRangeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -128,7 +128,7 @@ static zend_class_entry *register_class_RuntimeException(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RuntimeException", class_RuntimeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -138,7 +138,7 @@ static zend_class_entry *register_class_OutOfBoundsException(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OutOfBoundsException", class_OutOfBoundsException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -148,7 +148,7 @@ static zend_class_entry *register_class_OverflowException(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OverflowException", class_OverflowException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -158,7 +158,7 @@ static zend_class_entry *register_class_RangeException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RangeException", class_RangeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -168,7 +168,7 @@ static zend_class_entry *register_class_UnderflowException(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnderflowException", class_UnderflowException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -178,7 +178,7 @@ static zend_class_entry *register_class_UnexpectedValueException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnexpectedValueException", class_UnexpectedValueException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } diff --git a/ext/spl/spl_fixedarray_arginfo.h b/ext/spl/spl_fixedarray_arginfo.h index 2e66e7060d50b..e517833a02b89 100644 --- a/ext/spl/spl_fixedarray_arginfo.h +++ b/ext/spl/spl_fixedarray_arginfo.h @@ -94,7 +94,7 @@ static zend_class_entry *register_class_SplFixedArray(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFixedArray", class_SplFixedArray_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_IteratorAggregate, class_entry_ArrayAccess, class_entry_Countable, class_entry_JsonSerializable); diff --git a/ext/spl/spl_heap_arginfo.h b/ext/spl/spl_heap_arginfo.h index 9910ae15cd988..31a3f79fe2c75 100644 --- a/ext/spl/spl_heap_arginfo.h +++ b/ext/spl/spl_heap_arginfo.h @@ -161,7 +161,7 @@ static zend_class_entry *register_class_SplPriorityQueue(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplPriorityQueue", class_SplPriorityQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_Iterator, class_entry_Countable); zval const_EXTR_BOTH_value; @@ -190,8 +190,7 @@ static zend_class_entry *register_class_SplHeap(zend_class_entry *class_entry_It zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplHeap", class_SplHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 2, class_entry_Iterator, class_entry_Countable); return class_entry; @@ -202,7 +201,7 @@ static zend_class_entry *register_class_SplMinHeap(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplMinHeap", class_SplMinHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplHeap); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplHeap, 0); return class_entry; } @@ -212,7 +211,7 @@ static zend_class_entry *register_class_SplMaxHeap(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplMaxHeap", class_SplMaxHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplHeap); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplHeap, 0); return class_entry; } diff --git a/ext/spl/spl_iterators_arginfo.h b/ext/spl/spl_iterators_arginfo.h index 1d6566f6c6908..d0b0d5ddbcc87 100644 --- a/ext/spl/spl_iterators_arginfo.h +++ b/ext/spl/spl_iterators_arginfo.h @@ -605,7 +605,7 @@ static zend_class_entry *register_class_EmptyIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EmptyIterator", class_EmptyIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; @@ -616,7 +616,7 @@ static zend_class_entry *register_class_CallbackFilterIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CallbackFilterIterator", class_CallbackFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, 0); return class_entry; } @@ -626,7 +626,7 @@ static zend_class_entry *register_class_RecursiveCallbackFilterIterator(zend_cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveCallbackFilterIterator", class_RecursiveCallbackFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CallbackFilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CallbackFilterIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -648,7 +648,7 @@ static zend_class_entry *register_class_RecursiveIteratorIterator(zend_class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveIteratorIterator", class_RecursiveIteratorIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_OuterIterator); zval const_LEAVES_ONLY_value; @@ -694,7 +694,7 @@ static zend_class_entry *register_class_IteratorIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IteratorIterator", class_IteratorIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_OuterIterator); return class_entry; @@ -705,8 +705,7 @@ static zend_class_entry *register_class_FilterIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FilterIterator", class_FilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, ZEND_ACC_ABSTRACT); return class_entry; } @@ -716,8 +715,7 @@ static zend_class_entry *register_class_RecursiveFilterIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveFilterIterator", class_RecursiveFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -728,7 +726,7 @@ static zend_class_entry *register_class_ParentIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ParentIterator", class_ParentIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveFilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveFilterIterator, 0); return class_entry; } @@ -749,7 +747,7 @@ static zend_class_entry *register_class_LimitIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LimitIterator", class_LimitIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -759,7 +757,7 @@ static zend_class_entry *register_class_CachingIterator(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CachingIterator", class_CachingIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); zend_class_implements(class_entry, 3, class_entry_ArrayAccess, class_entry_Countable, class_entry_Stringable); zval const_CALL_TOSTRING_value; @@ -806,7 +804,7 @@ static zend_class_entry *register_class_RecursiveCachingIterator(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveCachingIterator", class_RecursiveCachingIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CachingIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CachingIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -817,7 +815,7 @@ static zend_class_entry *register_class_NoRewindIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NoRewindIterator", class_NoRewindIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -827,7 +825,7 @@ static zend_class_entry *register_class_AppendIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AppendIterator", class_AppendIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -837,7 +835,7 @@ static zend_class_entry *register_class_InfiniteIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InfiniteIterator", class_InfiniteIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -847,7 +845,7 @@ static zend_class_entry *register_class_RegexIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RegexIterator", class_RegexIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, 0); zval const_USE_KEY_value; ZVAL_LONG(&const_USE_KEY_value, REGIT_USE_KEY); @@ -905,7 +903,7 @@ static zend_class_entry *register_class_RecursiveRegexIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveRegexIterator", class_RecursiveRegexIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RegexIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RegexIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -916,7 +914,7 @@ static zend_class_entry *register_class_RecursiveTreeIterator(zend_class_entry * zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveTreeIterator", class_RecursiveTreeIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveIteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveIteratorIterator, 0); zval const_BYPASS_CURRENT_value; ZVAL_LONG(&const_BYPASS_CURRENT_value, RTIT_BYPASS_CURRENT); diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 730f4c279c254..be12c594e0146 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -255,7 +255,7 @@ static zend_class_entry *register_class_SplObjectStorage(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplObjectStorage", class_SplObjectStorage_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Countable, class_entry_SeekableIterator, class_entry_Serializable, class_entry_ArrayAccess); return class_entry; @@ -266,7 +266,7 @@ static zend_class_entry *register_class_MultipleIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "MultipleIterator", class_MultipleIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Iterator); zval const_MIT_NEED_ANY_value; diff --git a/ext/sqlite3/sqlite3_arginfo.h b/ext/sqlite3/sqlite3_arginfo.h index 9c813bace265c..31588ffd57345 100644 --- a/ext/sqlite3/sqlite3_arginfo.h +++ b/ext/sqlite3/sqlite3_arginfo.h @@ -294,8 +294,7 @@ static zend_class_entry *register_class_SQLite3Exception(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Exception", class_SQLite3Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -305,8 +304,7 @@ static zend_class_entry *register_class_SQLite3(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3", class_SQLite3_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_OK_value; ZVAL_LONG(&const_OK_value, SQLITE_OK); @@ -540,8 +538,7 @@ static zend_class_entry *register_class_SQLite3Stmt(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Stmt", class_SQLite3Stmt_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -551,8 +548,7 @@ static zend_class_entry *register_class_SQLite3Result(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Result", class_SQLite3Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 00bc7c5509d06..6834c3094dd73 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -4178,8 +4178,7 @@ static zend_class_entry *register_class___PHP_Incomplete_Class(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "__PHP_Incomplete_Class", class___PHP_Incomplete_Class_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); zend_string *attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0, 0); @@ -4193,7 +4192,7 @@ static zend_class_entry *register_class_AssertionError(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AssertionError", class_AssertionError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } diff --git a/ext/standard/dir_arginfo.h b/ext/standard/dir_arginfo.h index cdf21396bb0ab..47ab180ed7b17 100644 --- a/ext/standard/dir_arginfo.h +++ b/ext/standard/dir_arginfo.h @@ -58,7 +58,7 @@ static zend_class_entry *register_class_Directory(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Directory", class_Directory_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_path_default_value; ZVAL_UNDEF(&property_path_default_value); diff --git a/ext/standard/user_filters_arginfo.h b/ext/standard/user_filters_arginfo.h index a40a00f7ee476..f960a3a904e85 100644 --- a/ext/standard/user_filters_arginfo.h +++ b/ext/standard/user_filters_arginfo.h @@ -44,7 +44,7 @@ static zend_class_entry *register_class_php_user_filter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "php_user_filter", class_php_user_filter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_filtername_default_value; ZVAL_EMPTY_STRING(&property_filtername_default_value); @@ -72,8 +72,7 @@ static zend_class_entry *register_class_StreamBucket(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "StreamBucket", class_StreamBucket_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_bucket_default_value; ZVAL_NULL(&property_bucket_default_value); diff --git a/ext/sysvmsg/sysvmsg_arginfo.h b/ext/sysvmsg/sysvmsg_arginfo.h index 34eca90d6feb8..a5e84383e16ca 100644 --- a/ext/sysvmsg/sysvmsg_arginfo.h +++ b/ext/sysvmsg/sysvmsg_arginfo.h @@ -80,8 +80,7 @@ static zend_class_entry *register_class_SysvMessageQueue(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvMessageQueue", class_SysvMessageQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sysvsem/sysvsem_arginfo.h b/ext/sysvsem/sysvsem_arginfo.h index 4411a7319caab..d35ab67de2c74 100644 --- a/ext/sysvsem/sysvsem_arginfo.h +++ b/ext/sysvsem/sysvsem_arginfo.h @@ -41,8 +41,7 @@ static zend_class_entry *register_class_SysvSemaphore(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvSemaphore", class_SysvSemaphore_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sysvshm/sysvshm_arginfo.h b/ext/sysvshm/sysvshm_arginfo.h index 05715b2e79ffb..2c4b401a439c6 100644 --- a/ext/sysvshm/sysvshm_arginfo.h +++ b/ext/sysvshm/sysvshm_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_SysvSharedMemory(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvSharedMemory", class_SysvSharedMemory_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/tidy/tidy_arginfo.h b/ext/tidy/tidy_arginfo.h index 99cc28b68099d..56c0b78c32e47 100644 --- a/ext/tidy/tidy_arginfo.h +++ b/ext/tidy/tidy_arginfo.h @@ -526,7 +526,7 @@ static zend_class_entry *register_class_tidy(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "tidy", class_tidy_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_errorBuffer_default_value; ZVAL_NULL(&property_errorBuffer_default_value); @@ -548,8 +548,7 @@ static zend_class_entry *register_class_tidyNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "tidyNode", class_tidyNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); diff --git a/ext/tokenizer/tokenizer_arginfo.h b/ext/tokenizer/tokenizer_arginfo.h index e7ab3e31cf39c..04b7406596130 100644 --- a/ext/tokenizer/tokenizer_arginfo.h +++ b/ext/tokenizer/tokenizer_arginfo.h @@ -67,7 +67,7 @@ static zend_class_entry *register_class_PhpToken(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PhpToken", class_PhpToken_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Stringable); zval property_id_default_value; diff --git a/ext/xml/xml_arginfo.h b/ext/xml/xml_arginfo.h index 7b31981ed60da..824ae0bfedfe3 100644 --- a/ext/xml/xml_arginfo.h +++ b/ext/xml/xml_arginfo.h @@ -185,8 +185,7 @@ static zend_class_entry *register_class_XMLParser(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLParser", class_XMLParser_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/xmlreader/php_xmlreader_arginfo.h b/ext/xmlreader/php_xmlreader_arginfo.h index a5a0c12cd2593..4e2a431a55c29 100644 --- a/ext/xmlreader/php_xmlreader_arginfo.h +++ b/ext/xmlreader/php_xmlreader_arginfo.h @@ -176,7 +176,7 @@ static zend_class_entry *register_class_XMLReader(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLReader", class_XMLReader_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_NONE_value; ZVAL_LONG(&const_NONE_value, XML_READER_TYPE_NONE); diff --git a/ext/xmlwriter/php_xmlwriter_arginfo.h b/ext/xmlwriter/php_xmlwriter_arginfo.h index fda02c49f6f81..ebccf4225ba9f 100644 --- a/ext/xmlwriter/php_xmlwriter_arginfo.h +++ b/ext/xmlwriter/php_xmlwriter_arginfo.h @@ -484,7 +484,7 @@ static zend_class_entry *register_class_XMLWriter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLWriter", class_XMLWriter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } diff --git a/ext/xsl/php_xsl_arginfo.h b/ext/xsl/php_xsl_arginfo.h index 20559328d8181..d040928197f65 100644 --- a/ext/xsl/php_xsl_arginfo.h +++ b/ext/xsl/php_xsl_arginfo.h @@ -117,7 +117,7 @@ static zend_class_entry *register_class_XSLTProcessor(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XSLTProcessor", class_XSLTProcessor_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_doXInclude_default_value; ZVAL_FALSE(&property_doXInclude_default_value); diff --git a/ext/zend_test/fiber_arginfo.h b/ext/zend_test/fiber_arginfo.h index c25ed876614b4..e4a0b51bebc9d 100644 --- a/ext/zend_test/fiber_arginfo.h +++ b/ext/zend_test/fiber_arginfo.h @@ -39,8 +39,7 @@ static zend_class_entry *register_class__ZendTestFiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestFiber", class__ZendTestFiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/zend_test/iterators_arginfo.h b/ext/zend_test/iterators_arginfo.h index 2661550c5f6cd..3ec78808eaa19 100644 --- a/ext/zend_test/iterators_arginfo.h +++ b/ext/zend_test/iterators_arginfo.h @@ -21,8 +21,7 @@ static zend_class_entry *register_class_ZendTest_Iterators_TraversableTest(zend_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTest\\Iterators", "TraversableTest", class_ZendTest_Iterators_TraversableTest_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); return class_entry; diff --git a/ext/zend_test/object_handlers_arginfo.h b/ext/zend_test/object_handlers_arginfo.h index 510a6602ab0be..84a9203fd7ea8 100644 --- a/ext/zend_test/object_handlers_arginfo.h +++ b/ext/zend_test/object_handlers_arginfo.h @@ -49,8 +49,7 @@ static zend_class_entry *register_class_DoOperationNoCast(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DoOperationNoCast", class_DoOperationNoCast_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -66,8 +65,7 @@ static zend_class_entry *register_class_LongCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LongCastableNoOperations", class_LongCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -83,8 +81,7 @@ static zend_class_entry *register_class_FloatCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FloatCastableNoOperations", class_FloatCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -100,8 +97,7 @@ static zend_class_entry *register_class_NumericCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NumericCastableNoOperations", class_NumericCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -117,7 +113,7 @@ static zend_class_entry *register_class_DimensionHandlersNoArrayAccess(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DimensionHandlersNoArrayAccess", class_DimensionHandlersNoArrayAccess_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_read_default_value; ZVAL_FALSE(&property_read_default_value); diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index d1c587420fc2d..ac0d572147a59 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -620,7 +620,11 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestClass", class__ZendTestClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zend_class_implements(class_entry, 1, class_entry__ZendTestInterface); zend_register_class_alias("_ZendTestClassAlias", class_entry); @@ -753,7 +757,11 @@ static zend_class_entry *register_class__ZendTestMagicCall(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestMagicCall", class__ZendTestMagicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -763,7 +771,11 @@ static zend_class_entry *register_class__ZendTestChildClass(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestChildClass", class__ZendTestChildClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry__ZendTestClass, 0); +#else class_entry = zend_register_internal_class_ex(&ce, class_entry__ZendTestClass); +#endif return class_entry; } @@ -773,7 +785,11 @@ static zend_class_entry *register_class_ZendAttributeTest(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendAttributeTest", class_ZendAttributeTest_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval const_TEST_CONST_value; ZVAL_LONG(&const_TEST_CONST_value, 1); @@ -822,8 +838,12 @@ static zend_class_entry *register_class__ZendTestTrait(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestTrait", class__ZendTestTrait_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif zval property_testProp_default_value; ZVAL_NULL(&property_testProp_default_value); @@ -852,8 +872,12 @@ static zend_class_entry *register_class_ZendTestAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestAttribute", class_ZendTestAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zend_string *attribute_name_Attribute_class_ZendTestAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestAttribute_0, 1); @@ -870,8 +894,12 @@ static zend_class_entry *register_class_ZendTestAttributeWithArguments(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestAttributeWithArguments", class_ZendTestAttributeWithArguments_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zval property_arg_default_value; ZVAL_UNDEF(&property_arg_default_value); @@ -898,8 +926,12 @@ static zend_class_entry *register_class_ZendTestRepeatableAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestRepeatableAttribute", class_ZendTestRepeatableAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zend_string *attribute_name_Attribute_class_ZendTestRepeatableAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestRepeatableAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestRepeatableAttribute_0, 1); @@ -916,8 +948,12 @@ static zend_class_entry *register_class_ZendTestParameterAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zval property_parameter_default_value; ZVAL_UNDEF(&property_parameter_default_value); @@ -940,8 +976,12 @@ static zend_class_entry *register_class_ZendTestPropertyAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestPropertyAttribute", class_ZendTestPropertyAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif #if (PHP_VERSION_ID >= 80400) class_entry->doc_comment = zend_string_init_interned("/**\n * \"Lorem ipsum\"\n * @see https://www.php.net\n * @since 8.1\n */", 82, 1); #endif @@ -968,7 +1008,11 @@ static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zend_string *attribute_name_ZendTestParameterAttribute_func_no_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); @@ -995,7 +1039,11 @@ static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParamete zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute, 0); +#else class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute); +#endif zend_string *attribute_name_ZendTestParameterAttribute_func_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); @@ -1014,7 +1062,11 @@ static zend_class_entry *register_class_ZendTestClassWithPropertyAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestClassWithPropertyAttribute", class_ZendTestClassWithPropertyAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval property_attributed_default_value; ZVAL_UNDEF(&property_attributed_default_value); @@ -1035,8 +1087,12 @@ static zend_class_entry *register_class_ZendTestForbidDynamicCall(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestForbidDynamicCall", class_ZendTestForbidDynamicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif return class_entry; } @@ -1109,7 +1165,11 @@ static zend_class_entry *register_class_ZendTestNS_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "Foo", class_ZendTestNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1119,7 +1179,11 @@ static zend_class_entry *register_class_ZendTestNS_UnlikelyCompileError(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "UnlikelyCompileError", class_ZendTestNS_UnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1129,7 +1193,11 @@ static zend_class_entry *register_class_ZendTestNS_NotUnlikelyCompileError(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "NotUnlikelyCompileError", class_ZendTestNS_NotUnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1139,7 +1207,11 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2", "Foo", class_ZendTestNS2_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval property_foo_default_value; ZVAL_UNDEF(&property_foo_default_value); @@ -1156,7 +1228,11 @@ static zend_class_entry *register_class_ZendTestNS2_ZendSubNS_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2\\ZendSubNS", "Foo", class_ZendTestNS2_ZendSubNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 2a43bc4bf76a7..79e1185cfa164 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -616,7 +616,7 @@ static zend_class_entry *register_class_ZipArchive(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZipArchive", class_ZipArchive_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Countable); zval const_CREATE_value; diff --git a/ext/zlib/zlib_arginfo.h b/ext/zlib/zlib_arginfo.h index 1c0c9746d3d27..c29bd68936195 100644 --- a/ext/zlib/zlib_arginfo.h +++ b/ext/zlib/zlib_arginfo.h @@ -240,8 +240,7 @@ static zend_class_entry *register_class_InflateContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InflateContext", class_InflateContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -251,8 +250,7 @@ static zend_class_entry *register_class_DeflateContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DeflateContext", class_DeflateContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } From 4b6575a1f94ee4c8298dc11865b08b0f615ccf48 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 24 Aug 2024 12:20:27 +0200 Subject: [PATCH 176/280] Fix GH-15565: --disable-ipv6 during compilation produces error EAI_SYSTEM not found Closes GH-15567. --- NEWS | 2 ++ main/network.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 4653280876c04..64d4e9d4ddc25 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS (zeriyoshi) . Fixed bug GH-15515 (Configure error grep illegal option q). (Peter Kokot) . Fixed bug GH-15514 (Configure error: genif.sh: syntax error). (Peter Kokot) + . Fixed bug GH-15565 (--disable-ipv6 during compilation produces error + EAI_SYSTEM not found). (nielsdos) - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in diff --git a/main/network.c b/main/network.c index 1133bbb3e86cb..d6922064561fb 100644 --- a/main/network.c +++ b/main/network.c @@ -118,7 +118,9 @@ static const char *php_gai_strerror(int code) {EAI_NONAME, "Name or service not known"}, {EAI_SERVICE, "Servname not supported for ai_socktype"}, {EAI_SOCKTYPE, "ai_socktype not supported"}, +# ifdef EAI_SYSTEM {EAI_SYSTEM, "System error"}, +# endif {0, NULL} }; int i; From 67aac59cfc32c3d12399dbf2d9af71006f337cbf Mon Sep 17 00:00:00 2001 From: Flavio Heleno Date: Mon, 6 May 2024 11:56:48 -0300 Subject: [PATCH 177/280] Add PHP-FPM memory peak to the scoreboard Closes #14153 --- NEWS | 3 +++ UPGRADING | 1 + sapi/fpm/fpm/fpm_php_trace.c | 2 +- sapi/fpm/fpm/fpm_process_ctl.c | 8 ++++---- sapi/fpm/fpm/fpm_request.c | 7 +++++-- sapi/fpm/fpm/fpm_scoreboard.c | 9 ++++++--- sapi/fpm/fpm/fpm_scoreboard.h | 5 +++-- sapi/fpm/fpm/fpm_sockets.c | 2 +- sapi/fpm/fpm/fpm_status.c | 20 +++++++++++++++----- sapi/fpm/tests/fpm_get_status_basic.phpt | 4 +++- sapi/fpm/tests/status.inc | 4 ++++ 11 files changed, 46 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 2436f1b85a8e6..0eb5cc1f5dc42 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,9 @@ PHP NEWS . Fixed bug GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h). (nielsdos) +- FPM: + . Added memory peak to the scoreboard / status page. (Flávio Heleno) + - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) diff --git a/UPGRADING b/UPGRADING index 2107a07472584..88d022c2421de 100644 --- a/UPGRADING +++ b/UPGRADING @@ -290,6 +290,7 @@ PHP 8.4 UPGRADE NOTES - FPM: . Flushing headers without a body will now succeed. See GH-12785. + . Status page has a new field to display a memory peak. - Hash: . Added HashContext::__debugInfo(). diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index b1535b26e3ef8..fca79e4bf70e8 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -189,7 +189,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * void fpm_php_trace(struct fpm_child_s *child) /* {{{ */ { - fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); FILE *slowlog; zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid); diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c index 7a55d98b046fc..4abffdf093d01 100644 --- a/sapi/fpm/fpm/fpm_process_ctl.c +++ b/sapi/fpm/fpm/fpm_process_ctl.c @@ -373,7 +373,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ } } - fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); + fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); /* this is specific to PM_STYLE_ONDEMAND */ if (wp->config->pm == PM_STYLE_ONDEMAND) { @@ -406,7 +406,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ if (idle < wp->config->pm_min_spare_servers) { if (wp->running_children >= wp->config->pm_max_children) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } @@ -425,7 +425,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ children_to_fork = MIN(children_to_fork, wp->config->pm_max_children - wp->running_children); if (children_to_fork <= 0) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } @@ -529,7 +529,7 @@ void fpm_pctl_on_socket_accept(struct fpm_event_s *ev, short which, void *arg) / if (wp->running_children >= wp->config->pm_max_children) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c index 0eb75884d367a..92c6fa8f2cca9 100644 --- a/sapi/fpm/fpm/fpm_request.c +++ b/sapi/fpm/fpm/fpm_request.c @@ -54,7 +54,7 @@ void fpm_request_accepting(void) fpm_scoreboard_proc_release(proc); /* idle++, active-- */ - fpm_scoreboard_update_commit(1, -1, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); + fpm_scoreboard_update_commit(1, -1, 0, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); } void fpm_request_reading_headers(void) @@ -98,7 +98,7 @@ void fpm_request_reading_headers(void) fpm_scoreboard_proc_release(proc); /* idle--, active++, request++ */ - fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); + fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); } void fpm_request_info(void) @@ -199,6 +199,9 @@ void fpm_request_end(void) #endif proc->memory = memory; fpm_scoreboard_proc_release(proc); + + /* memory_peak */ + fpm_scoreboard_update_commit(0, 0, 0, 0, 0, 0, 0, proc->memory, FPM_SCOREBOARD_ACTION_SET, NULL); } void fpm_request_finished(void) diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 32f8e9ab161d8..4306d814dc07d 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -99,7 +99,7 @@ void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard) /* {{{ */ void fpm_scoreboard_update_commit( int idle, int active, int lq, int lq_len, int requests, int max_children_reached, - int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ + int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ { scoreboard = fpm_scoreboard_get_for_update(scoreboard); if (!scoreboard) { @@ -169,6 +169,9 @@ void fpm_scoreboard_update_commit( if (scoreboard->active > scoreboard->active_max) { scoreboard->active_max = scoreboard->active; } + if (scoreboard->memory_peak < memory_peak) { + scoreboard->memory_peak = memory_peak; + } fpm_unlock(scoreboard->lock); } @@ -177,11 +180,11 @@ void fpm_scoreboard_update_commit( void fpm_scoreboard_update( int idle, int active, int lq, int lq_len, int requests, int max_children_reached, - int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ + int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ { fpm_scoreboard_update_begin(scoreboard); fpm_scoreboard_update_commit( - idle, active, lq, lq_len, requests, max_children_reached, slow_rq, action, scoreboard); + idle, active, lq, lq_len, requests, max_children_reached, slow_rq, memory_peak, action, scoreboard); } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 5aeb5555133a7..4ccd8cfb4e23f 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -66,6 +66,7 @@ struct fpm_scoreboard_s { unsigned int nprocs; int free_proc; unsigned long int slow_rq; + size_t memory_peak; struct fpm_scoreboard_s *shared; struct fpm_scoreboard_proc_s procs[] ZEND_ELEMENT_COUNT(nprocs); }; @@ -74,8 +75,8 @@ int fpm_scoreboard_init_main(void); int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp); void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard); -void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); -void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); +void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_max, int action, struct fpm_scoreboard_s *scoreboard); +void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_max, int action, struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_s *fpm_scoreboard_get(void); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index); diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 18307ccaa0889..9a06f6d874b1e 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -514,7 +514,7 @@ int fpm_sockets_init_main(void) } if (wp->listen_address_domain == FPM_AF_INET && fpm_socket_get_listening_queue(wp->listening_socket, NULL, &lq_len) >= 0) { - fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); + fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, 0, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); } } diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index e9b6ce2d95cdb..cbf8644d99cab 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -94,6 +94,7 @@ int fpm_status_export_to_zval(zval *status) add_assoc_long(status, "max-active-processes", scoreboard.active_max); add_assoc_long(status, "max-children-reached", scoreboard.max_children_reached); add_assoc_long(status, "slow-requests", scoreboard.slow_rq); + add_assoc_long(status, "memory-peak", scoreboard.memory_peak); array_init(&fpm_proc_stats); for(i=0; imax active processes%d\n" "max children reached%u\n" "slow requests%lu\n" + "memory peak%zu\n" "\n"; if (!full) { @@ -309,7 +311,8 @@ int fpm_status_handle_request(void) /* {{{ */ "%d\n" "%d\n" "%u\n" - "%lu\n"; + "%lu\n" + "%zu\n"; if (!full) { short_post = ""; @@ -357,7 +360,8 @@ int fpm_status_handle_request(void) /* {{{ */ "\"total processes\":%d," "\"max active processes\":%d," "\"max children reached\":%u," - "\"slow requests\":%lu"; + "\"slow requests\":%lu," + "\"memory peak\":%zu"; if (!full) { short_post = "}"; @@ -426,6 +430,9 @@ int fpm_status_handle_request(void) /* {{{ */ "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value.\n" "# TYPE phpfpm_slow_requests counter\n" "phpfpm_slow_requests %lu\n" + "# HELP phpfpm_memory_peak The memory usage peak since FPM has started.\n" + "# TYPE phpfpm_memory_peak gauge\n" + "phpfpm_memory_peak %zu\n" "# EOF\n"; has_start_time = 0; @@ -457,7 +464,8 @@ int fpm_status_handle_request(void) /* {{{ */ "total processes: %d\n" "max active processes: %d\n" "max children reached: %u\n" - "slow requests: %lu\n"; + "slow requests: %lu\n" + "memory peak: %zu\n"; if (full) { full_syntax = @@ -496,7 +504,8 @@ int fpm_status_handle_request(void) /* {{{ */ scoreboard_p->idle + scoreboard_p->active, scoreboard_p->active_max, scoreboard_p->max_children_reached, - scoreboard_p->slow_rq); + scoreboard_p->slow_rq, + scoreboard_p->memory_peak); } else { spprintf(&buffer, 0, short_syntax, scoreboard_p->pool, @@ -511,7 +520,8 @@ int fpm_status_handle_request(void) /* {{{ */ scoreboard_p->idle + scoreboard_p->active, scoreboard_p->active_max, scoreboard_p->max_children_reached, - scoreboard_p->slow_rq); + scoreboard_p->slow_rq, + scoreboard_p->memory_peak); } PUTS(buffer); diff --git a/sapi/fpm/tests/fpm_get_status_basic.phpt b/sapi/fpm/tests/fpm_get_status_basic.phpt index d72a1f4d70aca..e566bedd7b29d 100644 --- a/sapi/fpm/tests/fpm_get_status_basic.phpt +++ b/sapi/fpm/tests/fpm_get_status_basic.phpt @@ -39,7 +39,7 @@ $tester->close(); Done --EXPECTF-- Test Start -array(15) { +array(16) { ["pool"]=> string(10) "unconfined" ["process-manager"]=> @@ -68,6 +68,8 @@ array(15) { int(0) ["slow-requests"]=> int(0) + ["memory-peak"]=> + int(0) ["procs"]=> array(1) { [0]=> diff --git a/sapi/fpm/tests/status.inc b/sapi/fpm/tests/status.inc index dc07de563adbc..76ef7fd55e118 100644 --- a/sapi/fpm/tests/status.inc +++ b/sapi/fpm/tests/status.inc @@ -35,6 +35,7 @@ class Status 'max active processes' => '\d+', 'max children reached' => '\d+', 'slow requests' => '\d+', + 'memory peak' => '\d+', ]; /** @@ -266,6 +267,9 @@ class Status "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value\.\n" . "# TYPE phpfpm_slow_requests counter\n" . "phpfpm_slow_requests " . $fields['slow requests'] . "\n" . + "# HELP phpfpm_memory_peak The memory usage peak since FPM has started\.\n" . + "# TYPE phpfpm_memory_peak gauge\n" . + "phpfpm_memory_peak " . $fields['memory peak'] . "\n" . "# EOF)\n"; if (!preg_match($pattern, $body)) { From 9c267778d2e1571eadb71077254a79638ba6dd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orlando=20Th=C3=B6ny?= Date: Sat, 24 Aug 2024 16:26:58 +0200 Subject: [PATCH 178/280] FPM: Remove usage of non-existing MAX_LINE_LENGTH constant (#5634) --- sapi/fpm/fpm/fpm_log.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c index bb66c081258d5..6619b7c26f064 100644 --- a/sapi/fpm/fpm/fpm_log.c +++ b/sapi/fpm/fpm/fpm_log.c @@ -19,11 +19,7 @@ #include "fastcgi.h" #include "zlog.h" -#ifdef MAX_LINE_LENGTH -# define FPM_LOG_BUFFER MAX_LINE_LENGTH -#else -# define FPM_LOG_BUFFER 1024 -#endif +#define FPM_LOG_BUFFER 1024 static char *fpm_log_format = NULL; static int fpm_log_fd = -1; From c5bce0d8a2e6794cd6809e4047dd1f488fa3459b Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sat, 24 Aug 2024 16:33:45 +0200 Subject: [PATCH 179/280] Deprecate disabling use_only_cookies (#13578) --- ext/session/session.c | 44 +++++++++++-- ext/session/tests/015.phpt | 10 ++- ext/session/tests/018.phpt | 3 + ext/session/tests/020.phpt | 3 + ext/session/tests/021.phpt | 7 +- ext/session/tests/bug36459.phpt | 3 + ext/session/tests/bug41600.phpt | 3 + ext/session/tests/bug42596.phpt | 1 + ext/session/tests/bug50308.phpt | 3 + ext/session/tests/bug51338.phpt | 1 + ext/session/tests/bug71683.phpt | 1 + ext/session/tests/bug71974.phpt | 1 + ext/session/tests/bug72940.phpt | 9 ++- ext/session/tests/bug74892.phpt | 17 +++-- ext/session/tests/deprecations.phpt | 64 +++++++++++++++++++ ext/session/tests/gh13891.phpt | 11 +++- ext/session/tests/rfc1867.phpt | 1 + ext/session/tests/rfc1867_cleanup.phpt | 1 + ext/session/tests/rfc1867_disabled.phpt | 1 + ext/session/tests/rfc1867_disabled_2.phpt | 1 + ext/session/tests/rfc1867_inter.phpt | 1 + ext/session/tests/rfc1867_no_name.phpt | 1 + ext/session/tests/rfc1867_sid_cookie.phpt | 1 + ext/session/tests/rfc1867_sid_get.phpt | 1 + ext/session/tests/rfc1867_sid_get_2.phpt | 1 + ext/session/tests/rfc1867_sid_invalid.phpt | 1 - ext/session/tests/rfc1867_sid_post.phpt | 1 + ext/session/tests/session_basic3.phpt | 3 + ext/session/tests/session_basic4.phpt | 3 + ext/session/tests/session_basic5.phpt | 7 +- .../tests/general_functions/bug44394_2.phpt | 5 +- .../output_add_rewrite_var_basic1.phpt | 7 +- .../output_add_rewrite_var_basic2.phpt | 5 +- .../output_add_rewrite_var_basic3.phpt | 5 +- .../output_add_rewrite_var_basic4.phpt | 4 +- .../url_rewriting_basic1.phpt | 7 +- .../url_rewriting_basic2.phpt | 7 +- .../url_rewriting_basic3.phpt | 7 +- ext/standard/url_scanner_ex.re | 6 ++ 39 files changed, 233 insertions(+), 25 deletions(-) create mode 100644 ext/session/tests/deprecations.phpt diff --git a/ext/session/session.c b/ext/session/session.c index 6c954a9327831..3d762886dbb6d 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -846,6 +846,40 @@ static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */ return SUCCESS; } /* }}} */ +static PHP_INI_MH(OnUpdateUseOnlyCookies) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + bool *p = (bool *) ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_bool(new_value); + if (!*p) { + php_error_docref("session.configuration", E_DEPRECATED, "Disabling session.use_only_cookies INI setting is deprecated"); + } + return SUCCESS; +} + +static PHP_INI_MH(OnUpdateUseTransSid) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + bool *p = (bool *) ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_bool(new_value); + if (*p) { + php_error_docref("session.configuration", E_DEPRECATED, "Enabling session.use_trans_sid INI setting is deprecated"); + } + return SUCCESS; +} + +static PHP_INI_MH(OnUpdateRefererCheck) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + if (ZSTR_LEN(new_value) != 0) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.referer_check INI setting is deprecated"); + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + /* {{{ PHP_INI */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) @@ -863,12 +897,12 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionString, cookie_samesite, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_only_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateSessionString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionString, cache_limiter, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateSessionBool, use_trans_sid, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) @@ -1516,7 +1550,7 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */ zval_ptr_dtor_str(sid); ZVAL_STR(sid, smart_str_extract(&var)); } else { - REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), 0); + REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), CONST_DEPRECATED); smart_str_free(&var); } } else { @@ -1524,7 +1558,7 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */ zval_ptr_dtor_str(sid); ZVAL_EMPTY_STRING(sid); } else { - REGISTER_STRINGL_CONSTANT("SID", "", 0, 0); + REGISTER_STRINGL_CONSTANT("SID", "", 0, CONST_DEPRECATED); } } diff --git a/ext/session/tests/015.phpt b/ext/session/tests/015.phpt index 1d6e9d65fe67e..3154022fae861 100644 --- a/ext/session/tests/015.phpt +++ b/ext/session/tests/015.phpt @@ -20,10 +20,16 @@ error_reporting(E_ALL); session_id("test015"); session_start(); +$sid = SID; ?> - + ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: Constant SID is deprecated in %s on line 6 diff --git a/ext/session/tests/018.phpt b/ext/session/tests/018.phpt index f504f120d6b10..5d9c6eb6261b1 100644 --- a/ext/session/tests/018.phpt +++ b/ext/session/tests/018.phpt @@ -26,4 +26,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0
diff --git a/ext/session/tests/020.phpt b/ext/session/tests/020.phpt index 873973f04bfc5..3fb64dbc076ae 100644 --- a/ext/session/tests/020.phpt +++ b/ext/session/tests/020.phpt @@ -27,4 +27,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/021.phpt b/ext/session/tests/021.phpt index 02f712a9d871e..00d5779adf421 100644 --- a/ext/session/tests/021.phpt +++ b/ext/session/tests/021.phpt @@ -59,7 +59,12 @@ ini_set("url_rewriter.tags", "a=href,fieldset=,area=href,frame=src,input=src"); session_destroy(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 4
diff --git a/ext/session/tests/bug36459.phpt b/ext/session/tests/bug36459.phpt index 201aed60e056e..21a5f62c64312 100644 --- a/ext/session/tests/bug36459.phpt +++ b/ext/session/tests/bug36459.phpt @@ -30,6 +30,9 @@ session_start(); --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 Bug #36459 Incorrect adding PHPSESSID to links, which contains \r\n diff --git a/ext/session/tests/bug41600.phpt b/ext/session/tests/bug41600.phpt index 4181becfef395..09e89e67ea1a8 100644 --- a/ext/session/tests/bug41600.phpt +++ b/ext/session/tests/bug41600.phpt @@ -27,4 +27,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/bug42596.phpt b/ext/session/tests/bug42596.phpt index dca5fc0c99068..c1217384ce850 100644 --- a/ext/session/tests/bug42596.phpt +++ b/ext/session/tests/bug42596.phpt @@ -34,5 +34,6 @@ foreach (glob($sessdir. "*") as $sessfile) { rmdir($sessdir); ?> --EXPECT-- +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 hello world string(6) "100777" diff --git a/ext/session/tests/bug50308.phpt b/ext/session/tests/bug50308.phpt index 414a8354d35fd..920f967d42f9b 100644 --- a/ext/session/tests/bug50308.phpt +++ b/ext/session/tests/bug50308.phpt @@ -25,6 +25,9 @@ session.use_only_cookies=0 --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/bug51338.phpt b/ext/session/tests/bug51338.phpt index d6a2ddb652746..44d6cface0538 100644 --- a/ext/session/tests/bug51338.phpt +++ b/ext/session/tests/bug51338.phpt @@ -13,6 +13,7 @@ session_start(); print_r(ob_list_handlers()); ?> --EXPECT-- +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 Array ( ) diff --git a/ext/session/tests/bug71683.phpt b/ext/session/tests/bug71683.phpt index 9541121daa3b3..ad4783ee50cc3 100644 --- a/ext/session/tests/bug71683.phpt +++ b/ext/session/tests/bug71683.phpt @@ -14,4 +14,5 @@ ob_start(); echo "ok\n"; ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 ok diff --git a/ext/session/tests/bug71974.phpt b/ext/session/tests/bug71974.phpt index 1c16ab1c24e46..225a465f4c572 100644 --- a/ext/session/tests/bug71974.phpt +++ b/ext/session/tests/bug71974.phpt @@ -5,6 +5,7 @@ session --SKIPIF-- --INI-- +display_startup_errors=0 session.save_handler=files session.auto_start=0 session.use_cookies=1 diff --git a/ext/session/tests/bug72940.phpt b/ext/session/tests/bug72940.phpt index 740c5410743f5..9a927a5419e4a 100644 --- a/ext/session/tests/bug72940.phpt +++ b/ext/session/tests/bug72940.phpt @@ -31,8 +31,15 @@ session_start(); var_dump(session_id(), SID); session_destroy(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 + +Deprecated: Constant SID is deprecated in %s on line 8 string(12) "bug72940test" string(0) "" + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 13 + +Deprecated: Constant SID is deprecated in %s on line 15 string(11) "bug72940get" string(21) "PHPSESSID=bug72940get" diff --git a/ext/session/tests/bug74892.phpt b/ext/session/tests/bug74892.phpt index 793e67cfadd44..916120cb4d447 100644 --- a/ext/session/tests/bug74892.phpt +++ b/ext/session/tests/bug74892.phpt @@ -1,15 +1,17 @@ --TEST-- Bug #74892 Url Rewriting (trans_sid) not working on urls that start with # +--INI-- +session.use_cookies=0 +session.use_only_cookies=0 +session.use_trans_sid=1 --EXTENSIONS-- session --SKIPIF-- --FILE-- External link with anchor

External link with anchor 2

Internal link

---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 3

Click This Anchor Tag!

External link with anchor

External link with anchor 2

diff --git a/ext/session/tests/deprecations.phpt b/ext/session/tests/deprecations.phpt new file mode 100644 index 0000000000000..4a2337fb99dad --- /dev/null +++ b/ext/session/tests/deprecations.phpt @@ -0,0 +1,64 @@ +--TEST-- +Deprecated GET/POST sessions +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.use_cookies=0 +session.use_only_cookies=1 +session.use_trans_sid=0 +--FILE-- + '0', 'use_only_cookies' => '0', 'use_trans_sid' => '1']); + +echo SID; + +?> +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 11 + +Deprecated: ini_set(): Usage of session.trans_sid_tags INI setting is deprecated in %s on line 16 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 21 + +Deprecated: ini_set(): Usage of session.referer_check INI setting is deprecated in %s on line 26 + +Deprecated: session_start(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 32 + +Deprecated: session_start(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 32 + +Deprecated: Constant SID is deprecated in %s on line 34 +PHPSESSID=%s diff --git a/ext/session/tests/gh13891.phpt b/ext/session/tests/gh13891.phpt index 7df9bffa770bc..97c0bfd617b70 100644 --- a/ext/session/tests/gh13891.phpt +++ b/ext/session/tests/gh13891.phpt @@ -14,4 +14,13 @@ session // We *must* set it here because the bug only triggers on a runtime edit ini_set('session.trans_sid_hosts','php.net'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Usage of session.trans_sid_hosts INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 3 + +Deprecated: PHP Request Shutdown: Usage of session.trans_sid_hosts INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/rfc1867.phpt b/ext/session/tests/rfc1867.phpt index 0962a91bc4fe7..6e2cf22752947 100644 --- a/ext/session/tests/rfc1867.phpt +++ b/ext/session/tests/rfc1867.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_cleanup.phpt b/ext/session/tests/rfc1867_cleanup.phpt index cdfd3c833104b..2cb25e8d6929a 100644 --- a/ext/session/tests/rfc1867_cleanup.phpt +++ b/ext/session/tests/rfc1867_cleanup.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_disabled.phpt b/ext/session/tests/rfc1867_disabled.phpt index a928a6171c33c..4ca2048f0446e 100644 --- a/ext/session/tests/rfc1867_disabled.phpt +++ b/ext/session/tests/rfc1867_disabled.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 disabled --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_disabled_2.phpt b/ext/session/tests/rfc1867_disabled_2.phpt index dcfbe075cbf5b..eb45d7f4bbcd3 100644 --- a/ext/session/tests/rfc1867_disabled_2.phpt +++ b/ext/session/tests/rfc1867_disabled_2.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 disabled 2 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_inter.phpt b/ext/session/tests/rfc1867_inter.phpt index a7ddff14f5e72..5ab9983ea14b1 100644 --- a/ext/session/tests/rfc1867_inter.phpt +++ b/ext/session/tests/rfc1867_inter.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_no_name.phpt b/ext/session/tests/rfc1867_no_name.phpt index d6a771baf2164..693c3814ec0d2 100644 --- a/ext/session/tests/rfc1867_no_name.phpt +++ b/ext/session/tests/rfc1867_no_name.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 no name --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_cookie.phpt b/ext/session/tests/rfc1867_sid_cookie.phpt index e090ebec5d6e6..5dc6492050f4f 100644 --- a/ext/session/tests/rfc1867_sid_cookie.phpt +++ b/ext/session/tests/rfc1867_sid_cookie.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid cookie --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_get.phpt b/ext/session/tests/rfc1867_sid_get.phpt index f227dd7d34300..8929556cdb0b3 100644 --- a/ext/session/tests/rfc1867_sid_get.phpt +++ b/ext/session/tests/rfc1867_sid_get.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid get --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_get_2.phpt b/ext/session/tests/rfc1867_sid_get_2.phpt index 8362f3b58d480..1a771935c4af0 100644 --- a/ext/session/tests/rfc1867_sid_get_2.phpt +++ b/ext/session/tests/rfc1867_sid_get_2.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid get 2 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_invalid.phpt b/ext/session/tests/rfc1867_sid_invalid.phpt index fe01b5a8ba2aa..2a61ab98d9206 100644 --- a/ext/session/tests/rfc1867_sid_invalid.phpt +++ b/ext/session/tests/rfc1867_sid_invalid.phpt @@ -6,7 +6,6 @@ upload_max_filesize=1024 session.save_path= session.name=PHPSESSID session.use_cookies=1 -session.use_only_cookies=0 session.use_strict_mode=0 session.auto_start=0 session.upload_progress.enabled=1 diff --git a/ext/session/tests/rfc1867_sid_post.phpt b/ext/session/tests/rfc1867_sid_post.phpt index e1f2123b56a58..62bc17bd83831 100644 --- a/ext/session/tests/rfc1867_sid_post.phpt +++ b/ext/session/tests/rfc1867_sid_post.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid post --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/session_basic3.phpt b/ext/session/tests/session_basic3.phpt index 661f48546d123..7ddeffaa48d37 100644 --- a/ext/session/tests/session_basic3.phpt +++ b/ext/session/tests/session_basic3.phpt @@ -222,6 +222,9 @@ var_dump(session_destroy()); ob_end_flush(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 *** Testing basic session functionality : variation3 use_trans_sid *** *** Test trans sid *** diff --git a/ext/session/tests/session_basic4.phpt b/ext/session/tests/session_basic4.phpt index 93b04604d24d4..d1c8cdcd95928 100644 --- a/ext/session/tests/session_basic4.phpt +++ b/ext/session/tests/session_basic4.phpt @@ -48,6 +48,9 @@ echo ' '; ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 *** Testing basic session functionality : variation4 use_trans_sid *** *** Test trans sid *** diff --git a/ext/session/tests/session_basic5.phpt b/ext/session/tests/session_basic5.phpt index 4f1d39ee02701..dd029b8aeeb7b 100644 --- a/ext/session/tests/session_basic5.phpt +++ b/ext/session/tests/session_basic5.phpt @@ -234,7 +234,12 @@ var_dump(session_destroy()); ob_end_flush(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 *** Testing basic session functionality : variation5 use_trans_sid *** *** Test trans sid *** diff --git a/ext/standard/tests/general_functions/bug44394_2.phpt b/ext/standard/tests/general_functions/bug44394_2.phpt index 356291318c8ba..c6107def029da 100644 --- a/ext/standard/tests/general_functions/bug44394_2.phpt +++ b/ext/standard/tests/general_functions/bug44394_2.phpt @@ -5,12 +5,12 @@ session --INI-- session.name=PHPSESSID session.use_only_cookies=0 +session.use_trans_sid=1 session.trans_sid_tags="a=href,area=href,frame=src,form=" url_rewriter.tags="a=href,area=href,frame=src,form=" --FILE-- --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 asd diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt index 007772f408a3f..62ef24429b211 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt @@ -74,7 +74,10 @@ Test use_trans_sid=1
---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 Without session @@ -105,6 +108,8 @@ Test use_trans_sid=0
+ +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt index 3aba659c34387..3f133669ad57a 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt @@ -74,7 +74,8 @@ Test use_trans_sid=1
---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 Without session @@ -105,6 +106,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt index 92cd59e4f458e..7a407f9e1caa6 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt @@ -73,7 +73,8 @@ Test use_trans_sid=1 ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 5 Without session @@ -104,6 +105,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 49 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt index 7dc1ecaa4b7d4..ae7f7a979e672 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt @@ -73,7 +73,7 @@ Test use_trans_sid=1 ---EXPECT-- +--EXPECTF-- Without session @@ -104,6 +104,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 49 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/url_rewriting_basic1.phpt b/ext/standard/tests/general_functions/url_rewriting_basic1.phpt index 4c1f6784dcb2c..0bc3a64573ce2 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic1.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic1.phpt @@ -76,7 +76,8 @@ session_start(); echo "\nURL-Rewriting with transparent session id support without output_add_rewrite_var()\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 URL-Rewriting with output_add_rewrite_var() without transparent session id support @@ -115,6 +116,10 @@ URL-Rewriting with output_add_rewrite_var() without transparent session id suppo
+Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 60 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 63 + URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/tests/general_functions/url_rewriting_basic2.phpt b/ext/standard/tests/general_functions/url_rewriting_basic2.phpt index 635383a33c913..bed24209eee7c 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic2.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic2.phpt @@ -87,7 +87,8 @@ output_add_rewrite_var('', ''); echo "\nURL-Rewriting with output_add_rewrite_var() without transparent session id support\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 URL-Rewriting with output_add_rewrite_var() without transparent session id support @@ -126,6 +127,10 @@ URL-Rewriting with output_add_rewrite_var() without transparent session id suppo
+Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 61 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 64 + URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/tests/general_functions/url_rewriting_basic3.phpt b/ext/standard/tests/general_functions/url_rewriting_basic3.phpt index edf41ba4fe200..7a2eed0823d9f 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic3.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic3.phpt @@ -80,7 +80,12 @@ output_add_rewrite_var('', ''); echo "\nURL-Rewriting with transparent session id support without output_add_rewrite_var()\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 47 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 305be39d8780f..1ce7521d7fab1 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -102,6 +102,9 @@ static zend_result php_ini_on_update_tags(zend_ini_entry *entry, zend_string *ne static PHP_INI_MH(OnUpdateSessionTags) { + if (!zend_string_starts_with_literal(new_value, "a=href,area=href,frame=src,form=")) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.trans_sid_tags INI setting is deprecated"); + } return php_ini_on_update_tags(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, /* is_session */ true); } @@ -152,6 +155,9 @@ static zend_result php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *n static PHP_INI_MH(OnUpdateSessionHosts) { + if (ZSTR_LEN(new_value) != 0) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.trans_sid_hosts INI setting is deprecated"); + } return php_ini_on_update_hosts(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, /* is_session */ true); } From 207ae12f59bf7d3e94b56f62a583c0c0dcafa258 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 24 Aug 2024 23:17:22 +0200 Subject: [PATCH 180/280] Autotools: Sync CS in ext/tidy (#15561) - AS_* macros used - When TIDY_DIR is not set error out in its own "if" sentence - break 2 used instead of break to exit also the first for loop --- ext/tidy/config.m4 | 51 +++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4 index 9c0fd05ff36fd..e179a31d60bfd 100644 --- a/ext/tidy/config.m4 +++ b/ext/tidy/config.m4 @@ -4,40 +4,35 @@ PHP_ARG_WITH([tidy], [Include TIDY support])]) if test "$PHP_TIDY" != "no"; then - - if test "$PHP_TIDY" != "yes"; then - TIDY_SEARCH_DIRS=$PHP_TIDY - else - TIDY_SEARCH_DIRS="/usr/local /usr" - fi + AS_VAR_IF([PHP_TIDY], [yes], + [TIDY_SEARCH_DIRS="/usr/local /usr"], + [TIDY_SEARCH_DIRS=$PHP_TIDY]) for i in $TIDY_SEARCH_DIRS; do for j in tidy tidyp; do - if test -f $i/include/$j/$j.h; then - TIDY_DIR=$i - TIDY_INCDIR=$i/include/$j - TIDY_LIB_NAME=$j - break - elif test -f $i/include/$j.h; then - TIDY_DIR=$i - TIDY_INCDIR=$i/include - TIDY_LIB_NAME=$j - break - fi + AS_IF([test -f $i/include/$j/$j.h], [ + TIDY_DIR=$i + TIDY_INCDIR=$i/include/$j + TIDY_LIB_NAME=$j + break 2 + ], + [test -f $i/include/$j.h], [ + TIDY_DIR=$i + TIDY_INCDIR=$i/include + TIDY_LIB_NAME=$j + break 2 + ]) done done - if test -z "$TIDY_DIR"; then - AC_MSG_ERROR([Cannot find libtidy]) - else - dnl Check for tidybuffio.h (as opposed to simply buffio.h) which indicates - dnl that we are building against tidy-html5 and not the legacy htmltidy. The - dnl two are compatible, except for with regard to this header file. - if test -f "$TIDY_INCDIR/tidybuffio.h"; then - AC_DEFINE([HAVE_TIDYBUFFIO_H], [1], - [Define to 1 if you have the header file.]) - fi - fi + AS_VAR_IF([TIDY_DIR],, [AC_MSG_ERROR([Cannot find libtidy])]) + + dnl Check for tidybuffio.h (as opposed to simply buffio.h) which indicates + dnl that we are building against tidy-html5 and not the legacy htmltidy. The + dnl two are compatible, except for with regard to this header file. + AS_IF([test -f "$TIDY_INCDIR/tidybuffio.h"], + [AC_DEFINE([HAVE_TIDYBUFFIO_H], [1], + [Define to 1 if you have the header file.])]) TIDY_LIBDIR=$TIDY_DIR/$PHP_LIBDIR AS_VAR_IF([TIDY_LIB_NAME], [tidyp], From 082b964dfa88ddd1eba8ce9b0fad05e66dc74da2 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 15 Aug 2024 22:36:56 +0200 Subject: [PATCH 181/280] Remove ifdefs from stub file --- ext/mysqli/mysqli.stub.php | 12 ------------ ext/mysqli/mysqli_arginfo.h | 16 +--------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 9b98369600e38..de287b347deef 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -96,7 +96,6 @@ * @cvalue CLIENT_FOUND_ROWS */ const MYSQLI_CLIENT_FOUND_ROWS = UNKNOWN; -#ifdef CLIENT_SSL_VERIFY_SERVER_CERT /** * @var int * @cvalue CLIENT_SSL_VERIFY_SERVER_CERT @@ -107,7 +106,6 @@ * @cvalue CLIENT_SSL_DONT_VERIFY_SERVER_CERT */ const MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT = UNKNOWN; -#endif /** * @var int * @cvalue CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS @@ -400,13 +398,11 @@ * @cvalue FIELD_TYPE_VECTOR */ const MYSQLI_TYPE_VECTOR = UNKNOWN; -#ifdef FIELD_TYPE_JSON /** * @var int * @cvalue FIELD_TYPE_JSON */ const MYSQLI_TYPE_JSON = UNKNOWN; -#endif /** * @var int * @cvalue FIELD_TYPE_NEWDECIMAL @@ -430,14 +426,12 @@ * @deprecated */ const MYSQLI_NO_DATA = UNKNOWN; -#ifdef MYSQL_DATA_TRUNCATED /** * @var int * @cvalue MYSQL_DATA_TRUNCATED * @deprecated */ const MYSQLI_DATA_TRUNCATED = UNKNOWN; -#endif /* reporting */ /** @@ -484,22 +478,18 @@ * @deprecated */ const MYSQLI_SERVER_QUERY_NO_INDEX_USED = UNKNOWN; -#ifdef SERVER_QUERY_WAS_SLOW /** * @var int * @cvalue SERVER_QUERY_WAS_SLOW * @deprecated */ const MYSQLI_SERVER_QUERY_WAS_SLOW = UNKNOWN; -#endif -#ifdef SERVER_PS_OUT_PARAMS /** * @var int * @cvalue SERVER_PS_OUT_PARAMS * @deprecated */ const MYSQLI_SERVER_PS_OUT_PARAMS = UNKNOWN; -#endif /** * @var int @@ -555,14 +545,12 @@ * @deprecated */ const MYSQLI_REFRESH_MASTER = UNKNOWN; -#ifdef REFRESH_BACKUP_LOG /** * @var int * @cvalue REFRESH_BACKUP_LOG * @deprecated */ const MYSQLI_REFRESH_BACKUP_LOG = UNKNOWN; -#endif /** * @var int diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 827589c7b2ddf..3613b952780cb 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 245640045ed8172d7772b708787c400f29bb607b */ + * Stub hash: 32baf7b0642af68dea551687bc44ae47d708d810 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1056,12 +1056,8 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_PERSISTENT); -#if defined(CLIENT_SSL_VERIFY_SERVER_CERT) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT", CLIENT_SSL_VERIFY_SERVER_CERT, CONST_PERSISTENT); -#endif -#if defined(CLIENT_SSL_VERIFY_SERVER_CERT) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT", CLIENT_SSL_DONT_VERIFY_SERVER_CERT, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS", CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_PERSISTENT); @@ -1118,16 +1114,12 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VECTOR", FIELD_TYPE_VECTOR, CONST_PERSISTENT); -#if defined(FIELD_TYPE_JSON) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_JSON", FIELD_TYPE_JSON, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(MYSQL_DATA_TRUNCATED) REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_PERSISTENT); @@ -1136,12 +1128,8 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(SERVER_QUERY_WAS_SLOW) REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_PERSISTENT | CONST_DEPRECATED); -#endif -#if defined(SERVER_PS_OUT_PARAMS) REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_PERSISTENT | CONST_DEPRECATED); @@ -1151,9 +1139,7 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_REPLICA", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(REFRESH_BACKUP_LOG) REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_PERSISTENT); From 2446500d973c85a2dac05c51cf0a5214d0c08bcc Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 15 Aug 2024 23:16:19 +0200 Subject: [PATCH 182/280] Remove unsupported mysqlnd options --- ext/mysqli/mysqli_api.c | 25 ------------------------- ext/mysqlnd/mysqlnd_connection.c | 22 ---------------------- ext/mysqlnd/mysqlnd_enum_n_def.h | 20 ++++++++++---------- 3 files changed, 10 insertions(+), 57 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 1d5dbc26deee7..2bc33e4ad673c 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1160,45 +1160,20 @@ static int mysqli_options_get_option_zval_type(int option) case MYSQLND_OPT_NET_READ_BUFFER_SIZE: case MYSQLND_OPT_INT_AND_FLOAT_NATIVE: case MYSQL_OPT_CONNECT_TIMEOUT: -#ifdef MYSQL_REPORT_DATA_TRUNCATION - case MYSQL_REPORT_DATA_TRUNCATION: -#endif case MYSQL_OPT_LOCAL_INFILE: case MYSQL_OPT_NAMED_PIPE: -#ifdef MYSQL_OPT_PROTOCOL case MYSQL_OPT_PROTOCOL: -#endif /* MySQL 4.1.0 */ case MYSQL_OPT_READ_TIMEOUT: case MYSQL_OPT_WRITE_TIMEOUT: -#ifdef MYSQL_OPT_GUESS_CONNECTION /* removed in MySQL-8.0 */ - case MYSQL_OPT_GUESS_CONNECTION: - case MYSQL_OPT_USE_EMBEDDED_CONNECTION: - case MYSQL_OPT_USE_REMOTE_CONNECTION: - case MYSQL_SECURE_AUTH: -#endif -#ifdef MYSQL_OPT_RECONNECT - case MYSQL_OPT_RECONNECT: -#endif /* MySQL 5.0.13 */ -#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: -#endif /* MySQL 5.0.23 */ -#ifdef MYSQL_OPT_COMPRESS case MYSQL_OPT_COMPRESS: -#endif /* mysqlnd @ PHP 5.3.2 */ case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS: return IS_LONG; -#ifdef MYSQL_SHARED_MEMORY_BASE_NAME - case MYSQL_SHARED_MEMORY_BASE_NAME: -#endif /* MySQL 4.1.0 */ -#ifdef MYSQL_SET_CLIENT_IP - case MYSQL_SET_CLIENT_IP: -#endif /* MySQL 4.1.1 */ case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: case MYSQL_INIT_COMMAND: case MYSQL_SET_CHARSET_NAME: - case MYSQL_SET_CHARSET_DIR: case MYSQL_SERVER_PUBLIC_KEY: case MYSQL_OPT_LOAD_DATA_LOCAL_DIR: return IS_STRING; diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index efcca57e5c82a..8582e376e92a6 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1444,10 +1444,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c } case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SET_CLIENT_IP: - case MYSQL_REPORT_DATA_TRUNCATION: -#endif /* currently not supported. Todo!! */ break; case MYSQL_SET_CHARSET_NAME: @@ -1475,18 +1471,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c conn->options->protocol = *(unsigned int*) value; } break; -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SET_CHARSET_DIR: - case MYSQL_OPT_RECONNECT: - /* we don't need external character sets, all character sets are - compiled in. For compatibility we just ignore this setting. - Same for protocol, we don't support old protocol */ - case MYSQL_OPT_USE_REMOTE_CONNECTION: - case MYSQL_OPT_USE_EMBEDDED_CONNECTION: - case MYSQL_OPT_GUESS_CONNECTION: - /* todo: throw an error, we don't support embedded */ - break; -#endif case MYSQLND_OPT_MAX_ALLOWED_PACKET: if (*(unsigned int*) value > (1<<16)) { conn->options->max_allowed_packet = *(unsigned int*) value; @@ -1522,12 +1506,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c DBG_INF_FMT("%d left", zend_hash_num_elements(conn->options->connect_attr)); } break; -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SHARED_MEMORY_BASE_NAME: - case MYSQL_OPT_USE_RESULT: - case MYSQL_SECURE_AUTH: - /* not sure, todo ? */ -#endif default: ret = FAIL; } diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 15db002aa7349..b54ea45bcb924 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -199,21 +199,21 @@ typedef enum mysqlnd_client_option MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, - MYSQL_SET_CHARSET_DIR, + MYSQL_SET_CHARSET_DIR, /* Unsupported by mysqlnd */ MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_PROTOCOL, - MYSQL_SHARED_MEMORY_BASE_NAME, + MYSQL_SHARED_MEMORY_BASE_NAME, /* Unsupported by mysqlnd */ MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, - MYSQL_OPT_USE_RESULT, - MYSQL_OPT_USE_REMOTE_CONNECTION, - MYSQL_OPT_USE_EMBEDDED_CONNECTION, - MYSQL_OPT_GUESS_CONNECTION, - MYSQL_SET_CLIENT_IP, - MYSQL_SECURE_AUTH, - MYSQL_REPORT_DATA_TRUNCATION, - MYSQL_OPT_RECONNECT, + MYSQL_OPT_USE_RESULT, /* Unsupported by mysqlnd */ + MYSQL_OPT_USE_REMOTE_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_OPT_USE_EMBEDDED_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_OPT_GUESS_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_SET_CLIENT_IP, /* Unsupported by mysqlnd */ + MYSQL_SECURE_AUTH, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_REPORT_DATA_TRUNCATION, /* Unsupported by mysqlnd */ + MYSQL_OPT_RECONNECT, /* Unsupported by mysqlnd */ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, From 195d59a83cf2d6abd4e1c740fceae09e4cfde2f8 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 15 Aug 2024 23:19:03 +0200 Subject: [PATCH 183/280] Remove dead code --- ext/mysqlnd/mysqlnd_protocol_frame_codec.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c index ba5a512194d40..570fba24d663a 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c @@ -355,9 +355,6 @@ MYSQLND_METHOD(mysqlnd_pfc, receive)(MYSQLND_PFC * const pfc, MYSQLND_VIO * cons DBG_RETURN(FAIL); } pfc->data->compressed_envelope_packet_no++; -#ifdef MYSQLND_DUMP_HEADER_N_BODY - DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (zend_ulong) net_payload_size); -#endif /* Now let's read from the wire, decompress it and fill the read buffer */ pfc->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(pfc, vio, net_payload_size, conn_stats, error_info); From cd6bac7f9f592798ffe0b940d8b7245f0ac25c96 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:19:03 +0200 Subject: [PATCH 184/280] [ci skip] Fix mistake in UPGRADING --- UPGRADING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADING b/UPGRADING index 39ff20b0bafdd..bd25aa96df92f 100644 --- a/UPGRADING +++ b/UPGRADING @@ -395,7 +395,7 @@ PHP 8.3 UPGRADE NOTES overloaded constructor of DatePeriod. - DOM: - . Added DOMNode::contains() and DOMNameSpaceNode::contains(). + . Added DOMNode::contains(). . Added DOMElement::getAttributeNames(). . Added DOMNode::getRootNode(). The $options argument does nothing at the moment because it only influences the shadow DOM, which we do not support From 2ca4f31bc711a1744aa54808eaeee8a2fa9c6b2b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 25 Aug 2024 14:19:11 +0200 Subject: [PATCH 185/280] Update Lexbor (#15573) Updates Lexbor to lexbor/lexbor@31d86445d07c9cd2c2f475ac52cfd3c2e22c69b5 --- ext/dom/lexbor/lexbor/css/selectors/selector.h | 2 +- ext/dom/lexbor/lexbor/dom/interfaces/element.c | 9 +++------ ext/dom/lexbor/lexbor/dom/interfaces/node.c | 2 +- ext/dom/lexbor/lexbor/html/parser.c | 2 +- ext/dom/lexbor/lexbor/tag/tag.c | 11 +++++------ ext/dom/lexbor/lexbor/tag/tag.h | 16 +++++++--------- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/ext/dom/lexbor/lexbor/css/selectors/selector.h b/ext/dom/lexbor/lexbor/css/selectors/selector.h index e87f5cd590578..52dbabc7ba5ce 100644 --- a/ext/dom/lexbor/lexbor/css/selectors/selector.h +++ b/ext/dom/lexbor/lexbor/css/selectors/selector.h @@ -110,7 +110,7 @@ typedef uint32_t lxb_css_selector_specificity_t; ((sp) & ~((((uint32_t) 1 << 9) - 1) << (n))) #define LXB_CSS_SELECTOR_SPECIFICITY_MASK \ - ((((uint32_t) 1 << 31) - 1) << (9)) + ((((uint32_t) 1 << (32 - 9)) - 1) << (9)) #define lxb_css_selector_sp_i(sp) ((sp) >> 28) diff --git a/ext/dom/lexbor/lexbor/dom/interfaces/element.c b/ext/dom/lexbor/lexbor/dom/interfaces/element.c index 6bbcf9252bbcb..157beb9cf7be6 100644 --- a/ext/dom/lexbor/lexbor/dom/interfaces/element.c +++ b/ext/dom/lexbor/lexbor/dom/interfaces/element.c @@ -651,12 +651,10 @@ lxb_dom_element_qualified_name(lxb_dom_element_t *element, size_t *len) const lxb_tag_data_t *data; if (element->qualified_name != 0) { - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->qualified_name); + data = lxb_tag_data_by_id(element->qualified_name); } else { - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->node.local_name); + data = lxb_tag_data_by_id(element->node.local_name); } if (len != NULL) { @@ -723,8 +721,7 @@ lxb_dom_element_local_name(lxb_dom_element_t *element, size_t *len) { const lxb_tag_data_t *data; - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->node.local_name); + data = lxb_tag_data_by_id(element->node.local_name); if (data == NULL) { if (len != NULL) { *len = 0; diff --git a/ext/dom/lexbor/lexbor/dom/interfaces/node.c b/ext/dom/lexbor/lexbor/dom/interfaces/node.c index 702d1a802c16d..934b350858258 100644 --- a/ext/dom/lexbor/lexbor/dom/interfaces/node.c +++ b/ext/dom/lexbor/lexbor/dom/interfaces/node.c @@ -184,7 +184,7 @@ lxb_dom_node_interface_copy(lxb_dom_node_t *dst, dst->local_name = src->local_name; } else { - tag = lxb_tag_data_by_id(from->tags, src->local_name); + tag = lxb_tag_data_by_id(src->local_name); if (tag == NULL) { return LXB_STATUS_ERROR_NOT_EXISTS; } diff --git a/ext/dom/lexbor/lexbor/html/parser.c b/ext/dom/lexbor/lexbor/html/parser.c index 8ad05beb565de..caca15e4be26b 100644 --- a/ext/dom/lexbor/lexbor/html/parser.c +++ b/ext/dom/lexbor/lexbor/html/parser.c @@ -202,7 +202,7 @@ lxb_html_parse_fragment_chunk_begin(lxb_html_parser_t *parser, } lxb_html_tokenizer_set_state_by_tag(parser->tkz, doc->scripting, tag_id, ns); - lxb_html_tokenizer_tmp_tag_id_set(parser->tkz, LXB_TAG__UNDEF); + lxb_html_tokenizer_tmp_tag_id_set(parser->tkz, LXB_TAG__UNDEF); parser->root = lxb_html_interface_create(new_doc, LXB_TAG_HTML, LXB_NS_HTML); if (parser->root == NULL) { diff --git a/ext/dom/lexbor/lexbor/tag/tag.c b/ext/dom/lexbor/lexbor/tag/tag.c index 05719570126d4..be5bb30dbb09e 100644 --- a/ext/dom/lexbor/lexbor/tag/tag.c +++ b/ext/dom/lexbor/lexbor/tag/tag.c @@ -60,7 +60,7 @@ lxb_tag_append_lower(lexbor_hash_t *hash, const lxb_char_t *name, size_t length) } const lxb_tag_data_t * -lxb_tag_data_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id) +lxb_tag_data_by_id(lxb_tag_id_t tag_id) { if (tag_id >= LXB_TAG__LAST_ENTRY) { if (tag_id == LXB_TAG__LAST_ENTRY) { @@ -121,16 +121,15 @@ lxb_tag_data_by_name_upper(lexbor_hash_t *hash, * No inline functions for ABI. */ const lxb_char_t * -lxb_tag_name_by_id_noi(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_by_id_noi(lxb_tag_id_t tag_id, size_t *len) { - return lxb_tag_name_by_id(hash, tag_id, len); + return lxb_tag_name_by_id(tag_id, len); } const lxb_char_t * -lxb_tag_name_upper_by_id_noi(lexbor_hash_t *hash, - lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_upper_by_id_noi(lxb_tag_id_t tag_id, size_t *len) { - return lxb_tag_name_upper_by_id(hash, tag_id, len); + return lxb_tag_name_upper_by_id(tag_id, len); } lxb_tag_id_t diff --git a/ext/dom/lexbor/lexbor/tag/tag.h b/ext/dom/lexbor/lexbor/tag/tag.h index 9e64a2fd242d9..33a515d20364d 100644 --- a/ext/dom/lexbor/lexbor/tag/tag.h +++ b/ext/dom/lexbor/lexbor/tag/tag.h @@ -29,7 +29,7 @@ lxb_tag_data_t; LXB_API const lxb_tag_data_t * -lxb_tag_data_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id); +lxb_tag_data_by_id(lxb_tag_id_t tag_id); LXB_API const lxb_tag_data_t * lxb_tag_data_by_name(lexbor_hash_t *hash, const lxb_char_t *name, size_t len); @@ -42,9 +42,9 @@ lxb_tag_data_by_name_upper(lexbor_hash_t *hash, * Inline functions */ lxb_inline const lxb_char_t * -lxb_tag_name_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_by_id(lxb_tag_id_t tag_id, size_t *len) { - const lxb_tag_data_t *data = lxb_tag_data_by_id(hash, tag_id); + const lxb_tag_data_t *data = lxb_tag_data_by_id(tag_id); if (data == NULL) { if (len != NULL) { *len = 0; @@ -61,9 +61,9 @@ lxb_tag_name_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) } lxb_inline const lxb_char_t * -lxb_tag_name_upper_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_upper_by_id(lxb_tag_id_t tag_id, size_t *len) { - const lxb_tag_data_t *data = lxb_tag_data_by_id(hash, tag_id); + const lxb_tag_data_t *data = lxb_tag_data_by_id(tag_id); if (data == NULL) { if (len != NULL) { *len = 0; @@ -101,12 +101,10 @@ lxb_tag_mraw(lexbor_hash_t *hash) * No inline functions for ABI. */ LXB_API const lxb_char_t * -lxb_tag_name_by_id_noi(lexbor_hash_t *hash, lxb_tag_id_t tag_id, - size_t *len); +lxb_tag_name_by_id_noi(lxb_tag_id_t tag_id, size_t *len); LXB_API const lxb_char_t * -lxb_tag_name_upper_by_id_noi(lexbor_hash_t *hash, - lxb_tag_id_t tag_id, size_t *len); +lxb_tag_name_upper_by_id_noi(lxb_tag_id_t tag_id, size_t *len); LXB_API lxb_tag_id_t lxb_tag_id_by_name_noi(lexbor_hash_t *hash, From 690ce6d5d4c9afb78d214160c764da005fa6f33a Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 24 Aug 2024 17:07:19 +0200 Subject: [PATCH 186/280] Fix GH-15570: Segmentation fault (access null pointer) in ext/dom/html5_serializer.c Closes GH-15572. --- NEWS | 2 ++ ext/dom/html5_serializer.c | 4 ++-- ext/dom/tests/gh15570.phpt | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 ext/dom/tests/gh15570.phpt diff --git a/NEWS b/NEWS index 0eb5cc1f5dc42..6c8374371214c 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,8 @@ PHP NEWS - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h). (nielsdos) + . Fixed bug GH-15570 (Segmentation fault (access null pointer) in + ext/dom/html5_serializer.c). (nielsdos) - FPM: . Added memory peak to the scoreboard / status page. (Flávio Heleno) diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c index 3970fb059c1c5..f0048aa4aae89 100644 --- a/ext/dom/html5_serializer.c +++ b/ext/dom/html5_serializer.c @@ -137,8 +137,8 @@ static zend_result dom_html5_serialize_text_node(dom_html5_serialize_context *ct return SUCCESS; } - if (node->parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(node->parent, php_dom_ns_is_html_magic_token)) { - const xmlNode *parent = node->parent; + const xmlNode *parent = node->parent; + if (parent != NULL && parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(parent, php_dom_ns_is_html_magic_token)) { size_t name_length = strlen((const char *) parent->name); /* Spec tells us to only emit noscript content as-is if scripting is enabled. * However, the user agent (PHP) does not support (JS) scripting. diff --git a/ext/dom/tests/gh15570.phpt b/ext/dom/tests/gh15570.phpt new file mode 100644 index 0000000000000..f2337cca2259d --- /dev/null +++ b/ext/dom/tests/gh15570.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-15570 (Segmentation fault (access null pointer) in ext/dom/html5_serializer.c) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +dom +--FILE-- + + +HTML; +$dom = Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR); +$a = $dom->head->firstChild->cloneNode(false); +var_dump($dom->saveHTML($a)); +?> +--EXPECT-- +string(1) " +" From f88e32d4b5797024954258c0caa5058f5b929159 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 25 Aug 2024 17:25:54 +0200 Subject: [PATCH 187/280] Autotools: Simplify adding tidy cflags (#15577) --- ext/tidy/config.m4 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4 index e179a31d60bfd..164440fb5b2c7 100644 --- a/ext/tidy/config.m4 +++ b/ext/tidy/config.m4 @@ -57,9 +57,12 @@ if test "$PHP_TIDY" != "no"; then [TIDY_SHARED_LIBADD]) PHP_ADD_INCLUDE([$TIDY_INCDIR]) - dnl Add -Wno-ignored-qualifiers as this is an issue upstream - TIDY_COMPILER_FLAGS="$TIDY_CFLAGS -Wno-ignored-qualifiers -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" - PHP_NEW_EXTENSION([tidy], [tidy.c], [$ext_shared],, [$TIDY_COMPILER_FLAGS]) + dnl Add -Wno-ignored-qualifiers as this is an issue upstream. Fixed in + dnl tidy-html5 5.7.20: https://github.com/htacg/tidy-html5/issues/866 + PHP_NEW_EXTENSION([tidy], + [tidy.c], + [$ext_shared],, + [-Wno-ignored-qualifiers -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_SUBST([TIDY_SHARED_LIBADD]) AC_DEFINE([HAVE_TIDY], [1], [Define to 1 if the PHP extension 'tidy' is available.]) From fefa7d8c07a097f0e65ebeb0f044322ba7842332 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 25 Aug 2024 17:26:21 +0200 Subject: [PATCH 188/280] Autotools: Sync CS in ext/phar (#15586) --- ext/phar/config.m4 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index bd5f59d37e952..66b4b318e92ae 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -18,17 +18,16 @@ if test "$PHP_PHAR" != "no"; then ]), [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + AC_MSG_CHECKING([for phar openssl support]) - if test "$PHP_OPENSSL_SHARED" = "yes"; then - AC_MSG_RESULT([no (shared openssl)]) - else - if test "$PHP_OPENSSL" = "yes"; then + AS_VAR_IF([PHP_OPENSSL_SHARED], [yes], + [AC_MSG_RESULT([no (shared openssl)])], + [AS_VAR_IF([PHP_OPENSSL], [yes], [ AC_MSG_RESULT([yes]) - AC_DEFINE(PHAR_HAVE_OPENSSL,1,[ ]) - else - AC_MSG_RESULT([no]) - fi - fi + AC_DEFINE([PHAR_HAVE_OPENSSL], [1], + [Define to 1 if phar extension has native OpenSSL support.]) + ], [AC_MSG_RESULT([no])])]) + PHP_ADD_EXTENSION_DEP(phar, hash) PHP_ADD_EXTENSION_DEP(phar, spl) PHP_ADD_MAKEFILE_FRAGMENT From 5947db6bb8e336252337fb0194c3b8e834d100b6 Mon Sep 17 00:00:00 2001 From: Bernd Kuhls Date: Sun, 25 Aug 2024 18:00:29 +0200 Subject: [PATCH 189/280] Fix GH-15587: Autotools: fix configure check for aarch64 CRC32 API On arm32 bit the check succeeds leading to a build error later on: /home/autobuild/autobuild/instance-3/output-1/build/php-8.3.10/ext/standard/crc32.c:70:12: error: 'armv8-a' does not support feature 'nothing' 70 | # pragma GCC target ("+nothing+crc") Co-authored-by: Thomas Petazzoni [http://lists.busybox.net/pipermail/buildroot/2024-August/761151.html] Signed-off-by: Bernd Kuhls --- NEWS | 2 ++ configure.ac | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 64d4e9d4ddc25..60a17e3cb15be 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ PHP NEWS . Fixed bug GH-15514 (Configure error: genif.sh: syntax error). (Peter Kokot) . Fixed bug GH-15565 (--disable-ipv6 during compilation produces error EAI_SYSTEM not found). (nielsdos) + . Fixed bug GH-15587 (CRC32 API build error on arm 32-bit). + (Bernd Kuhls, Thomas Petazzoni) - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in diff --git a/configure.ac b/configure.ac index 1142c9459d71c..fb59a81700f4b 100644 --- a/configure.ac +++ b/configure.ac @@ -738,11 +738,25 @@ AC_FUNC_ALLOCA PHP_TIME_R_TYPE PHP_CHECK_IN_ADDR_T -AC_CACHE_CHECK([for aarch64 CRC32 API], ac_cv_func___crc32d, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[__crc32d(0, 0);]])],[ac_cv_func___crc32d=yes],[ac_cv_func___crc32d="no"])]) -if test "$ac_cv_func___crc32d" = "yes"; then - AC_DEFINE([HAVE_AARCH64_CRC32], [1], [Define when aarch64 CRC32 API is available.]) -fi +AC_CACHE_CHECK([for aarch64 CRC32 API], [ac_cv_func___crc32d], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([ +#include +# if defined(__GNUC__) +# if!defined(__clang__) +# pragma GCC push_options +# pragma GCC target ("+nothing+crc") +# elif defined(__APPLE__) +# pragma clang attribute push(__attribute__((target("crc"))), apply_to=function) +# else +# pragma clang attribute push(__attribute__((target("+nothing+crc"))), apply_to=function) +# endif +# endif +], [__crc32d(0, 0);])], +[ac_cv_func___crc32d=yes], +[ac_cv_func___crc32d=no])]) +AS_VAR_IF([ac_cv_func___crc32d], [yes], + [AC_DEFINE([HAVE_AARCH64_CRC32], [1], + [Define to 1 when aarch64 CRC32 API is available.])]) dnl Check for asm goto support. AC_CACHE_CHECK([for asm goto], ac_cv__asm_goto, From f61aad8f32720a0b92ffa5c5ba20a4a3d97d0388 Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Mon, 26 Aug 2024 03:35:38 +0700 Subject: [PATCH 190/280] [skip ci] UPGRADING: Note `Phar::setAlias()`/`setDefaultStub()` return type changes (#15566) Follow-up to GH-15426 (6836cae) Co-authored-by: Gina Peter Banyard --- UPGRADING | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UPGRADING b/UPGRADING index 88d022c2421de..4d3a460e6a5c0 100644 --- a/UPGRADING +++ b/UPGRADING @@ -657,6 +657,10 @@ PHP 8.4 UPGRADE NOTES - PGSQL: . pg_select, the conditions arguments accepts an empty array and is optional. +- Phar: + . Phar::setAlias() and Phar::setDefaultStub() methods now have a tentative + return type of true instead of bool. + - POSIX: . posix_isatty now sets the error number when the file descriptor/stream argument is invalid. From 555b603d23ce747f55715994941115ca283b553e Mon Sep 17 00:00:00 2001 From: ^_^ Date: Mon, 26 Aug 2024 11:52:26 +0800 Subject: [PATCH 191/280] mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT (#13618) --- NEWS | 3 +++ UPGRADING | 4 ++++ ext/mysqli/tests/bug81335.phpt | 34 ++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_enum_n_def.h | 1 + ext/mysqlnd/mysqlnd_result.c | 2 +- ext/mysqlnd/mysqlnd_wireprotocol.c | 17 ++++++++++++++- 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 ext/mysqli/tests/bug81335.phpt diff --git a/NEWS b/NEWS index 6c8374371214c..19a6e7045c7b6 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,9 @@ PHP NEWS . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) +- PDO_MYSQL: + . mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla) + - Session: . Emit warnings for non-positive values of session.gc_divisor and negative values of session.gc_probability. (Jorg Sowa) diff --git a/UPGRADING b/UPGRADING index 4d3a460e6a5c0..283b82f75ccc5 100644 --- a/UPGRADING +++ b/UPGRADING @@ -126,6 +126,10 @@ PHP 8.4 UPGRADE NOTES has changed. Consult https://github.com/PCRE2Project/pcre2/blob/master/NEWS for a full changelog. +- MySQLnd + . The error code reported for MySQL server wait timeouts has been changed from 2006 + to 4031 for MySQL server versions 8.0.24 and above. + - PCNTL: . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and pcntl_sigtimedwait() now throw: diff --git a/ext/mysqli/tests/bug81335.phpt b/ext/mysqli/tests/bug81335.phpt new file mode 100644 index 0000000000000..26f6bcd7e2d14 --- /dev/null +++ b/ext/mysqli/tests/bug81335.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #81335: Packets out of order after connection timeout +--EXTENSIONS-- +mysqli +--SKIPIF-- += 8.0.24"); +} +?> +--FILE-- +query('SET WAIT_TIMEOUT=1'); +usleep(1000000 * 1.1); +try { + $mysqli->query('SELECT 1 + 1'); +} catch(mysqli_sql_exception $e) { + echo $e->getMessage(); + echo "\n"; + echo $e->getCode(); +} +?> +--EXPECTF-- +The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. +4031 diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index b54ea45bcb924..851174032c404 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -130,6 +130,7 @@ #define CR_INVALID_PARAMETER_NO 2034 #define CR_INVALID_BUFFER_USE 2035 #define CR_LOAD_DATA_LOCAL_INFILE_REJECTED 2068 +#define CR_CLIENT_INTERACTION_TIMEOUT 4031 #define MYSQLND_EE_FILENOTFOUND 7890 diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 7f781d9e5cca7..ae8dc77b4cd9a 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -183,7 +183,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s) UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); if (FAIL == (ret = PACKET_READ(conn, &rset_header))) { - if (conn->error_info->error_no != CR_SERVER_GONE_ERROR) { + if (conn->error_info->error_no != CR_SERVER_GONE_ERROR && conn->error_info->error_no != CR_CLIENT_INTERACTION_TIMEOUT) { php_error_docref(NULL, E_WARNING, "Error reading result set's header"); } break; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 3b46fb2c985be..b1f38f01b2180 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -267,6 +267,19 @@ mysqlnd_read_header(MYSQLND_PFC * pfc, MYSQLND_VIO * vio, MYSQLND_PACKET_HEADER pfc->data->packet_no++; DBG_RETURN(PASS); } + // @see https://dev.mysql.com/worklog/task/?id=12999 + if (header->size > 0) { + zend_uchar *buf = mnd_emalloc(header->size); + if ((PASS == pfc->data->m.receive(pfc, vio, buf, header->size, conn_stats, error_info)) && buf[0] == ERROR_MARKER) { + php_mysqlnd_read_error_from_line(buf + 1, header->size - 1, + error_info->error, sizeof(error_info->error), + &error_info->error_no, error_info->sqlstate + ); + mnd_efree(buf); + DBG_RETURN(FAIL); + } + mnd_efree(buf); + } DBG_ERR_FMT("Logical link: packets out of order. Expected %u received %u. Packet size=%zu", pfc->data->packet_no, header->packet_no, header->size); @@ -294,7 +307,9 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, DBG_INF_FMT("buf=%p size=%zu", buf, buf_size); if (FAIL == mysqlnd_read_header(pfc, vio, packet_header, stats, error_info)) { SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT); - SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); + if (error_info->error_no == 0) { + SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); + } DBG_ERR_FMT("Can't read %s's header", packet_type_as_text); DBG_RETURN(FAIL); } From a3b7cc2217889042180d7f3e865b1e3d12c547b8 Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Mon, 26 Aug 2024 19:33:16 +0700 Subject: [PATCH 192/280] ext/curl: Add `CURLOPT_PREREQFUNCTION` (#13255) Curl >= 7.80.0 supports declaring a function for `CURLOPT_PREREQFUNCTION` option that gets called after Curl establishes a connection (including the TLS handshake for HTTPS connections), but before the actual request is made. The callable must return either `CURL_PREREQFUNC_OK` or `CURL_PREREQFUNC_ABORT` to allow or abort the request. This adds support for it to PHP with required ifdef. - libc: https://curl.se/libcurl/c/CURLOPT_PREREQFUNCTION.html Co-authored-by: Gina Peter Bnayard --- ext/curl/curl.stub.php | 15 ++ ext/curl/curl_arginfo.h | 11 +- ext/curl/curl_private.h | 3 + ext/curl/interface.c | 79 +++++++- ext/curl/sync-constants.php | 1 + .../curl_setopt_CURLOPT_PREREQFUNCTION.phpt | 182 ++++++++++++++++++ 6 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index 473e8b6297e98..c7eba7394843c 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -3497,6 +3497,21 @@ * @cvalue CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 */ const CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = UNKNOWN; +/** + * @var int + * @cvalue CURLOPT_PREREQFUNCTION + */ +const CURLOPT_PREREQFUNCTION = UNKNOWN; +/** + * @var int + * @cvalue CURL_PREREQFUNC_OK + */ +const CURL_PREREQFUNC_OK = UNKNOWN; +/** + * @var int + * @cvalue CURL_PREREQFUNC_ABORT + */ +const CURL_PREREQFUNC_ABORT = UNKNOWN; #endif #if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */ diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index c1cedaa6acb36..f3f13ae3b4ca0 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: ddfcdd8a0bf0ee6c338ec1689c6de5d7fd87303d */ + * Stub hash: 3a5bd4e561f08f0dbd26383132a771acc8192fff */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -1061,6 +1061,15 @@ static void register_curl_symbols(int module_number) #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ REGISTER_LONG_CONSTANT("CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CONST_PERSISTENT); #endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURLOPT_PREREQFUNCTION", CURLOPT_PREREQFUNCTION, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURL_PREREQFUNC_OK", CURL_PREREQFUNC_OK, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURL_PREREQFUNC_ABORT", CURL_PREREQFUNC_ABORT, CONST_PERSISTENT); +#endif #if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */ REGISTER_LONG_CONSTANT("CURLOPT_MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CONST_PERSISTENT); #endif diff --git a/ext/curl/curl_private.h b/ext/curl/curl_private.h index c15396f255b17..011c4874e6140 100644 --- a/ext/curl/curl_private.h +++ b/ext/curl/curl_private.h @@ -68,6 +68,9 @@ typedef struct { zend_fcall_info_cache progress; zend_fcall_info_cache xferinfo; zend_fcall_info_cache fnmatch; +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + zend_fcall_info_cache prereq; +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ zend_fcall_info_cache sshhostkey; #endif diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 8ec2ec33520ec..4697f468098d6 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -504,6 +504,11 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n) zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.fnmatch); } +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(curl->handlers.prereq)) { + zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(curl->handlers.sshhostkey)) { zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.sshhostkey); @@ -709,6 +714,60 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, } /* }}} */ +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ +static int curl_prereqfunction(void *clientp, char *conn_primary_ip, char *conn_local_ip, int conn_primary_port, int conn_local_port) +{ + php_curl *ch = (php_curl *)clientp; + int rval = CURL_PREREQFUNC_OK; + + // when CURLOPT_PREREQFUNCTION is set to null, curl_prereqfunction still + // gets called. Return CURL_PREREQFUNC_OK immediately in this case to avoid + // zend_call_known_fcc() with an uninitialized FCC. + if (!ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + return rval; + } + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_prereqfunction() called\n"); + fprintf(stderr, "conn_primary_ip = %s, conn_local_ip = %s, conn_primary_port = %d, conn_local_port = %d\n", conn_primary_ip, conn_local_ip, conn_primary_port, conn_local_port); +#endif + + zval args[5]; + zval retval; + + GC_ADDREF(&ch->std); + ZVAL_OBJ(&args[0], &ch->std); + ZVAL_STRING(&args[1], conn_primary_ip); + ZVAL_STRING(&args[2], conn_local_ip); + ZVAL_LONG(&args[3], conn_primary_port); + ZVAL_LONG(&args[4], conn_local_port); + + ch->in_callback = true; + zend_call_known_fcc(&ch->handlers.prereq, &retval, /* param_count */ 5, args, /* named_params */ NULL); + ch->in_callback = false; + + if (!Z_ISUNDEF(retval)) { + _php_curl_verify_handlers(ch, /* reporterror */ true); + if (Z_TYPE(retval) == IS_LONG) { + zend_long retval_long = Z_LVAL(retval); + if (retval_long == CURL_PREREQFUNC_OK || retval_long == CURL_PREREQFUNC_ABORT) { + rval = retval_long; + } else { + zend_value_error("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT"); + } + } else { + zend_type_error("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT"); + } + } + + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[2]); + + return rval; +} +#endif + #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key, size_t keylen) { @@ -1037,6 +1096,9 @@ void init_curl_handle(php_curl *ch) ch->handlers.progress = empty_fcall_info_cache; ch->handlers.xferinfo = empty_fcall_info_cache; ch->handlers.fnmatch = empty_fcall_info_cache; +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + ch->handlers.prereq = empty_fcall_info_cache; +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ ch->handlers.sshhostkey = empty_fcall_info_cache; #endif @@ -1210,6 +1272,9 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress); php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo); php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch); +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + php_curl_copy_fcc_with_option(ch, CURLOPT_PREREQDATA, &ch->handlers.prereq, &source->handlers.prereq); +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ php_curl_copy_fcc_with_option(ch, CURLOPT_SSH_HOSTKEYDATA, &ch->handlers.sshhostkey, &source->handlers.sshhostkey); #endif @@ -1570,6 +1635,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PROGRESS, handlers.progress, curl_progress); HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_XFERINFO, handlers.xferinfo, curl_xferinfo); HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_FNMATCH_, handlers.fnmatch, curl_fnmatch); +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PREREQ, handlers.prereq, curl_prereqfunction); +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_SSH_HOSTKEY, handlers.sshhostkey, curl_ssh_hostkeyfunction); #endif @@ -2736,6 +2804,11 @@ static void curl_free_obj(zend_object *object) if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) { zend_fcc_dtor(&ch->handlers.fnmatch); } +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + zend_fcc_dtor(&ch->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) { zend_fcc_dtor(&ch->handlers.sshhostkey); @@ -2814,7 +2887,11 @@ static void _php_curl_reset_handlers(php_curl *ch) if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) { zend_fcc_dtor(&ch->handlers.fnmatch); } - +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + zend_fcc_dtor(&ch->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) { zend_fcc_dtor(&ch->handlers.sshhostkey); diff --git a/ext/curl/sync-constants.php b/ext/curl/sync-constants.php index d827de5fc97e3..8f35f7b05fa38 100755 --- a/ext/curl/sync-constants.php +++ b/ext/curl/sync-constants.php @@ -17,6 +17,7 @@ const IGNORED_CURL_CONSTANTS = [ 'CURLOPT_PROGRESSDATA', 'CURLOPT_XFERINFODATA', + 'CURLOPT_PREREQDATA', ]; const IGNORED_PHP_CONSTANTS = [ diff --git a/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt new file mode 100644 index 0000000000000..d11e29f078c09 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt @@ -0,0 +1,182 @@ +--TEST-- +Curl option CURLOPT_PREREQFUNCTION +--EXTENSIONS-- +curl +filter +--SKIPIF-- += 7.80.0"); +?> +--FILE-- +getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid type\n"; +curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) { + return 'this should be an integer'; +}); +try { + curl_exec($ch); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid value\n"; +curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) { + return 42; +}); +try { + curl_exec($ch); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid option value\n"; +try { + curl_setopt($ch, CURLOPT_PREREQFUNCTION, 42); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid option callback\n"; +try { + curl_setopt($ch, CURLOPT_PREREQFUNCTION, 'function_does_not_exist'); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with null as the callback\n"; +var_dump(curl_setopt($ch, CURLOPT_PREREQFUNCTION, null)); +var_dump(curl_exec($ch)); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); + +echo "\nDone"; +?> +--EXPECT-- +int(20312) +int(0) +int(1) + +Testing with CURL_PREREQFUNC_ABORT +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +string(41) "operation aborted by pre-request callback" +int(42) + +Testing with CURL_PREREQFUNC_OK +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +int(0) + +Testing with curl_copy_handle +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +int(0) + +Testing with no return type +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid type +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid value +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid option value +curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, no array or string given + +Testing with invalid option callback +curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, function "function_does_not_exist" not found or invalid function name + +Testing with null as the callback +bool(true) +string(0) "" +string(0) "" +int(0) + +Done From b9b317afd4602cbe67ca861702c65038c32f0d4e Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Mon, 26 Aug 2024 14:54:36 +0200 Subject: [PATCH 193/280] Export opcache shared globals (#15543) --- ext/opcache/zend_shared_alloc.c | 2 +- ext/opcache/zend_shared_alloc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 8db61ed3f3465..c19d72c63b776 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -53,7 +53,7 @@ static const zend_shared_memory_handlers *g_shared_alloc_handler = NULL; static const char *g_shared_model; /* pointer to globals allocated in SHM and shared across processes */ -zend_smm_shared_globals *smm_shared_globals; +ZEND_EXT_API zend_smm_shared_globals *smm_shared_globals; #ifndef ZEND_WIN32 #ifdef ZTS diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 1283351f2e149..41cba0bb35199 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -119,7 +119,7 @@ typedef struct _zend_smm_shared_globals { size_t reserved_size; } zend_smm_shared_globals; -extern zend_smm_shared_globals *smm_shared_globals; +ZEND_EXT_API extern zend_smm_shared_globals *smm_shared_globals; #define ZSMMG(element) (smm_shared_globals->element) From b839c5f1af68f366fbb66651e0b4821d76eb3fcb Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 26 Aug 2024 17:22:04 +0200 Subject: [PATCH 194/280] Fix building of callgraph including preloaded symbols (GH-15545) This issue was introduced in GH-15021. When building the call graph, we can now see preloaded functions. However, building the call graph involves adding the function to the caller list of the callee, which we don't want to do for functions not coming from the script. Fixes GH-15490 --- NEWS | 4 ++++ Zend/Optimizer/zend_call_graph.c | 3 ++- ext/opcache/tests/jit/gh15490.inc | 9 +++++++++ ext/opcache/tests/jit/gh15490.phpt | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/gh15490.inc create mode 100644 ext/opcache/tests/jit/gh15490.phpt diff --git a/NEWS b/NEWS index 19a6e7045c7b6..df968d86ccb45 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,10 @@ PHP NEWS . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) +- Opcache: + . Fixed bug GH-15490 (Building of callgraph modifies preloaded symbols). + (ilutov) + - PDO_MYSQL: . mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla) diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index abd5dac533137..8a2f8ea2a7e1a 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -79,7 +79,8 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 if (build_flags & ZEND_CALL_TREE) { call_info->next_caller = NULL; - } else if (func->type == ZEND_INTERNAL_FUNCTION) { + } else if (func->type == ZEND_INTERNAL_FUNCTION + || func->op_array.filename != script->filename) { call_info->next_caller = NULL; } else { zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array); diff --git a/ext/opcache/tests/jit/gh15490.inc b/ext/opcache/tests/jit/gh15490.inc new file mode 100644 index 0000000000000..e702a9e244028 --- /dev/null +++ b/ext/opcache/tests/jit/gh15490.inc @@ -0,0 +1,9 @@ + +--FILE-- + +--EXPECT-- +Hello world! From 606eb849bb11eae1fa35712ca80ad42b773ebf4a Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 26 Aug 2024 17:26:18 +0200 Subject: [PATCH 195/280] Stop recording of trace when encountering hook Fixes GH-15178 --- NEWS | 1 + ext/opcache/jit/zend_jit_internal.h | 1 + ext/opcache/jit/zend_jit_vm_helpers.c | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/NEWS b/NEWS index df968d86ccb45..0322b9b452dc3 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,7 @@ PHP NEWS - Opcache: . Fixed bug GH-15490 (Building of callgraph modifies preloaded symbols). (ilutov) + . Fixed bug GH-15178 (Assertion in tracing JIT on hooks). (ilutov) - PDO_MYSQL: . mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla) diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index ccc86a4834cf5..2007f28e91fd2 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -265,6 +265,7 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key); _(INNER_LOOP, "inner loop") /* trace it */ \ _(COMPILED_LOOP, "compiled loop") \ _(TRAMPOLINE, "trampoline call") \ + _(PROP_HOOK_CALL, "property hook call") \ _(BAD_FUNC, "bad function call") \ _(COMPILER_ERROR, "JIT compilation error") \ /* no recoverable error (blacklist immediately) */ \ diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 2a7399c185d5f..e9cdeeab9865a 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -503,6 +503,11 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend /* TODO: Can we continue recording ??? */ return -1; } + /* Function is a property hook. */ + if (func->common.prop_info) { + /* TODO: Can we continue recording ??? */ + return -1; + } if (func->type == ZEND_INTERNAL_FUNCTION && (func->op_array.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) { return -1; @@ -966,6 +971,12 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, break; } + if (EX(func)->op_array.prop_info) { + /* TODO: Can we continue recording ??? */ + stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL; + break; + } + TRACE_RECORD(ZEND_JIT_TRACE_ENTER, EX(return_value) != NULL ? ZEND_JIT_TRACE_RETURN_VALUE_USED : 0, op_array); @@ -1069,6 +1080,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, /* TODO: Can we continue recording ??? */ stop = ZEND_JIT_TRACE_STOP_BAD_FUNC; break; + } else if (EX(call)->func->common.prop_info) { + /* TODO: Can we continue recording ??? */ + stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL; + break; } func = EX(call)->func; if (func->type == ZEND_INTERNAL_FUNCTION From f78d5cfcd2fe06ddd6da33ff880c6823072adc1b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 27 Jul 2024 15:45:16 +0200 Subject: [PATCH 196/280] Allow ZEND_ACC_VIRTUAL to be used to not have property backing storage without resorting to hooks This is useful to reduce the memory usage of objects that don't actually use the backing storage. Examples are XMLReader and DOM. When the properties were added to the stubs, these objects became much much bigger, which is a waste of memory. Closes GH-11644. Work towards GH-13988. --- build/gen_stub.php | 11 +++++++++++ ext/reflection/php_reflection.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 2b6af02e190f2..27e52cec55188 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -2916,6 +2916,7 @@ class PropertyInfo extends VariableLike public ?Expr $defaultValue; public ?string $defaultValueString; public bool $isDocReadonly; + public bool $isVirtual; /** * @var AttributeInfo[] $attributes @@ -2929,6 +2930,7 @@ public function __construct( ?Expr $defaultValue, ?string $defaultValueString, bool $isDocReadonly, + bool $isVirtual, ?string $link, ?int $phpVersionIdMinimumCompatibility, array $attributes, @@ -2939,6 +2941,7 @@ public function __construct( $this->defaultValue = $defaultValue; $this->defaultValueString = $defaultValueString; $this->isDocReadonly = $isDocReadonly; + $this->isVirtual = $isVirtual; parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment); } @@ -3054,6 +3057,10 @@ protected function getFlagsByPhpVersion(): array $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_82_VERSION_ID); } + if ($this->isVirtual) { + $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID); + } + return $flags; } @@ -4454,6 +4461,7 @@ function parseProperty( ): PropertyInfo { $phpDocType = null; $isDocReadonly = false; + $isVirtual = false; $link = null; if ($comments) { @@ -4465,6 +4473,8 @@ function parseProperty( $isDocReadonly = true; } elseif ($tag->name === 'link') { $link = $tag->value; + } elseif ($tag->name === 'virtual') { + $isVirtual = true; } } } @@ -4493,6 +4503,7 @@ function parseProperty( $property->default, $property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null, $isDocReadonly, + $isVirtual, $link, $phpVersionIdMinimumCompatibility, $attributes, diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 0956bbc1acf70..1d26c80f222bf 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6041,7 +6041,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) } /* Get-only virtual property can never be written to. */ - if ((prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); reflection_type_factory(never_type, return_value, 0); return; From 6c63c48a7eaa83bc41d8c3895f52b40e9259cc03 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 27 Jul 2024 15:50:00 +0200 Subject: [PATCH 197/280] Use virtual annotation in XMLReader All properties of XMLReader are virtual and therefore don't need backing storage. --- ext/xmlreader/php_xmlreader.stub.php | 14 +++++++++ ext/xmlreader/php_xmlreader_arginfo.h | 30 +++++++++--------- ext/xmlreader/tests/virtual_properties.phpt | 34 +++++++++++++++++++++ 3 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 ext/xmlreader/tests/virtual_properties.phpt diff --git a/ext/xmlreader/php_xmlreader.stub.php b/ext/xmlreader/php_xmlreader.stub.php index c58ee2460ff02..d319037066046 100644 --- a/ext/xmlreader/php_xmlreader.stub.php +++ b/ext/xmlreader/php_xmlreader.stub.php @@ -99,32 +99,46 @@ class XMLReader public const int SUBST_ENTITIES = UNKNOWN; + /** @virtual */ public int $attributeCount; + /** @virtual */ public string $baseURI; + /** @virtual */ public int $depth; + /** @virtual */ public bool $hasAttributes; + /** @virtual */ public bool $hasValue; + /** @virtual */ public bool $isDefault; + /** @virtual */ public bool $isEmptyElement; + /** @virtual */ public string $localName; + /** @virtual */ public string $name; + /** @virtual */ public string $namespaceURI; + /** @virtual */ public int $nodeType; + /** @virtual */ public string $prefix; + /** @virtual */ public string $value; + /** @virtual */ public string $xmlLang; /** @tentative-return-type */ diff --git a/ext/xmlreader/php_xmlreader_arginfo.h b/ext/xmlreader/php_xmlreader_arginfo.h index 4e2a431a55c29..78e7c2dda44c2 100644 --- a/ext/xmlreader/php_xmlreader_arginfo.h +++ b/ext/xmlreader/php_xmlreader_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 551324d130f9755c4c61cebb5084953fb6f539c4 */ + * Stub hash: 80288a0f40eabc7802a928963386616ea31e448d */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_XMLReader_close, 0, 0, IS_TRUE, 0) ZEND_END_ARG_INFO() @@ -313,85 +313,85 @@ static zend_class_entry *register_class_XMLReader(void) zval property_attributeCount_default_value; ZVAL_UNDEF(&property_attributeCount_default_value); zend_string *property_attributeCount_name = zend_string_init("attributeCount", sizeof("attributeCount") - 1, 1); - zend_declare_typed_property(class_entry, property_attributeCount_name, &property_attributeCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_attributeCount_name, &property_attributeCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_attributeCount_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_baseURI_name); zval property_depth_default_value; ZVAL_UNDEF(&property_depth_default_value); zend_string *property_depth_name = zend_string_init("depth", sizeof("depth") - 1, 1); - zend_declare_typed_property(class_entry, property_depth_name, &property_depth_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_depth_name, &property_depth_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_depth_name); zval property_hasAttributes_default_value; ZVAL_UNDEF(&property_hasAttributes_default_value); zend_string *property_hasAttributes_name = zend_string_init("hasAttributes", sizeof("hasAttributes") - 1, 1); - zend_declare_typed_property(class_entry, property_hasAttributes_name, &property_hasAttributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_hasAttributes_name, &property_hasAttributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_hasAttributes_name); zval property_hasValue_default_value; ZVAL_UNDEF(&property_hasValue_default_value); zend_string *property_hasValue_name = zend_string_init("hasValue", sizeof("hasValue") - 1, 1); - zend_declare_typed_property(class_entry, property_hasValue_name, &property_hasValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_hasValue_name, &property_hasValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_hasValue_name); zval property_isDefault_default_value; ZVAL_UNDEF(&property_isDefault_default_value); zend_string *property_isDefault_name = zend_string_init("isDefault", sizeof("isDefault") - 1, 1); - zend_declare_typed_property(class_entry, property_isDefault_name, &property_isDefault_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isDefault_name, &property_isDefault_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isDefault_name); zval property_isEmptyElement_default_value; ZVAL_UNDEF(&property_isEmptyElement_default_value); zend_string *property_isEmptyElement_name = zend_string_init("isEmptyElement", sizeof("isEmptyElement") - 1, 1); - zend_declare_typed_property(class_entry, property_isEmptyElement_name, &property_isEmptyElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isEmptyElement_name, &property_isEmptyElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isEmptyElement_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_namespaceURI_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_xmlLang_default_value; ZVAL_UNDEF(&property_xmlLang_default_value); zend_string *property_xmlLang_name = zend_string_init("xmlLang", sizeof("xmlLang") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlLang_name, &property_xmlLang_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlLang_name, &property_xmlLang_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlLang_name); return class_entry; diff --git a/ext/xmlreader/tests/virtual_properties.phpt b/ext/xmlreader/tests/virtual_properties.phpt new file mode 100644 index 0000000000000..57499292b8ce0 --- /dev/null +++ b/ext/xmlreader/tests/virtual_properties.phpt @@ -0,0 +1,34 @@ +--TEST-- +Virtual property tests +--EXTENSIONS-- +xmlreader +--FILE-- +getProperty("nodeType"); +var_dump($prop->isVirtual()); +var_dump($prop->getSettableType()); +var_dump($prop->getHooks()); +var_dump($prop->getRawValue(new XMLReader)); +var_dump($prop->getValue(new XMLReader)); + +$reader = XMLReader::XML("hi"); +var_dump(json_encode($reader)); +var_export($reader); echo "\n"; +var_dump(get_object_vars($reader)); + +?> +--EXPECTF-- +bool(true) +object(ReflectionNamedType)#%d (0) { +} +array(0) { +} +int(0) +int(0) +string(2) "{}" +\XMLReader::__set_state(array( +)) +array(0) { +} From baac01f5945664d59567811bda235a20a23d7ed8 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:53:23 +0200 Subject: [PATCH 198/280] Improve virtual property error message Co-authored-by: Ilija Tovilo --- Zend/tests/property_hooks/unserialize.phpt | 2 +- ext/standard/var_unserializer.re | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/tests/property_hooks/unserialize.phpt b/Zend/tests/property_hooks/unserialize.phpt index 2461817a08814..b8834e1d39ff4 100644 --- a/Zend/tests/property_hooks/unserialize.phpt +++ b/Zend/tests/property_hooks/unserialize.phpt @@ -54,7 +54,7 @@ object(Test)#2 (1) { Test::$prop3::get Test::$prop3::set -Warning: unserialize(): Cannot unserialize value for hooked property Test::$prop3 in %s on line %d +Warning: unserialize(): Cannot unserialize value for virtual property Test::$prop3 in %s on line %d Warning: unserialize(): Error at offset 26 of 32 bytes in %s on line %d bool(false) diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 78d102eefda6c..cbd457e16fdb1 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -561,7 +561,7 @@ static int is_property_visibility_changed(zend_class_entry *ce, zval *key) return 1; } else { php_error_docref(NULL, E_WARNING, - "Cannot unserialize value for hooked property %s::$%s", + "Cannot unserialize value for virtual property %s::$%s", ZSTR_VAL(existing_propinfo->ce->name), Z_STRVAL_P(key)); zval_ptr_dtor_str(key); return -1; From fef55bc8e4f2bb7ef4101a6e359d2c15a299e35e Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 27 Aug 2024 00:00:20 +0200 Subject: [PATCH 199/280] Autotools: Fix tidy library checks (#15576) When configuring with tidy library installed in non-standard paths, the library adding macro must be done before the PHP_CHECK_LIBRARY to be able to detect it. This fixes these edge cases. For example: ./configure --with-tidy=/path/to/custom-tidy-installation --- ext/tidy/config.m4 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4 index 164440fb5b2c7..8c3ceb38dafd7 100644 --- a/ext/tidy/config.m4 +++ b/ext/tidy/config.m4 @@ -46,11 +46,16 @@ if test "$PHP_TIDY" != "no"; then [Define to 1 if Tidy library has the 'tidyOptGetDoc' function.])], [PHP_CHECK_LIBRARY([tidy5], [tidyOptGetDoc], [TIDY_LIB_NAME=tidy5 - AC_DEFINE([HAVE_TIDYOPTGETDOC], [1])])]) + AC_DEFINE([HAVE_TIDYOPTGETDOC], [1])], + [], + [-L$TIDY_LIBDIR])], + [-L$TIDY_LIBDIR]) PHP_CHECK_LIBRARY([$TIDY_LIB_NAME], [tidyReleaseDate], [AC_DEFINE([HAVE_TIDYRELEASEDATE], [1], - [Define to 1 if Tidy library has the 'tidyReleaseDate' function.])]) + [Define to 1 if Tidy library has the 'tidyReleaseDate' function.])], + [], + [-L$TIDY_LIBDIR]) PHP_ADD_LIBRARY_WITH_PATH([$TIDY_LIB_NAME], [$TIDY_LIBDIR], From 8df557ac42c8227d8e7573f6a3a8d799ef28e7cd Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 27 Aug 2024 02:04:48 +0200 Subject: [PATCH 200/280] [RFC] Asymmetric visibility v2 (GH-15063) Co-authored-by: Larry Garfield --- NEWS | 1 + Zend/tests/asymmetric_visibility/__set.phpt | 43 +++++ Zend/tests/asymmetric_visibility/__unset.phpt | 47 +++++ .../asymmetric_visibility/ast_printing.phpt | 28 +++ Zend/tests/asymmetric_visibility/bug001.phpt | 33 ++++ Zend/tests/asymmetric_visibility/bug002.phpt | 33 ++++ Zend/tests/asymmetric_visibility/bug003.phpt | 28 +++ Zend/tests/asymmetric_visibility/bug004.phpt | 18 ++ .../asymmetric_visibility/cpp_no_type.phpt | 14 ++ .../asymmetric_visibility/cpp_private.phpt | 32 ++++ .../asymmetric_visibility/cpp_protected.phpt | 42 +++++ .../cpp_wider_set_scope.phpt | 14 ++ .../decrease_scope_private_private.phpt | 13 ++ .../decrease_scope_private_protected.phpt | 12 ++ .../decrease_scope_protected_protected.phpt | 13 ++ Zend/tests/asymmetric_visibility/dim_add.phpt | 34 ++++ .../duplicate_modifier.phpt | 12 ++ .../duplicate_modifier_2.phpt | 12 ++ .../asymmetric_visibility/nested_write.phpt | 24 +++ Zend/tests/asymmetric_visibility/no_type.phpt | 12 ++ .../object_reference.phpt | 37 ++++ .../override_private_public.phpt | 16 ++ .../override_protected_private.phpt | 16 ++ .../override_protected_public.phpt | 20 ++ .../override_public_private.phpt | 16 ++ .../override_public_protected.phpt | 16 ++ Zend/tests/asymmetric_visibility/private.phpt | 61 ++++++ .../asymmetric_visibility/protected.phpt | 66 +++++++ .../tests/asymmetric_visibility/readonly.phpt | 62 ++++++ .../asymmetric_visibility/reference.phpt | 32 ++++ .../asymmetric_visibility/reference_2.phpt | 30 +++ .../scope_rebinding.phpt | 36 ++++ Zend/tests/asymmetric_visibility/unset.phpt | 67 +++++++ .../unshared_rw_cache_slot.phpt | 37 ++++ .../asymmetric_visibility/variation.phpt | 134 +++++++++++++ .../variation_nested.phpt | 84 +++++++++ .../abstract_get_set_readonly.phpt | 13 ++ .../interface_get_set_readonly.phpt | 4 +- .../readonly_props/initialization_scope.phpt | 29 +-- Zend/tests/readonly_props/magic_get_set.phpt | 4 +- .../public_set_non_readonly.phpt | 13 ++ Zend/tests/readonly_props/unset.phpt | 2 +- Zend/tests/readonly_props/variation.phpt | 22 ++- .../readonly_props/variation_nested.phpt | 9 +- Zend/zend_API.c | 27 +++ Zend/zend_ast.c | 20 +- Zend/zend_compile.c | 32 +++- Zend/zend_compile.h | 23 ++- Zend/zend_execute.c | 47 ++++- Zend/zend_execute.h | 3 + Zend/zend_inheritance.c | 31 +++ Zend/zend_language_parser.y | 6 + Zend/zend_language_scanner.l | 12 ++ Zend/zend_object_handlers.c | 177 +++++++++--------- Zend/zend_object_handlers.h | 2 + ext/opcache/jit/zend_jit_helpers.c | 34 ++-- ext/opcache/jit/zend_jit_ir.c | 69 +++++-- ext/reflection/php_reflection.c | 23 ++- ext/reflection/php_reflection.stub.php | 8 + ext/reflection/php_reflection_arginfo.h | 22 ++- .../tests/ReflectionClass_toString_005.phpt | 4 +- .../tests/ReflectionEnumUnitCase_getEnum.phpt | 2 +- .../tests/ReflectionEnum_toString.phpt | 2 +- .../tests/asymmetric_visibility_flags.phpt | 34 ++++ .../tests/asymmetric_visibility_write.phpt | 25 +++ ext/reflection/tests/readonly_properties.phpt | 2 +- .../directory/DirectoryClass_basic_001.phpt | 4 +- ext/tokenizer/tokenizer_data.c | 3 + ext/tokenizer/tokenizer_data.stub.php | 15 ++ ext/tokenizer/tokenizer_data_arginfo.h | 5 +- 70 files changed, 1768 insertions(+), 155 deletions(-) create mode 100644 Zend/tests/asymmetric_visibility/__set.phpt create mode 100644 Zend/tests/asymmetric_visibility/__unset.phpt create mode 100644 Zend/tests/asymmetric_visibility/ast_printing.phpt create mode 100644 Zend/tests/asymmetric_visibility/bug001.phpt create mode 100644 Zend/tests/asymmetric_visibility/bug002.phpt create mode 100644 Zend/tests/asymmetric_visibility/bug003.phpt create mode 100644 Zend/tests/asymmetric_visibility/bug004.phpt create mode 100644 Zend/tests/asymmetric_visibility/cpp_no_type.phpt create mode 100644 Zend/tests/asymmetric_visibility/cpp_private.phpt create mode 100644 Zend/tests/asymmetric_visibility/cpp_protected.phpt create mode 100644 Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt create mode 100644 Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt create mode 100644 Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt create mode 100644 Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt create mode 100644 Zend/tests/asymmetric_visibility/dim_add.phpt create mode 100644 Zend/tests/asymmetric_visibility/duplicate_modifier.phpt create mode 100644 Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt create mode 100644 Zend/tests/asymmetric_visibility/nested_write.phpt create mode 100644 Zend/tests/asymmetric_visibility/no_type.phpt create mode 100644 Zend/tests/asymmetric_visibility/object_reference.phpt create mode 100644 Zend/tests/asymmetric_visibility/override_private_public.phpt create mode 100644 Zend/tests/asymmetric_visibility/override_protected_private.phpt create mode 100644 Zend/tests/asymmetric_visibility/override_protected_public.phpt create mode 100644 Zend/tests/asymmetric_visibility/override_public_private.phpt create mode 100644 Zend/tests/asymmetric_visibility/override_public_protected.phpt create mode 100644 Zend/tests/asymmetric_visibility/private.phpt create mode 100644 Zend/tests/asymmetric_visibility/protected.phpt create mode 100644 Zend/tests/asymmetric_visibility/readonly.phpt create mode 100644 Zend/tests/asymmetric_visibility/reference.phpt create mode 100644 Zend/tests/asymmetric_visibility/reference_2.phpt create mode 100644 Zend/tests/asymmetric_visibility/scope_rebinding.phpt create mode 100644 Zend/tests/asymmetric_visibility/unset.phpt create mode 100644 Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt create mode 100644 Zend/tests/asymmetric_visibility/variation.phpt create mode 100644 Zend/tests/asymmetric_visibility/variation_nested.phpt create mode 100644 Zend/tests/property_hooks/abstract_get_set_readonly.phpt create mode 100644 Zend/tests/readonly_props/public_set_non_readonly.phpt create mode 100644 ext/reflection/tests/asymmetric_visibility_flags.phpt create mode 100644 ext/reflection/tests/asymmetric_visibility_write.phpt diff --git a/NEWS b/NEWS index 0322b9b452dc3..14845065252fd 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ PHP NEWS undefined). (Peter Kokot) . Fixed bug GH-15565 (--disable-ipv6 during compilation produces error EAI_SYSTEM not found). (nielsdos) + . Implemented asymmetric visibility for properties. (ilutov) - Date: . Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end diff --git a/Zend/tests/asymmetric_visibility/__set.phpt b/Zend/tests/asymmetric_visibility/__set.phpt new file mode 100644 index 0000000000000..7476f5304e253 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/__set.phpt @@ -0,0 +1,43 @@ +--TEST-- +Asymmetric visibility __set +--FILE-- +bar = $bar; + } + + public function unsetBar() { + unset($this->bar); + } + + public function __set(string $name, mixed $value) { + echo __CLASS__, '::', __METHOD__, "\n"; + } +} + +$foo = new Foo(); +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->unsetBar(); +$foo->bar = 'baz'; + +?> +--EXPECT-- +Cannot modify private(set) property Foo::$bar from global scope +Cannot modify private(set) property Foo::$bar from global scope +Foo::Foo::__set diff --git a/Zend/tests/asymmetric_visibility/__unset.phpt b/Zend/tests/asymmetric_visibility/__unset.phpt new file mode 100644 index 0000000000000..3d5977d79782b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/__unset.phpt @@ -0,0 +1,47 @@ +--TEST-- +Asymmetric visibility __unset +--FILE-- +bar = $bar; + } + + public function unsetBar() { + unset($this->bar); + } + + public function __unset($name) { + echo __METHOD__, "\n"; + } +} + +function test($foo) { + try { + unset($foo->bar); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +} + +$foo = new Foo(); +test($foo); + +$foo->unsetBar(); +test($foo); + +$foo->setBar('bar'); +test($foo); + +$foo->unsetBar(); +test($foo); + +?> +--EXPECT-- +Cannot unset private(set) property Foo::$bar from global scope +Foo::__unset +Cannot unset private(set) property Foo::$bar from global scope +Foo::__unset diff --git a/Zend/tests/asymmetric_visibility/ast_printing.phpt b/Zend/tests/asymmetric_visibility/ast_printing.phpt new file mode 100644 index 0000000000000..25803e67c09df --- /dev/null +++ b/Zend/tests/asymmetric_visibility/ast_printing.phpt @@ -0,0 +1,28 @@ +--TEST-- +private(set) protected(set) ast printing +--INI-- +zend.assertions=1 +assert.exception=1 +--FILE-- +getMessage(); +} + +?> +--EXPECT-- +assert(function () { + class Foo { + public private(set) string $bar; + public protected(set) string $baz; + } + +} && false) diff --git a/Zend/tests/asymmetric_visibility/bug001.phpt b/Zend/tests/asymmetric_visibility/bug001.phpt new file mode 100644 index 0000000000000..c306434d610b1 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug001.phpt @@ -0,0 +1,33 @@ +--TEST-- +Unset from __unset respects set visibility +--FILE-- +a); + } +} + +class D extends C { + public function __unset($name) { + unset($this->a); + } +} + +$c = new D(); +try { + unset($c->a); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Cannot unset private(set) property C::$a from scope D +object(D)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/asymmetric_visibility/bug002.phpt b/Zend/tests/asymmetric_visibility/bug002.phpt new file mode 100644 index 0000000000000..1f6dc2b852780 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug002.phpt @@ -0,0 +1,33 @@ +--TEST-- +Set from __set respects set visibility +--FILE-- +a); + } +} + +class D extends C { + public function __set($name, $value) { + $this->a = $value; + } +} + +$c = new D(); +try { + $c->a = 2; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Cannot modify private(set) property C::$a from scope D +object(D)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/asymmetric_visibility/bug003.phpt b/Zend/tests/asymmetric_visibility/bug003.phpt new file mode 100644 index 0000000000000..9f541f87f7cdb --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug003.phpt @@ -0,0 +1,28 @@ +--TEST-- +Explicitly unset property with a-vis still respects set visibility +--FILE-- +a); + } +} + +$c = new C(); +try { + $c->a = 2; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + unset($c->a); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot modify private(set) property C::$a from global scope +Cannot unset private(set) property C::$a from global scope diff --git a/Zend/tests/asymmetric_visibility/bug004.phpt b/Zend/tests/asymmetric_visibility/bug004.phpt new file mode 100644 index 0000000000000..f44d69cd21644 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug004.phpt @@ -0,0 +1,18 @@ +--TEST-- +Missing property initialization for private(set) constructor promoted property +--FILE-- + +--EXPECTF-- +object(T)#%d (1) { + ["prop"]=> + string(4) "Test" +} diff --git a/Zend/tests/asymmetric_visibility/cpp_no_type.phpt b/Zend/tests/asymmetric_visibility/cpp_no_type.phpt new file mode 100644 index 0000000000000..b1d169b6e1888 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_no_type.phpt @@ -0,0 +1,14 @@ +--TEST-- +Asymmetric visibility in CPP with no type +--FILE-- + +--EXPECTF-- +Fatal error: Property with asymmetric visibility Foo::$bar must have type in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/cpp_private.phpt b/Zend/tests/asymmetric_visibility/cpp_private.phpt new file mode 100644 index 0000000000000..c308330d3ab01 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_private.phpt @@ -0,0 +1,32 @@ +--TEST-- +Asymmetric visibility private(set) CPP +--FILE-- +bar = $bar; + } +} + +$foo = new Foo('bar'); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +var_dump($foo->bar); + +?> +--EXPECT-- +string(3) "bar" +Cannot modify private(set) property Foo::$bar from global scope +string(3) "baz" diff --git a/Zend/tests/asymmetric_visibility/cpp_protected.phpt b/Zend/tests/asymmetric_visibility/cpp_protected.phpt new file mode 100644 index 0000000000000..f13351e32003b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_protected.phpt @@ -0,0 +1,42 @@ +--TEST-- +Asymmetric visibility protected(set) CPP +--FILE-- +bar = $bar; + } +} + +class FooChild extends Foo { + public function setBarProtected($bar) { + $this->bar = $bar; + } +} + +$foo = new FooChild('bar'); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBarPrivate('baz'); +var_dump($foo->bar); + +$foo->setBarProtected('qux'); +var_dump($foo->bar); + +?> +--EXPECT-- +string(3) "bar" +Cannot modify protected(set) property Foo::$bar from global scope +string(3) "baz" +string(3) "qux" diff --git a/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt b/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt new file mode 100644 index 0000000000000..45fcc96518691 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt @@ -0,0 +1,14 @@ +--TEST-- +Asymmetric visibility private(get) protected(set) in CPP is not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt new file mode 100644 index 0000000000000..affe965b45c47 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt @@ -0,0 +1,13 @@ +--TEST-- +Asymmetric visibility private(get) private(set) is allowed +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt new file mode 100644 index 0000000000000..625f12382cf7e --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt @@ -0,0 +1,12 @@ +--TEST-- +Asymmetric visibility private(get) protected(set) not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt new file mode 100644 index 0000000000000..7d98b61b47420 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt @@ -0,0 +1,13 @@ +--TEST-- +Asymmetric visibility protected(get) protected(set) is allowed +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/asymmetric_visibility/dim_add.phpt b/Zend/tests/asymmetric_visibility/dim_add.phpt new file mode 100644 index 0000000000000..f7bf0ceaf939c --- /dev/null +++ b/Zend/tests/asymmetric_visibility/dim_add.phpt @@ -0,0 +1,34 @@ +--TEST-- +Asymmetric visibility DIM add +--FILE-- +bars[] = $bar; + } +} + +$foo = new Foo(); + +try { + $foo->bars[] = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bars); + +$foo->addBar('baz'); +var_dump($foo->bars); + +?> +--EXPECT-- +Cannot indirectly modify private(set) property Foo::$bars from global scope +array(0) { +} +array(1) { + [0]=> + string(3) "baz" +} diff --git a/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt b/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt new file mode 100644 index 0000000000000..d09eacd18deae --- /dev/null +++ b/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate asymmetric visibility modifier +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt b/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt new file mode 100644 index 0000000000000..832c57b296e67 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate asymmetric visibility modifier +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/nested_write.phpt b/Zend/tests/asymmetric_visibility/nested_write.phpt new file mode 100644 index 0000000000000..8386b6b2503c6 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/nested_write.phpt @@ -0,0 +1,24 @@ +--TEST-- +Asymmetric visibility nested write +--FILE-- +bar = new Bar; + } +} + +class Bar { + public int $baz; +} + +$foo = new Foo(); +$foo->bar->baz = 42; +var_dump($foo->bar->baz); + +?> +--EXPECT-- +int(42) diff --git a/Zend/tests/asymmetric_visibility/no_type.phpt b/Zend/tests/asymmetric_visibility/no_type.phpt new file mode 100644 index 0000000000000..3e48bdbb06feb --- /dev/null +++ b/Zend/tests/asymmetric_visibility/no_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Asymmetric visibility with no type +--FILE-- + +--EXPECTF-- +Fatal error: Property with asymmetric visibility Foo::$bar must have type in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/object_reference.phpt b/Zend/tests/asymmetric_visibility/object_reference.phpt new file mode 100644 index 0000000000000..26cc08386107b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/object_reference.phpt @@ -0,0 +1,37 @@ +--TEST-- +Attempting to obtain reference of object of private(set) object returns a copy instead +--FILE-- +bar = new Bar(); + } +} + +class Bar {} + +function test() { + $foo = new Foo(); + $bar = &$foo->bar; + var_dump($foo); +} + +test(); +// Test zend_fetch_property_address with warmed cache +test(); + +?> +--EXPECT-- +object(Foo)#1 (1) { + ["bar"]=> + object(Bar)#2 (0) { + } +} +object(Foo)#2 (1) { + ["bar"]=> + object(Bar)#1 (0) { + } +} diff --git a/Zend/tests/asymmetric_visibility/override_private_public.phpt b/Zend/tests/asymmetric_visibility/override_private_public.phpt new file mode 100644 index 0000000000000..122c6efbda633 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_private_public.phpt @@ -0,0 +1,16 @@ +--TEST-- +private(set) property is implicitly final +--FILE-- + +--EXPECTF-- +Fatal error: Cannot override final property A::$foo in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_protected_private.phpt b/Zend/tests/asymmetric_visibility/override_protected_private.phpt new file mode 100644 index 0000000000000..958e886dd807f --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_protected_private.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten protected asymmetric property with private asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be protected(set) (as in class A) or weaker in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_protected_public.phpt b/Zend/tests/asymmetric_visibility/override_protected_public.phpt new file mode 100644 index 0000000000000..36890c50b4b5e --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_protected_public.phpt @@ -0,0 +1,20 @@ +--TEST-- +Overwritten protected asymmetric property with public property +--FILE-- +foo = 'foo'; +echo $b->foo, "\n"; + +?> +--EXPECT-- +foo diff --git a/Zend/tests/asymmetric_visibility/override_public_private.phpt b/Zend/tests/asymmetric_visibility/override_public_private.phpt new file mode 100644 index 0000000000000..f1b2191ac16d4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_public_private.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten public property with private asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be omitted (as in class A) in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_public_protected.phpt b/Zend/tests/asymmetric_visibility/override_public_protected.phpt new file mode 100644 index 0000000000000..5611d368b19d4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_public_protected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten public property with protected asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be omitted (as in class A) in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/private.phpt b/Zend/tests/asymmetric_visibility/private.phpt new file mode 100644 index 0000000000000..48e557c6e87d3 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/private.phpt @@ -0,0 +1,61 @@ +--TEST-- +Asymmetric visibility private(set) +--FILE-- +bar = $bar; + } + + public function setBaz($baz) { + $this->baz = $baz; + } +} + +class FooChild extends Foo { + public function modifyBar($bar) { + $this->bar = $bar; + } +} + +$foo = new Foo(); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +var_dump($foo->bar); + +try { + $foo->baz = 'baz2'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBaz('baz2'); +var_dump($foo->baz); + +$child = new FooChild(); +try { + $child->modifyBar('baz'); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +string(3) "bar" +Cannot modify private(set) property Foo::$bar from global scope +string(3) "baz" +Cannot modify private(set) property Foo::$baz from global scope +string(4) "baz2" +Cannot modify private(set) property Foo::$bar from scope FooChild diff --git a/Zend/tests/asymmetric_visibility/protected.phpt b/Zend/tests/asymmetric_visibility/protected.phpt new file mode 100644 index 0000000000000..49a39b399362b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/protected.phpt @@ -0,0 +1,66 @@ +--TEST-- +Asymmetric visibility protected(set) +--FILE-- +bar = $bar; + } + + public function setBazPrivate($baz) { + $this->baz = $baz; + } +} + +class FooChild extends Foo { + public function setBarProtected($bar) { + $this->bar = $bar; + } + + public function setBazProtected($baz) { + $this->baz = $baz; + } +} + +$foo = new FooChild(); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBarPrivate('baz'); +var_dump($foo->bar); + +$foo->setBarProtected('qux'); +var_dump($foo->bar); + +try { + $foo->baz = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setbazPrivate('baz2'); +var_dump($foo->baz); + +$foo->setbazProtected('baz3'); +var_dump($foo->baz); + + +?> +--EXPECT-- +string(3) "bar" +Cannot modify protected(set) property Foo::$bar from global scope +string(3) "baz" +string(3) "qux" +Cannot modify protected(set) property Foo::$baz from global scope +string(4) "baz2" +string(4) "baz3" diff --git a/Zend/tests/asymmetric_visibility/readonly.phpt b/Zend/tests/asymmetric_visibility/readonly.phpt new file mode 100644 index 0000000000000..8fa77aafb1d9f --- /dev/null +++ b/Zend/tests/asymmetric_visibility/readonly.phpt @@ -0,0 +1,62 @@ +--TEST-- +Asymmetric visibility with readonly +--FILE-- +pDefault = 1; + $this->pPrivate = 1; + $this->pProtected = 1; + $this->pPublic = 1; + } +} + +class C extends P { + public function __construct() { + $this->pDefault = 1; + try { + $this->pPrivate = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + $this->pProtected = 1; + $this->pPublic = 1; + } +} + +function test() { + $p = new ReflectionClass(P::class)->newInstanceWithoutConstructor(); + try { + $p->pDefault = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + $p->pPrivate = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + $p->pProtected = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + $p->pPublic = 1; +} + +new P(); +new C(); +test(); + +?> +--EXPECT-- +Cannot modify private(set) property P::$pPrivate from scope C +Cannot modify protected(set) property P::$pDefault from global scope +Cannot modify private(set) property P::$pPrivate from global scope +Cannot modify protected(set) property P::$pProtected from global scope diff --git a/Zend/tests/asymmetric_visibility/reference.phpt b/Zend/tests/asymmetric_visibility/reference.phpt new file mode 100644 index 0000000000000..ae5271418282a --- /dev/null +++ b/Zend/tests/asymmetric_visibility/reference.phpt @@ -0,0 +1,32 @@ +--TEST-- +Asymmetric visibility reference +--FILE-- +bar; + $bar++; + } +} + +$foo = new Foo(); + +try { + $bar = &$foo->bar; + $bar++; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar); + +$foo->test(); +var_dump($foo->bar); + +?> +--EXPECT-- +Cannot indirectly modify private(set) property Foo::$bar from global scope +int(0) +int(1) diff --git a/Zend/tests/asymmetric_visibility/reference_2.phpt b/Zend/tests/asymmetric_visibility/reference_2.phpt new file mode 100644 index 0000000000000..d4ef6c03a7889 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/reference_2.phpt @@ -0,0 +1,30 @@ +--TEST-- +Asymmetric visibility reference in forbidden scope +--FILE-- +prop; + $prop = 42; +} + +try { + test(new C()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +try { + test(new C()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot indirectly modify private(set) property C::$prop from global scope +Cannot indirectly modify private(set) property C::$prop from global scope diff --git a/Zend/tests/asymmetric_visibility/scope_rebinding.phpt b/Zend/tests/asymmetric_visibility/scope_rebinding.phpt new file mode 100644 index 0000000000000..8c10d10f77a42 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/scope_rebinding.phpt @@ -0,0 +1,36 @@ +--TEST-- +Changing scope with Closure::bindTo() does not confuse asymmetric visibility +--FILE-- +bar++; +}; + +($c->bindTo(null, Foo::class))(); +var_dump($foo->bar); +try { + $c(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + ($c->bindTo(null, Bar::class))(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar); + +?> +--EXPECT-- +int(2) +Cannot modify private(set) property Foo::$bar from global scope +Cannot modify private(set) property Foo::$bar from scope Bar +int(2) diff --git a/Zend/tests/asymmetric_visibility/unset.phpt b/Zend/tests/asymmetric_visibility/unset.phpt new file mode 100644 index 0000000000000..3fd3d76730810 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/unset.phpt @@ -0,0 +1,67 @@ +--TEST-- +Asymmetric visibility unset protected(set) +--FILE-- +bar = $bar; + } + + public function setSecret($s) { + $this->secret = $s; + } + + public function unsetBarPrivate() { + unset($this->bar); + } +} + +class FooChild extends Foo { + public function unsetBarProtected() { + unset($this->bar); + } + + public function unsetSecret() { + unset($this->secret); + } +} + +$foo = new FooChild(); + +$foo->setBar('bar'); +try { + unset($foo->bar); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar ?? 'unset'); + +$foo->setBar('bar'); +$foo->unsetBarPrivate(); +var_dump($foo->bar ?? 'unset'); + +$foo->setBar('bar'); +$foo->unsetBarProtected(); +var_dump($foo->bar ?? 'unset'); + +$foo->setSecret('beep'); +try { + $foo->unsetSecret(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->secret ?? 'unset'); + +?> +--EXPECT-- +Cannot unset protected(set) property Foo::$bar from global scope +string(3) "bar" +string(5) "unset" +string(5) "unset" +Cannot unset private(set) property Foo::$secret from scope FooChild +string(4) "beep" diff --git a/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt b/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt new file mode 100644 index 0000000000000..d81f4d3891bf4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt @@ -0,0 +1,37 @@ +--TEST-- +R/w cache slots should be unshared +--FILE-- +bar); + $this->bar = $bar; + } +} + +$c = new C(); +try { + $c->setBar(1); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + $c->setBar(1); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Typed property P::$bar must not be accessed before initialization +Typed property P::$bar must not be accessed before initialization +object(C)#%d (0) { + ["bar"]=> + uninitialized(string) +} diff --git a/Zend/tests/asymmetric_visibility/variation.phpt b/Zend/tests/asymmetric_visibility/variation.phpt new file mode 100644 index 0000000000000..03cac375f7126 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/variation.phpt @@ -0,0 +1,134 @@ +--TEST-- +Asymmetric visibility variations +--FILE-- +prop = 1; + $this->array = []; + } + + public function r() { + echo $this->prop; + } + + public function w() { + $this->prop = 1; + echo 'done'; + } + + public function rw() { + $this->prop += 1; + echo 'done'; + } + + public function im() { + $this->array[] = 1; + echo 'done'; + } + + public function is() { + echo (int) isset($this->prop); + } + + public function us() { + unset($this->prop); + echo 'done'; + } + + public function us_dim() { + unset($this->array[0]); + echo 'done'; + } +} + +function r($test) { + echo $test->prop; +} + +function w($test) { + $test->prop = 0; + echo 'done'; +} + +function rw($test) { + $test->prop += 1; + echo 'done'; +} + +function im($test) { + $test->array[] = 1; + echo 'done'; +} + +function is($test) { + echo (int) isset($test->prop); +} + +function us($test) { + unset($test->prop); + echo 'done'; +} + +function us_dim($test) { + unset($test->array[0]); + echo 'done'; +} + +foreach ([true, false] as $init) { + foreach ([true, false] as $scope) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { + $test = new Test(); + if ($init) { + $test->init(); + } + + echo 'Init: ' . ((int) $init) . ', scope: ' . ((int) $scope) . ', op: ' . $op . ": "; + try { + if ($scope) { + $test->{$op}(); + } else { + $op($test); + } + } catch (Error $e) { + echo $e->getMessage(); + } + echo "\n"; + } + } +} + +?> +--EXPECT-- +Init: 1, scope: 1, op: r: 1 +Init: 1, scope: 1, op: w: done +Init: 1, scope: 1, op: rw: done +Init: 1, scope: 1, op: im: done +Init: 1, scope: 1, op: is: 1 +Init: 1, scope: 1, op: us: done +Init: 1, scope: 1, op: us_dim: done +Init: 1, scope: 0, op: r: 1 +Init: 1, scope: 0, op: w: Cannot modify private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: rw: Cannot modify private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: im: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 1, scope: 0, op: is: 1 +Init: 1, scope: 0, op: us: Cannot unset private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: us_dim: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 0, scope: 1, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 1, op: w: done +Init: 0, scope: 1, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 1, op: im: done +Init: 0, scope: 1, op: is: 0 +Init: 0, scope: 1, op: us: done +Init: 0, scope: 1, op: us_dim: done +Init: 0, scope: 0, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 0, op: w: Cannot modify private(set) property Test::$prop from global scope +Init: 0, scope: 0, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 0, op: im: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 0, scope: 0, op: is: 0 +Init: 0, scope: 0, op: us: Cannot unset private(set) property Test::$prop from global scope +Init: 0, scope: 0, op: us_dim: done diff --git a/Zend/tests/asymmetric_visibility/variation_nested.phpt b/Zend/tests/asymmetric_visibility/variation_nested.phpt new file mode 100644 index 0000000000000..c1dc753a944f1 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/variation_nested.phpt @@ -0,0 +1,84 @@ +--TEST-- +Asymmetric visibility nested variations +--FILE-- +prop = new Inner(); + } +} + +function r($test) { + echo $test->prop->prop; +} + +function w($test) { + $test->prop->prop = 0; + echo 'done'; +} + +function rw($test) { + $test->prop->prop += 1; + echo 'done'; +} + +function im($test) { + $test->prop->array[] = 1; + echo 'done'; +} + +function is($test) { + echo (int) isset($test->prop->prop); +} + +function us($test) { + unset($test->prop->prop); + echo 'done'; +} + +function us_dim($test) { + unset($test->prop->array[0]); + echo 'done'; +} + +foreach ([true, false] as $init) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { + $test = new Test(); + if ($init) { + $test->init(); + } + + echo 'Init: ' . ((int) $init) . ', op: ' . $op . ": "; + try { + $op($test); + } catch (Error $e) { + echo $e->getMessage(); + } + echo "\n"; + } +} + +?> +--EXPECT-- +Init: 1, op: r: 1 +Init: 1, op: w: done +Init: 1, op: rw: done +Init: 1, op: im: done +Init: 1, op: is: 1 +Init: 1, op: us: done +Init: 1, op: us_dim: done +Init: 0, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, op: w: Cannot indirectly modify private(set) property Test::$prop from global scope +Init: 0, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, op: im: Cannot indirectly modify private(set) property Test::$prop from global scope +Init: 0, op: is: 0 +Init: 0, op: us: done +Init: 0, op: us_dim: done diff --git a/Zend/tests/property_hooks/abstract_get_set_readonly.phpt b/Zend/tests/property_hooks/abstract_get_set_readonly.phpt new file mode 100644 index 0000000000000..644ffb474960b --- /dev/null +++ b/Zend/tests/property_hooks/abstract_get_set_readonly.phpt @@ -0,0 +1,13 @@ +--TEST-- +readonly property does not satisfy get/set abstract property +--FILE-- + +--EXPECTF-- +Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (P::$prop::set) in %s on line %d diff --git a/Zend/tests/property_hooks/interface_get_set_readonly.phpt b/Zend/tests/property_hooks/interface_get_set_readonly.phpt index 685eb4ee8bd0f..692a0bc7e7879 100644 --- a/Zend/tests/property_hooks/interface_get_set_readonly.phpt +++ b/Zend/tests/property_hooks/interface_get_set_readonly.phpt @@ -1,5 +1,7 @@ --TEST-- readonly property does not satisfy get/set interface property +--DESCRIPTION-- +The error message should be improved, the set access level comes from readonly. --FILE-- --EXPECTF-- -Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (I::$prop::set) in %s on line %d +Fatal error: Set access level of C::$prop must be omitted (as in class I) in %s on line %d diff --git a/Zend/tests/readonly_props/initialization_scope.phpt b/Zend/tests/readonly_props/initialization_scope.phpt index b01dacf2d42f4..f3e87efb2dfa3 100644 --- a/Zend/tests/readonly_props/initialization_scope.phpt +++ b/Zend/tests/readonly_props/initialization_scope.phpt @@ -22,12 +22,10 @@ try { } catch (Error $e) { echo $e->getMessage(), "\n"; } -try { - $test->initProtected(); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +$test->initProtected(); +var_dump($test); +$test = new B; $test->initPrivate(); var_dump($test->prop); @@ -56,17 +54,20 @@ class Y extends X { } $test = new Y; -try { - $test->initFromParent(); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +$test->initFromParent(); +var_dump($test); ?> ---EXPECT-- -Cannot initialize readonly property A::$prop from global scope -Cannot initialize readonly property A::$prop from scope B +--EXPECTF-- +Cannot modify protected(set) property A::$prop from global scope +object(B)#%d (1) { + ["prop"]=> + int(2) +} int(3) int(1) int(3) -Cannot initialize readonly property Y::$prop from scope X +object(Y)#%d (1) { + ["prop"]=> + int(1) +} diff --git a/Zend/tests/readonly_props/magic_get_set.phpt b/Zend/tests/readonly_props/magic_get_set.phpt index 201c4e3bfe2f8..2ce24cf2f1116 100644 --- a/Zend/tests/readonly_props/magic_get_set.phpt +++ b/Zend/tests/readonly_props/magic_get_set.phpt @@ -64,8 +64,8 @@ try { --EXPECT-- bool(false) Typed property Test::$prop must not be accessed before initialization -Cannot initialize readonly property Test::$prop from global scope -Cannot unset readonly property Test::$prop from global scope +Cannot modify protected(set) property Test::$prop from global scope +Cannot unset protected(set) property Test::$prop from global scope Test::__isset(prop) bool(true) Test::__get(prop) diff --git a/Zend/tests/readonly_props/public_set_non_readonly.phpt b/Zend/tests/readonly_props/public_set_non_readonly.phpt new file mode 100644 index 0000000000000..05bb1c0db32fa --- /dev/null +++ b/Zend/tests/readonly_props/public_set_non_readonly.phpt @@ -0,0 +1,13 @@ +--TEST-- +public(set) is allowed on non-readonly +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/readonly_props/unset.phpt b/Zend/tests/readonly_props/unset.phpt index 5bf2107a09be7..d6c3f1edf5479 100644 --- a/Zend/tests/readonly_props/unset.phpt +++ b/Zend/tests/readonly_props/unset.phpt @@ -61,4 +61,4 @@ Test2::__get int(1) int(1) Cannot unset readonly property Test2::$prop -Cannot unset readonly property Test3::$prop from global scope +Cannot unset protected(set) property Test3::$prop from global scope diff --git a/Zend/tests/readonly_props/variation.phpt b/Zend/tests/readonly_props/variation.phpt index 1c93f3f6f5994..12d4b41ed9fc2 100644 --- a/Zend/tests/readonly_props/variation.phpt +++ b/Zend/tests/readonly_props/variation.phpt @@ -5,9 +5,11 @@ Readonly variations class Test { public readonly int $prop; + public readonly array $array; public function init() { $this->prop = 1; + $this->array = []; } public function r() { @@ -37,6 +39,11 @@ class Test { unset($this->prop); echo 'done'; } + + public function us_dim() { + unset($this->array[0]); + echo 'done'; + } } function r($test) { @@ -67,9 +74,14 @@ function us($test) { echo 'done'; } +function us_dim($test) { + unset($test->array[0]); + echo 'done'; +} + foreach ([true, false] as $init) { foreach ([true, false] as $scope) { - foreach (['r', 'w', 'rw', 'im', 'is', 'us'] as $op) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { $test = new Test(); if ($init) { $test->init(); @@ -98,21 +110,25 @@ Init: 1, scope: 1, op: rw: Cannot modify readonly property Test::$prop Init: 1, scope: 1, op: im: Cannot indirectly modify readonly property Test::$prop Init: 1, scope: 1, op: is: 1 Init: 1, scope: 1, op: us: Cannot unset readonly property Test::$prop +Init: 1, scope: 1, op: us_dim: Cannot indirectly modify readonly property Test::$array Init: 1, scope: 0, op: r: 1 Init: 1, scope: 0, op: w: Cannot modify readonly property Test::$prop Init: 1, scope: 0, op: rw: Cannot modify readonly property Test::$prop Init: 1, scope: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 1, scope: 0, op: is: 1 Init: 1, scope: 0, op: us: Cannot unset readonly property Test::$prop +Init: 1, scope: 0, op: us_dim: Cannot indirectly modify readonly property Test::$array Init: 0, scope: 1, op: r: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 1, op: w: done Init: 0, scope: 1, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 1, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, scope: 1, op: is: 0 Init: 0, scope: 1, op: us: done +Init: 0, scope: 1, op: us_dim: done Init: 0, scope: 0, op: r: Typed property Test::$prop must not be accessed before initialization -Init: 0, scope: 0, op: w: Cannot initialize readonly property Test::$prop from global scope +Init: 0, scope: 0, op: w: Cannot modify protected(set) property Test::$prop from global scope Init: 0, scope: 0, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, scope: 0, op: is: 0 -Init: 0, scope: 0, op: us: Cannot unset readonly property Test::$prop from global scope +Init: 0, scope: 0, op: us: Cannot unset protected(set) property Test::$prop from global scope +Init: 0, scope: 0, op: us_dim: done diff --git a/Zend/tests/readonly_props/variation_nested.phpt b/Zend/tests/readonly_props/variation_nested.phpt index 72a7925da9905..31608afcc2cea 100644 --- a/Zend/tests/readonly_props/variation_nested.phpt +++ b/Zend/tests/readonly_props/variation_nested.phpt @@ -44,8 +44,13 @@ function us($test) { echo 'done'; } +function us_dim($test) { + unset($test->prop->array[0]); + echo 'done'; +} + foreach ([true, false] as $init) { - foreach (['r', 'w', 'rw', 'im', 'is', 'us'] as $op) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { $test = new Test(); if ($init) { $test->init(); @@ -69,9 +74,11 @@ Init: 1, op: rw: done Init: 1, op: im: done Init: 1, op: is: 1 Init: 1, op: us: done +Init: 1, op: us_dim: done Init: 0, op: r: Typed property Test::$prop must not be accessed before initialization Init: 0, op: w: Cannot indirectly modify readonly property Test::$prop Init: 0, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, op: is: 0 Init: 0, op: us: done +Init: 0, op: us_dim: done diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 27a914aab9e6b..1d10f61e62175 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4523,6 +4523,33 @@ ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, z if (!(access_type & ZEND_ACC_PPP_MASK)) { access_type |= ZEND_ACC_PUBLIC; } + /* Add the protected(set) bit for public readonly properties with no set visibility. */ + if ((access_type & (ZEND_ACC_PUBLIC|ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) == (ZEND_ACC_PUBLIC|ZEND_ACC_READONLY)) { + access_type |= ZEND_ACC_PROTECTED_SET; + } else if (UNEXPECTED(access_type & ZEND_ACC_PPP_SET_MASK)) { + if (!ZEND_TYPE_IS_SET(type)) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "Property with asymmetric visibility %s::$%s must have type", + ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + uint32_t get_visibility = zend_visibility_to_set_visibility(access_type & ZEND_ACC_PPP_MASK); + uint32_t set_visibility = access_type & ZEND_ACC_PPP_SET_MASK; + if (get_visibility > set_visibility) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "Visibility of property %s::$%s must not be weaker than set visibility", + ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + /* Remove equivalent set visibility. */ + if (((access_type & (ZEND_ACC_PUBLIC|ZEND_ACC_PUBLIC_SET)) == (ZEND_ACC_PUBLIC|ZEND_ACC_PUBLIC_SET)) + || ((access_type & (ZEND_ACC_PROTECTED|ZEND_ACC_PROTECTED_SET)) == (ZEND_ACC_PROTECTED|ZEND_ACC_PROTECTED_SET)) + || ((access_type & (ZEND_ACC_PRIVATE|ZEND_ACC_PRIVATE_SET)) == (ZEND_ACC_PRIVATE|ZEND_ACC_PRIVATE_SET))) { + access_type &= ~ZEND_ACC_PPP_SET_MASK; + } + /* private(set) properties are implicitly final. */ + if (access_type & ZEND_ACC_PRIVATE_SET) { + access_type |= ZEND_ACC_FINAL; + } + } /* Virtual properties have no backing storage, the offset should never be used. However, the * virtual flag cannot be definitively determined at compile time. Allow using default values diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 5ecda76870452..d33747412ef0a 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1697,7 +1697,7 @@ static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, } } -static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags) { +static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags, zend_modifier_target target) { if (flags & ZEND_ACC_PUBLIC) { smart_str_appends(str, "public "); } else if (flags & ZEND_ACC_PROTECTED) { @@ -1705,6 +1705,16 @@ static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags) } else if (flags & ZEND_ACC_PRIVATE) { smart_str_appends(str, "private "); } + + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + if (flags & ZEND_ACC_PRIVATE_SET) { + smart_str_appends(str, "private(set) "); + } else if (flags & ZEND_ACC_PROTECTED_SET) { + smart_str_appends(str, "protected(set) "); + } else if (flags & ZEND_ACC_PUBLIC_SET) { + smart_str_appends(str, "public(set) "); + } + } } static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) { @@ -1815,7 +1825,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, decl->child[4], indent, newlines); } - zend_ast_export_visibility(str, decl->flags); + zend_ast_export_visibility(str, decl->flags, ZEND_MODIFIER_TARGET_METHOD); if (decl->flags & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); @@ -1941,7 +1951,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, ast->child[2], indent, 1); } - zend_ast_export_visibility(str, ast->attr); + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_PROPERTY); if (ast->attr & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); @@ -1967,7 +1977,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, ast->child[1], indent, 1); } - zend_ast_export_visibility(str, ast->attr); + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CONSTANT); smart_str_appends(str, "const "); if (ast->child[2]) { zend_ast_export_type(str, ast->child[2], indent); @@ -2388,7 +2398,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio for (uint32_t i = 0; i < hook_list->children; i++) { zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; - zend_ast_export_visibility(str, hook->flags); + zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 003e2bd83122e..36231a5610f32 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -860,6 +860,12 @@ static char *zend_modifier_token_to_string(uint32_t token) return "readonly"; case T_ABSTRACT: return "abstract"; + case T_PUBLIC_SET: + return "public(set)"; + case T_PROTECTED_SET: + return "protected(set)"; + case T_PRIVATE_SET: + return "private(set)"; EMPTY_SWITCH_DEFAULT_CASE() } } @@ -905,6 +911,21 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token return ZEND_ACC_STATIC; } break; + case T_PUBLIC_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PUBLIC_SET; + } + break; + case T_PROTECTED_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PROTECTED_SET; + } + break; + case T_PRIVATE_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PRIVATE_SET; + } + break; } char *member; @@ -1020,6 +1041,13 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag, zend_modifi "Cannot use the final modifier on an abstract method", 0); return 0; } + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + if ((flags & ZEND_ACC_PPP_SET_MASK) && (new_flag & ZEND_ACC_PPP_SET_MASK)) { + zend_throw_exception(zend_ce_compile_error, + "Multiple access type modifiers are not allowed", 0); + return 0; + } + } return new_flags; } /* }}} */ @@ -7569,7 +7597,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast)); bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0; - uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); + uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY); bool is_promoted = property_flags || hooks_ast; znode var_node, default_node; @@ -7793,7 +7821,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_ast *param_ast = list->child[i]; zend_ast *hooks_ast = param_ast->child[5]; bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; - uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); + uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY); bool is_promoted = flags || hooks_ast; if (!is_promoted) { continue; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c7e31877b5cd2..92a31764a89f8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -253,7 +253,7 @@ typedef struct _zend_oparray_context { /* or IS_CONSTANT_VISITED_MARK | | | */ #define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ /* | | | */ -/* Property Flags (unused: 10...) | | | */ +/* Property Flags (unused: 13...) | | | */ /* =========== | | | */ /* | | | */ /* Promoted property / parameter | | | */ @@ -262,6 +262,11 @@ typedef struct _zend_oparray_context { /* Virtual property without backing storage | | | */ #define ZEND_ACC_VIRTUAL (1 << 9) /* | | X | */ /* | | | */ +/* Asymmetric visibility | | | */ +#define ZEND_ACC_PUBLIC_SET (1 << 10) /* | | X | */ +#define ZEND_ACC_PROTECTED_SET (1 << 11) /* | | X | */ +#define ZEND_ACC_PRIVATE_SET (1 << 12) /* | | X | */ +/* | | | */ /* Class Flags (unused: 30,31) | | | */ /* =========== | | | */ /* | | | */ @@ -395,6 +400,20 @@ typedef struct _zend_oparray_context { #define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE) +#define ZEND_ACC_PPP_SET_MASK (ZEND_ACC_PUBLIC_SET | ZEND_ACC_PROTECTED_SET | ZEND_ACC_PRIVATE_SET) + +static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t visibility) +{ + switch (visibility) { + case ZEND_ACC_PUBLIC: + return ZEND_ACC_PUBLIC_SET; + case ZEND_ACC_PROTECTED: + return ZEND_ACC_PROTECTED_SET; + case ZEND_ACC_PRIVATE: + return ZEND_ACC_PRIVATE_SET; + EMPTY_SWITCH_DEFAULT_CASE(); + } +} /* call through internal function handler. e.g. Closure::invoke() */ #define ZEND_ACC_CALL_VIA_HANDLER ZEND_ACC_CALL_VIA_TRAMPOLINE @@ -1001,7 +1020,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_FETCH_CLASS_ALLOW_UNLINKED 0x0400 #define ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED 0x0800 -/* These should not clash with ZEND_ACC_(PUBLIC|PROTECTED|PRIVATE) */ +/* These should not clash with ZEND_ACC_PPP_MASK and ZEND_ACC_PPP_SET_MASK */ #define ZEND_PARAM_REF (1<<3) #define ZEND_PARAM_VARIADIC (1<<4) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 602bb3b0e79f5..eb868760575b0 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -915,6 +915,32 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_pr ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( + const zend_property_info *prop_info, const char *operation +) { + zend_class_entry *scope; + if (EG(fake_scope)) { + scope = EG(fake_scope); + } else { + scope = zend_get_called_scope(EG(current_execute_data)); + } + + const char *visibility; + if (prop_info->flags & ZEND_ACC_PRIVATE_SET) { + visibility = "private(set)"; + } else { + ZEND_ASSERT(prop_info->flags & ZEND_ACC_PROTECTED_SET); + visibility = "protected(set)"; + } + + zend_throw_error(NULL, "Cannot %s %s property %s::$%s from %s%s", + operation, + visibility, + ZSTR_VAL(prop_info->ce->name), + ZSTR_VAL(prop_info->name), + scope ? "scope " : "global scope", scope ? ZSTR_VAL(scope->name) : ""); +} + static const zend_class_entry *resolve_single_class_type(zend_string *name, const zend_class_entry *self_ce) { if (zend_string_equals_literal_ci(name, "self")) { return self_ce; @@ -1028,9 +1054,15 @@ static zend_never_inline zval* zend_assign_to_typed_prop(zend_property_info *inf { zval tmp; - if (UNEXPECTED((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(info); - return &EG(uninitialized_zval); + if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { + zend_readonly_property_modification_error(info); + return &EG(uninitialized_zval); + } + if (info->flags & ZEND_ACC_PPP_SET_MASK && !zend_asymmetric_property_has_set_access(info)) { + zend_asymmetric_visibility_property_modification_error(info, "modify"); + return &EG(uninitialized_zval); + } } ZVAL_DEREF(value); @@ -3357,7 +3389,8 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c ZVAL_INDIRECT(result, ptr); zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); if (prop_info) { - if (UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { + if (UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) + && ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info))) { /* For objects, W/RW/UNSET fetch modes might not actually modify object. * Similar as with magic __get() allow them, but return the value as a copy * to make sure no actual modification is possible. */ @@ -3365,7 +3398,11 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c if (Z_TYPE_P(ptr) == IS_OBJECT) { ZVAL_COPY(result, ptr); } else { - zend_readonly_property_indirect_modification_error(prop_info); + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_readonly_property_indirect_modification_error(prop_info); + } else { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + } ZVAL_ERROR(result); } return; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index fe854f305150c..190d67f82a598 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -92,6 +92,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_pr ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *info, const char *operation); + ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); ZEND_API ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *value); diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 2d6e0e427738c..9d7c7f179de7d 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -212,6 +212,18 @@ char *zend_visibility_string(uint32_t fn_flags) /* {{{ */ } /* }}} */ +static const char *zend_asymmetric_visibility_string(uint32_t fn_flags) /* {{{ */ +{ + if (fn_flags & ZEND_ACC_PRIVATE_SET) { + return "private(set)"; + } else if (fn_flags & ZEND_ACC_PROTECTED_SET) { + return "protected(set)"; + } else { + ZEND_ASSERT(!(fn_flags & ZEND_ACC_PUBLIC_SET)); + return "omitted"; + } +} + static zend_string *resolve_class_name(zend_class_entry *scope, zend_string *name) { ZEND_ASSERT(scope); if (zend_string_equals_literal_ci(name, "parent") && scope->parent) { @@ -1442,6 +1454,25 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke ZSTR_VAL(ce->name), ZSTR_VAL(key)); } } + if (UNEXPECTED((child_info->flags & ZEND_ACC_PPP_SET_MASK)) + /* Get-only virtual properties have no set visibility, so any child visibility is fine. */ + && !(parent_info->hooks && (parent_info->flags & ZEND_ACC_VIRTUAL) && !parent_info->hooks[ZEND_PROPERTY_HOOK_SET])) { + uint32_t parent_set_visibility = parent_info->flags & ZEND_ACC_PPP_SET_MASK; + /* Adding set protection is fine if it's the same or weaker than + * the parents full property visibility. */ + if (!parent_set_visibility) { + parent_set_visibility = zend_visibility_to_set_visibility(parent_info->flags & ZEND_ACC_PPP_MASK); + } + uint32_t child_set_visibility = child_info->flags & ZEND_ACC_PPP_SET_MASK; + if (child_set_visibility > parent_set_visibility) { + zend_error_noreturn( + E_COMPILE_ERROR, + "Set access level of %s::$%s must be %s (as in class %s)%s", + ZSTR_VAL(ce->name), ZSTR_VAL(key), + zend_asymmetric_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), + !(parent_info->flags & ZEND_ACC_PPP_SET_MASK) ? "" : " or weaker"); + } + } if (UNEXPECTED((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK))) { zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ZSTR_VAL(ce->name), ZSTR_VAL(key), zend_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 5423d40185766..d2a29e670d8bf 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -154,6 +154,9 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_PRIVATE "'private'" %token T_PROTECTED "'protected'" %token T_PUBLIC "'public'" +%token T_PRIVATE_SET "'private(set)'" +%token T_PROTECTED_SET "'protected(set)'" +%token T_PUBLIC_SET "'public(set)'" %token T_READONLY "'readonly'" %token T_VAR "'var'" %token T_UNSET "'unset'" @@ -1066,6 +1069,9 @@ member_modifier: T_PUBLIC { $$ = T_PUBLIC; } | T_PROTECTED { $$ = T_PROTECTED; } | T_PRIVATE { $$ = T_PRIVATE; } + | T_PUBLIC_SET { $$ = T_PUBLIC_SET; } + | T_PROTECTED_SET { $$ = T_PROTECTED_SET; } + | T_PRIVATE_SET { $$ = T_PRIVATE_SET; } | T_STATIC { $$ = T_STATIC; } | T_ABSTRACT { $$ = T_ABSTRACT; } | T_FINAL { $$ = T_FINAL; } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 4551d26a17e79..194f5a995fbce 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1725,6 +1725,18 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN_WITH_IDENT(T_PROTECTED); } +"public(set)" { + RETURN_TOKEN_WITH_IDENT(T_PUBLIC_SET); +} + +"protected(set)" { + RETURN_TOKEN_WITH_IDENT(T_PROTECTED_SET); +} + +"private(set)" { + RETURN_TOKEN_WITH_IDENT(T_PRIVATE_SET); +} + "public" { RETURN_TOKEN_WITH_IDENT(T_PUBLIC); } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 4c096d26b1b7b..fdac24ccb258b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -304,13 +304,6 @@ static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( return 1; } -static ZEND_COLD zend_never_inline void zend_readonly_property_modification_scope_error( - const zend_class_entry *ce, const zend_string *member, const zend_class_entry *scope, const char *operation) { - zend_throw_error(NULL, "Cannot %s readonly property %s::$%s from %s%s", - operation, ZSTR_VAL(ce->name), ZSTR_VAL(member), - scope ? "scope " : "global scope", scope ? ZSTR_VAL(scope->name) : ""); -} - static ZEND_COLD zend_never_inline void zend_readonly_property_unset_error( zend_class_entry *ce, zend_string *member) { zend_throw_error(NULL, "Cannot unset readonly property %s::$%s", @@ -547,6 +540,17 @@ ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_st } /* }}} */ +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info) { + ZEND_ASSERT(prop_info->flags & ZEND_ACC_PPP_SET_MASK); + ZEND_ASSERT(!(prop_info->flags & ZEND_ACC_PUBLIC_SET)); + zend_class_entry *scope = get_fake_or_executed_scope(); + if (prop_info->ce == scope) { + return true; + } + return EXPECTED((prop_info->flags & ZEND_ACC_PROTECTED_SET) + && is_protected_compatible_scope(prop_info->ce, scope)); +} + static void zend_property_guard_dtor(zval *el) /* {{{ */ { uint32_t *ptr = (uint32_t*)Z_PTR_P(el); if (EXPECTED(!(((uintptr_t)ptr) & 1))) { @@ -686,32 +690,31 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { try_again: retval = OBJ_PROP(zobj, property_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY) - && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) { - if (Z_TYPE_P(retval) == IS_OBJECT) { - /* For objects, W/RW/UNSET fetch modes might not actually modify object. - * Similar as with magic __get() allow them, but return the value as a copy - * to make sure no actual modification is possible. */ - ZVAL_COPY(rv, retval); - retval = rv; - } else { - zend_readonly_property_indirect_modification_error(prop_info); - retval = &EG(uninitialized_zval); - } + + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) + && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) + && ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info))) { + if (Z_TYPE_P(retval) == IS_OBJECT) { + /* For objects, W/RW/UNSET fetch modes might not actually modify object. + * Similar as with magic __get() allow them, but return the value as a copy + * to make sure no actual modification is possible. */ + ZVAL_COPY(rv, retval); + retval = rv; + goto exit; + } else if (Z_TYPE_P(retval) == IS_UNDEF && type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + goto exit; } - goto exit; - } else { - if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - if (type == BP_VAR_W || type == BP_VAR_RW) { - zend_readonly_property_indirect_modification_error(prop_info); - retval = &EG(uninitialized_zval); - goto exit; - } else if (type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - goto exit; - } + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_readonly_property_indirect_modification_error(prop_info); + } else { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); } + retval = &EG(uninitialized_zval); + goto exit; + } + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + goto exit; } if (UNEXPECTED(Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT)) { /* Skip __get() for uninitialized typed properties */ @@ -912,36 +915,12 @@ static zend_always_inline bool property_uses_strict_types(void) { && ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)); } -static bool verify_readonly_initialization_access( - const zend_property_info *prop_info, const zend_class_entry *ce, - zend_string *name, const char *operation) { - zend_class_entry *scope = get_fake_or_executed_scope(); - if (prop_info->ce == scope) { - return true; - } - - /* We may have redeclared a parent property. In that case the parent should still be - * allowed to initialize it. */ - if (scope && is_derived_class(ce, scope)) { - const zend_property_info *prop_info = zend_hash_find_ptr(&scope->properties_info, name); - if (prop_info) { - /* This should be ensured by inheritance. */ - ZEND_ASSERT(prop_info->flags & ZEND_ACC_READONLY); - if (prop_info->ce == scope) { - return true; - } - } - } - - zend_readonly_property_modification_scope_error(prop_info->ce, name, scope, operation); - return false; -} - ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zval *value, void **cache_slot) /* {{{ */ { zval *variable_ptr, tmp; uintptr_t property_offset; const zend_property_info *prop_info = NULL; + uint32_t *guard = NULL; ZEND_ASSERT(!Z_ISREF_P(value)); property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__set != NULL), cache_slot, &prop_info); @@ -949,17 +928,35 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { try_again: variable_ptr = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { - Z_TRY_ADDREF_P(value); - if (prop_info) { - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(variable_ptr) & IS_PROP_REINITABLE))) { - Z_TRY_DELREF_P(value); + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + bool error; + if (Z_TYPE_P(variable_ptr) != IS_UNDEF || (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_UNINIT) || !zobj->ce->__set) { + error = true; + } else { + guard = zend_get_property_guard(zobj, name); + error = (*guard) & IN_SET; + } + if (error) { + if ((prop_info->flags & ZEND_ACC_READONLY) + && Z_TYPE_P(variable_ptr) != IS_UNDEF + && !(Z_PROP_FLAG_P(variable_ptr) & IS_PROP_REINITABLE)) { zend_readonly_property_modification_error(prop_info); variable_ptr = &EG(error_zval); goto exit; } + if ((prop_info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(prop_info)) { + zend_asymmetric_visibility_property_modification_error(prop_info, "modify"); + variable_ptr = &EG(error_zval); + goto exit; + } + } + } + + if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { + Z_TRY_ADDREF_P(value); + if (prop_info) { typed_property: ZVAL_COPY_VALUE(&tmp, value); // Increase refcount to prevent object from being released in __toString() @@ -1073,7 +1070,9 @@ found:; /* magic set */ if (zobj->ce->__set) { - uint32_t *guard = zend_get_property_guard(zobj, name); + if (!guard) { + guard = zend_get_property_guard(zobj, name); + } if (!((*guard) & IN_SET)) { GC_ADDREF(zobj); @@ -1099,12 +1098,6 @@ found:; Z_TRY_ADDREF_P(value); if (prop_info) { - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) - && !verify_readonly_initialization_access(prop_info, zobj->ce, name, "initialize"))) { - Z_TRY_DELREF_P(value); - variable_ptr = &EG(error_zval); - goto exit; - } goto typed_property; } @@ -1270,9 +1263,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam ZVAL_NULL(retval); } } - } else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - /* Readonly property, delegate to read_property + write_property. */ - retval = NULL; + } else if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info)) { + retval = NULL; + } } else if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) { ZVAL_NULL(retval); } @@ -1280,9 +1274,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam /* we do have getter - fail and let it try again with usual get/set */ retval = NULL; } - } else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - /* Readonly property, delegate to read_property + write_property. */ - retval = NULL; + } else if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info)) { + retval = NULL; + } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { if (EXPECTED(zobj->properties)) { @@ -1327,21 +1322,36 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void { uintptr_t property_offset; const zend_property_info *prop_info = NULL; + uint32_t *guard = NULL; property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__unset != NULL), cache_slot, &prop_info); if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { zval *slot = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(slot) != IS_UNDEF) { - if (UNEXPECTED(prop_info && (prop_info->flags & ZEND_ACC_READONLY))) { - if (Z_PROP_FLAG_P(slot) & IS_PROP_REINITABLE) { - Z_PROP_FLAG_P(slot) &= ~IS_PROP_REINITABLE; - } else { + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + bool error; + if (Z_TYPE_P(slot) != IS_UNDEF || Z_PROP_FLAG_P(slot) & IS_PROP_UNINIT || !zobj->ce->__unset) { + error = true; + } else { + guard = zend_get_property_guard(zobj, name); + error = (*guard) & IN_UNSET; + } + if (error) { + if ((prop_info->flags & ZEND_ACC_READONLY) + && Z_TYPE_P(slot) != IS_UNDEF + && !(Z_PROP_FLAG_P(slot) & IS_PROP_REINITABLE)) { zend_readonly_property_unset_error(prop_info->ce, name); return; } + if ((prop_info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(prop_info)) { + zend_asymmetric_visibility_property_modification_error(prop_info, "unset"); + return; + } } + } + + if (Z_TYPE_P(slot) != IS_UNDEF) { if (UNEXPECTED(Z_ISREF_P(slot)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(slot)))) { if (prop_info) { @@ -1358,11 +1368,6 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void return; } if (UNEXPECTED(Z_PROP_FLAG_P(slot) & IS_PROP_UNINIT)) { - if (UNEXPECTED(prop_info && (prop_info->flags & ZEND_ACC_READONLY) - && !verify_readonly_initialization_access(prop_info, zobj->ce, name, "unset"))) { - return; - } - /* Reset the IS_PROP_UNINIT flag, if it exists and bypass __unset(). */ Z_PROP_FLAG_P(slot) = 0; return; @@ -1388,7 +1393,9 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void /* magic unset */ if (zobj->ce->__unset) { - uint32_t *guard = zend_get_property_guard(zobj, name); + if (!guard) { + guard = zend_get_property_guard(zobj, name); + } if (!((*guard) & IN_UNSET)) { /* have unsetter - try with it! */ (*guard) |= IN_UNSET; /* prevent circular unsetting */ diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 730b110eccd37..8ec2164413df5 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -310,6 +310,8 @@ ZEND_API zend_function *zend_get_property_hook_trampoline( const zend_property_info *prop_info, zend_property_hook_kind kind, zend_string *prop_name); +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); + #define zend_release_properties(ht) do { \ if ((ht) && !(GC_FLAGS(ht) & GC_IMMUTABLE) && !GC_DELREF(ht)) { \ zend_array_destroy(ht); \ diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 8ed378d7552b0..a1370ea0723a8 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2648,6 +2648,22 @@ static void ZEND_FASTCALL zend_jit_assign_obj_helper(zend_object *zobj, zend_str } } +static zend_always_inline bool verify_readonly_and_avis(zval *property_val, zend_property_info *info, bool indirect) +{ + if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { + zend_readonly_property_modification_error(info); + return false; + } + if ((info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(info)) { + const char *operation = indirect ? "indirectly modify" : "modify"; + zend_asymmetric_visibility_property_modification_error(info, operation); + return false; + } + } + return true; +} + static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend_property_info *info, zval *value, zval *result) { zend_execute_data *execute_data = EG(current_execute_data); @@ -2661,8 +2677,7 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend value = &EG(uninitialized_zval); } - if (UNEXPECTED((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(info); + if (UNEXPECTED(!verify_readonly_and_avis(property_val, info, false))) { if (result) { ZVAL_UNDEF(result); } @@ -2723,8 +2738,7 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_prop zend_execute_data *execute_data = EG(current_execute_data); zval z_copy; - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(zptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(zptr, prop_info, true))) { return; } @@ -2818,8 +2832,7 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { return; } @@ -2851,8 +2864,7 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { return; } @@ -2898,8 +2910,7 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { if (result) { ZVAL_UNDEF(result); } @@ -2933,8 +2944,7 @@ static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { if (result) { ZVAL_UNDEF(result); } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index bb0caf477e511..49ddf40a0e7ce 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -13933,16 +13933,37 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, && (!ce || ce_is_instanceof || (ce->ce_flags & (ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_TRAIT)))) { uint32_t flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS; + ir_ref allowed_inputs = IR_UNUSED; + ir_ref forbidden_inputs = IR_UNUSED; + ir_ref prop_info_ref = ir_LOAD_A( ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2)); ir_ref if_has_prop_info = ir_IF(prop_info_ref); ir_IF_TRUE_cold(if_has_prop_info); - ir_ref if_readonly = ir_IF( - ir_AND_U32(ir_LOAD_U32(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_property_info, flags))), - ir_CONST_U32(ZEND_ACC_READONLY))); + ir_ref prop_flags = ir_LOAD_U32(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_property_info, flags))); + ir_ref if_readonly_or_avis = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))); + + ir_IF_FALSE(if_readonly_or_avis); + ir_END_list(allowed_inputs); + + ir_IF_TRUE_cold(if_readonly_or_avis); + + ir_ref if_readonly = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY))); ir_IF_TRUE(if_readonly); + ir_END_list(forbidden_inputs); + + ir_IF_FALSE(if_readonly); + ir_ref has_avis_access = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_asymmetric_property_has_set_access), prop_info_ref); + ir_ref if_avis_access = ir_IF(has_avis_access); + ir_IF_TRUE(if_avis_access); + ir_END_list(allowed_inputs); + + ir_IF_FALSE(if_avis_access); + ir_END_list(forbidden_inputs); + + ir_MERGE_list(forbidden_inputs); ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); ir_IF_TRUE(if_prop_obj); @@ -13955,19 +13976,27 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_FALSE_cold(if_prop_obj); jit_SET_EX_OPLINE(jit, opline); + if_readonly = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY))); + ir_IF_TRUE(if_readonly); ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_readonly_property_indirect_modification_error), prop_info_ref); jit_set_Z_TYPE_INFO(jit, res_addr, _IS_ERROR); ir_END_list(end_inputs); + ir_IF_FALSE(if_readonly); + ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_asymmetric_visibility_property_modification_error), + prop_info_ref, ir_CONST_ADDR("indirectly modify")); + jit_set_Z_TYPE_INFO(jit, res_addr, _IS_ERROR); + ir_END_list(end_inputs); + + ir_MERGE_list(allowed_inputs); + if (flags == ZEND_FETCH_DIM_WRITE) { - ir_IF_FALSE_cold(if_readonly); jit_SET_EX_OPLINE(jit, opline); ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_check_array_promotion), prop_ref, prop_info_ref); ir_END_list(end_inputs); ir_IF_FALSE(if_has_prop_info); } else if (flags == ZEND_FETCH_REF) { - ir_IF_FALSE_cold(if_readonly); ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_create_typed_ref), prop_ref, prop_info_ref, @@ -13976,10 +14005,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_FALSE(if_has_prop_info); } else { ZEND_ASSERT(flags == 0); - ir_IF_FALSE(if_has_prop_info); - ir_ref no_prop_info_path = ir_END(); - ir_IF_FALSE(if_readonly); - ir_MERGE_WITH(no_prop_info_path); + ir_MERGE_WITH_EMPTY_FALSE(if_has_prop_info); } } } else { @@ -14005,9 +14031,6 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_TRUE(if_def); } if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_READONLY)) { - if (!prop_type_ref) { - prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr); - } ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); ir_IF_TRUE(if_prop_obj); ir_ref ref = jit_Z_PTR(jit, prop_addr); @@ -14023,6 +14046,28 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_END_list(end_inputs); goto result_fetched; + } else if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_PPP_SET_MASK)) { + /* Readonly properties which are also asymmetric are never mutable indirectly, which is + * handled by the previous branch. */ + ir_ref has_access = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_asymmetric_property_has_set_access), ir_CONST_ADDR(prop_info)); + + ir_ref if_access = ir_IF(has_access); + ir_IF_FALSE_cold(if_access); + + ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); + ir_IF_TRUE(if_prop_obj); + ir_ref ref = jit_Z_PTR(jit, prop_addr); + jit_GC_ADDREF(jit, ref); + jit_set_Z_PTR(jit, res_addr, ref); + jit_set_Z_TYPE_INFO(jit, res_addr, IS_OBJECT_EX); + ir_END_list(end_inputs); + + ir_IF_FALSE_cold(if_prop_obj); + ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_asymmetric_visibility_property_modification_error), + ir_CONST_ADDR(prop_info), ir_CONST_ADDR("indirectly modify")); + ir_END_list(end_inputs); + + ir_IF_TRUE(if_access); } if (opline->opcode == ZEND_FETCH_OBJ_W diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1d26c80f222bf..1215fa8b1ad48 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -940,6 +940,17 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha smart_str_appends(str, "protected "); break; } + switch (prop->flags & ZEND_ACC_PPP_SET_MASK) { + case ZEND_ACC_PRIVATE_SET: + smart_str_appends(str, "private(set) "); + break; + case ZEND_ACC_PROTECTED_SET: + smart_str_appends(str, "protected(set) "); + break; + case ZEND_ACC_PUBLIC_SET: + ZEND_UNREACHABLE(); + break; + } if (prop->flags & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); } @@ -5679,6 +5690,16 @@ ZEND_METHOD(ReflectionProperty, isProtected) } /* }}} */ +ZEND_METHOD(ReflectionProperty, isPrivateSet) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE_SET); +} + +ZEND_METHOD(ReflectionProperty, isProtectedSet) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED_SET); +} + /* {{{ Returns whether this property is static */ ZEND_METHOD(ReflectionProperty, isStatic) { @@ -5727,7 +5748,7 @@ ZEND_METHOD(ReflectionProperty, getModifiers) { reflection_object *intern; property_reference *ref; - uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL; + uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL; if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index d6d9c9d715f4a..2bb9a9a5efa01 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -444,6 +444,10 @@ class ReflectionProperty implements Reflector public const int IS_PRIVATE = UNKNOWN; /** @cvalue ZEND_ACC_ABSTRACT */ public const int IS_ABSTRACT = UNKNOWN; + /** @cvalue ZEND_ACC_PROTECTED_SET */ + public const int IS_PROTECTED_SET = UNKNOWN; + /** @cvalue ZEND_ACC_PRIVATE_SET */ + public const int IS_PRIVATE_SET = UNKNOWN; public string $name; public string $class; @@ -480,6 +484,10 @@ public function isPrivate(): bool {} /** @tentative-return-type */ public function isProtected(): bool {} + public function isPrivateSet(): bool {} + + public function isProtectedSet(): bool {} + /** @tentative-return-type */ public function isStatic(): bool {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 2f0a513044c5d..19812c409c053 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d2a365f6f398bbcf3f2520c28d508ca63f08b5ff */ + * Stub hash: 28fde6ed0e247201ee25d608d27a4c5b0bb8f2f7 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -371,6 +371,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_isProtected arginfo_class_ReflectionFunctionAbstract_inNamespace +#define arginfo_class_ReflectionProperty_isPrivateSet arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionProperty_isProtectedSet arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + #define arginfo_class_ReflectionProperty_isStatic arginfo_class_ReflectionFunctionAbstract_inNamespace #define arginfo_class_ReflectionProperty_isReadOnly arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType @@ -785,6 +789,8 @@ ZEND_METHOD(ReflectionProperty, isInitialized); ZEND_METHOD(ReflectionProperty, isPublic); ZEND_METHOD(ReflectionProperty, isPrivate); ZEND_METHOD(ReflectionProperty, isProtected); +ZEND_METHOD(ReflectionProperty, isPrivateSet); +ZEND_METHOD(ReflectionProperty, isProtectedSet); ZEND_METHOD(ReflectionProperty, isStatic); ZEND_METHOD(ReflectionProperty, isReadOnly); ZEND_METHOD(ReflectionProperty, isDefault); @@ -1078,6 +1084,8 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, isPublic, arginfo_class_ReflectionProperty_isPublic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isPrivate, arginfo_class_ReflectionProperty_isPrivate, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isProtected, arginfo_class_ReflectionProperty_isProtected, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isPrivateSet, arginfo_class_ReflectionProperty_isPrivateSet, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isProtectedSet, arginfo_class_ReflectionProperty_isProtectedSet, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isStatic, arginfo_class_ReflectionProperty_isStatic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isReadOnly, arginfo_class_ReflectionProperty_isReadOnly, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isDefault, arginfo_class_ReflectionProperty_isDefault, ZEND_ACC_PUBLIC) @@ -1515,6 +1523,18 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla zend_declare_typed_class_constant(class_entry, const_IS_ABSTRACT_name, &const_IS_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_IS_ABSTRACT_name); + zval const_IS_PROTECTED_SET_value; + ZVAL_LONG(&const_IS_PROTECTED_SET_value, ZEND_ACC_PROTECTED_SET); + zend_string *const_IS_PROTECTED_SET_name = zend_string_init_interned("IS_PROTECTED_SET", sizeof("IS_PROTECTED_SET") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_SET_name, &const_IS_PROTECTED_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IS_PROTECTED_SET_name); + + zval const_IS_PRIVATE_SET_value; + ZVAL_LONG(&const_IS_PRIVATE_SET_value, ZEND_ACC_PRIVATE_SET); + zend_string *const_IS_PRIVATE_SET_name = zend_string_init_interned("IS_PRIVATE_SET", sizeof("IS_PRIVATE_SET") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_SET_name, &const_IS_PRIVATE_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IS_PRIVATE_SET_name); + zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); diff --git a/ext/reflection/tests/ReflectionClass_toString_005.phpt b/ext/reflection/tests/ReflectionClass_toString_005.phpt index 4d4178828cc8e..a43cd96d8b7c8 100644 --- a/ext/reflection/tests/ReflectionClass_toString_005.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_005.phpt @@ -25,8 +25,8 @@ Class [ readonly class Foo ] { } - Properties [2] { - Property [ public readonly int $bar ] - Property [ public readonly int $baz ] + Property [ public protected(set) readonly int $bar ] + Property [ public protected(set) readonly int $baz ] } - Methods [0] { diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt index 21a2bc82d7697..f9c05d2f6e596 100644 --- a/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt +++ b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt @@ -31,7 +31,7 @@ Class [ final class Foo implements UnitEnum ] { } - Properties [1] { - Property [ public readonly string $name ] + Property [ public protected(set) readonly string $name ] } - Methods [0] { diff --git a/ext/reflection/tests/ReflectionEnum_toString.phpt b/ext/reflection/tests/ReflectionEnum_toString.phpt index 00965e7b783c0..91ef587a9a3a4 100644 --- a/ext/reflection/tests/ReflectionEnum_toString.phpt +++ b/ext/reflection/tests/ReflectionEnum_toString.phpt @@ -31,7 +31,7 @@ Class [ final class Foo implements UnitEnum ] { } - Properties [1] { - Property [ public readonly string $name ] + Property [ public protected(set) readonly string $name ] } - Methods [0] { diff --git a/ext/reflection/tests/asymmetric_visibility_flags.phpt b/ext/reflection/tests/asymmetric_visibility_flags.phpt new file mode 100644 index 0000000000000..e6b171d3e765a --- /dev/null +++ b/ext/reflection/tests/asymmetric_visibility_flags.phpt @@ -0,0 +1,34 @@ +--TEST-- +ReflectionProperty::is{Private,Protected}Set +--FILE-- +isPrivateSet()); + var_dump($reflectionProperty->isProtectedSet()); + var_dump(($reflectionProperty->getModifiers() & ReflectionProperty::IS_PRIVATE_SET) !== 0); + var_dump(($reflectionProperty->getModifiers() & ReflectionProperty::IS_PROTECTED_SET) !== 0); + echo $reflectionProperty; +} + +test('bar'); +test('baz'); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +Property [ public private(set) int $bar ] +bool(false) +bool(true) +bool(false) +bool(true) +Property [ public protected(set) int $baz ] diff --git a/ext/reflection/tests/asymmetric_visibility_write.phpt b/ext/reflection/tests/asymmetric_visibility_write.phpt new file mode 100644 index 0000000000000..6a582392fedb6 --- /dev/null +++ b/ext/reflection/tests/asymmetric_visibility_write.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionProperty::is{Private,Protected}Set +--FILE-- +setValue($foo, $i++); + var_dump($reflectionProperty->getValue($foo)); +} + +test('bar'); +test('baz'); + +?> +--EXPECT-- +int(0) +int(1) diff --git a/ext/reflection/tests/readonly_properties.phpt b/ext/reflection/tests/readonly_properties.phpt index 25b3adcca3637..dd1a1a06f2be7 100644 --- a/ext/reflection/tests/readonly_properties.phpt +++ b/ext/reflection/tests/readonly_properties.phpt @@ -25,4 +25,4 @@ bool(false) bool(false) bool(true) bool(true) -Property [ public readonly int $ro ] +Property [ public protected(set) readonly int $ro ] diff --git a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt index d02eeb96477a9..c345ea30b84b4 100644 --- a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt +++ b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt @@ -36,8 +36,8 @@ Class [ class Directory ] { } - Properties [2] { - Property [ public readonly string $path ] - Property [ public readonly mixed $handle ] + Property [ public protected(set) readonly string $path ] + Property [ public protected(set) readonly mixed $handle ] } - Methods [3] { diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index cdaaddecd7bfa..a046ab50e1498 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -92,6 +92,9 @@ char *get_token_type_name(int token_type) case T_PRIVATE: return "T_PRIVATE"; case T_PROTECTED: return "T_PROTECTED"; case T_PUBLIC: return "T_PUBLIC"; + case T_PRIVATE_SET: return "T_PRIVATE_SET"; + case T_PROTECTED_SET: return "T_PROTECTED_SET"; + case T_PUBLIC_SET: return "T_PUBLIC_SET"; case T_READONLY: return "T_READONLY"; case T_VAR: return "T_VAR"; case T_UNSET: return "T_UNSET"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index 81e4e92626f37..45f3c89f2de3a 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -337,6 +337,21 @@ * @cvalue T_PUBLIC */ const T_PUBLIC = UNKNOWN; +/** + * @var int + * @cvalue T_PRIVATE_SET + */ +const T_PRIVATE_SET = UNKNOWN; +/** + * @var int + * @cvalue T_PROTECTED_SET + */ +const T_PROTECTED_SET = UNKNOWN; +/** + * @var int + * @cvalue T_PUBLIC_SET + */ +const T_PUBLIC_SET = UNKNOWN; /** * @var int * @cvalue T_READONLY diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 0fc1f219619dd..61f6ac1ec3659 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b7a13b3b242bd535f62a7d819eb0df751efb54ed */ + * Stub hash: d917cab61a2b436a16d2227cdb438add45e42d69 */ static void register_tokenizer_data_symbols(int module_number) { @@ -70,6 +70,9 @@ static void register_tokenizer_data_symbols(int module_number) REGISTER_LONG_CONSTANT("T_PRIVATE", T_PRIVATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PROTECTED", T_PROTECTED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PUBLIC", T_PUBLIC, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PRIVATE_SET", T_PRIVATE_SET, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PROTECTED_SET", T_PROTECTED_SET, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PUBLIC_SET", T_PUBLIC_SET, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_READONLY", T_READONLY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_VAR", T_VAR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_UNSET", T_UNSET, CONST_PERSISTENT); From 93799629dcf94dd8d9cac56b7df84094cd22bcf5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 27 Aug 2024 02:06:38 +0200 Subject: [PATCH 201/280] [skip ci] Add missing UPGRADING note for a-vis --- UPGRADING | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING b/UPGRADING index 283b82f75ccc5..85d231e10d44d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -267,6 +267,8 @@ PHP 8.4 UPGRADE NOTES namespace block, even if a previous namespace block declared a symbol with the same name. See Zend/tests/use_function/ns_end_resets_seen_symbols_1.phpt. + . Implemented asymmetric property visibility. + RFC: https://wiki.php.net/rfc/asymmetric-visibility-v2 - Curl: . curl_version() returns an additional feature_list value, which is an From cc67220ea357132b83dc2214aceb9ba07ff99912 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 22 Aug 2024 22:41:39 +0100 Subject: [PATCH 202/280] Fixed GH-15547: curl_multi_wait expects a signed int for timeout. confusion might come from the previous argument type. PHP expects ms so we check it fits integer boundaries before the cast. raising a warning at least for stable branches. close GH-15548 --- NEWS | 4 ++++ ext/curl/multi.c | 10 +++++++++- ext/curl/tests/gh15547.phpt | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ext/curl/tests/gh15547.phpt diff --git a/NEWS b/NEWS index 60a17e3cb15be..3be42abdd2b8e 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ PHP NEWS . Fixed bug GH-15587 (CRC32 API build error on arm 32-bit). (Bernd Kuhls, Thomas Petazzoni) +- Curl: + . FIxed bug GH-15547 (curl_multi_select overflow on timeout argument). + (David Carlier) + - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h). (nielsdos) diff --git a/ext/curl/multi.c b/ext/curl/multi.c index e8c32301d2e4d..70cc7e0366410 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -187,7 +187,15 @@ PHP_FUNCTION(curl_multi_select) mh = Z_CURL_MULTI_P(z_mh); - error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds); + if (!(timeout >= 0.0 && timeout <= ((double)INT_MAX / 1000.0))) { + php_error_docref(NULL, E_WARNING, "timeout must be between 0 and %d", (int)ceilf((double)INT_MAX / 1000)); +#ifdef CURLM_BAD_FUNCTION_ARGUMENT + SAVE_CURLM_ERROR(mh, CURLM_BAD_FUNCTION_ARGUMENT); +#endif + RETURN_LONG(-1); + } + + error = curl_multi_wait(mh->multi, NULL, 0, (int) (timeout * 1000.0), &numfds); if (CURLM_OK != error) { SAVE_CURLM_ERROR(mh, error); RETURN_LONG(-1); diff --git a/ext/curl/tests/gh15547.phpt b/ext/curl/tests/gh15547.phpt new file mode 100644 index 0000000000000..bbb1d5c5b0365 --- /dev/null +++ b/ext/curl/tests/gh15547.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-15547 - curl_multi_select overflow on timeout argument +--EXTENSIONS-- +curl +--FILE-- + +--EXPECTF-- +Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d +int(-1) +%s + +Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d +int(-1) +%s +int(0) +string(8) "No error" From 3ed884fab73c5807fe2b3001ee79545c27ad5e70 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 27 Aug 2024 04:59:06 +0100 Subject: [PATCH 203/280] [ci skip] NEWS --- NEWS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/NEWS b/NEWS index 9cba19a8f966d..14845065252fd 100644 --- a/NEWS +++ b/NEWS @@ -22,10 +22,6 @@ PHP NEWS . Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end date). (Mark Bennewitz, Derick) -- Curl: - . FIxed bug GH-15547 (curl_multi_select overflow on timeout argument). - (David Carlier) - - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h). (nielsdos) From 8487ddb8a3342c147a32a9e4be07f1a1af2b2631 Mon Sep 17 00:00:00 2001 From: Simonov Denis Date: Tue, 27 Aug 2024 12:35:04 +0300 Subject: [PATCH 204/280] pdo_firebird: Cleanup code (GH-15510) Since we're requiring fbclient >= 3.0 anyway, we: * Remove unneeded `#if FB_API_VER >= 25`, `#if FB_API_VER >= 30`, `#ifdef SQL_BOOLEAN` * Simplify support for new types for query input parameters. Support force_null for them. * fbclient 3.0+ does not have a limit on the length of a SQL query of 64 KB. The new limit is 10 MB, no one in their right mind would transmit a query of such length. --- ext/pdo_firebird/firebird_driver.c | 66 --------------------------- ext/pdo_firebird/firebird_statement.c | 14 +++--- 2 files changed, 7 insertions(+), 73 deletions(-) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index a044cd6400519..5db0c7f75aa1d 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -463,53 +463,6 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa #if FB_API_VER >= 40 /* set coercing a data type */ -static void set_coercing_input_data_types(XSQLDA* sqlda) -{ - /* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */ - /* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)), */ - /* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. */ - /* This function allows you to ensure minimal performance */ - /* of queries if they contain parameters of the above types. */ - unsigned int i; - short dtype; - short nullable; - XSQLVAR* var; - for (i=0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++) { - dtype = (var->sqltype & ~1); /* drop flag bit */ - nullable = (var->sqltype & 1); - switch(dtype) { - case SQL_INT128: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 46; - var->sqlscale = 0; - break; - - case SQL_DEC16: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 24; - break; - - case SQL_DEC34: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 43; - break; - - case SQL_TIMESTAMP_TZ: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 58; - break; - - case SQL_TIME_TZ: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 46; - break; - - default: - break; - } - } -} - static void set_coercing_output_data_types(XSQLDA* sqlda) { /* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */ @@ -602,14 +555,12 @@ void php_firebird_set_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *state, einfo->errmsg_length = read_len; einfo->errmsg = pestrndup(buf, read_len, dbh->is_persistent); -#if FB_API_VER >= 25 char sqlstate[sizeof(pdo_error_type)]; fb_sqlstate(sqlstate, H->isc_status); if (sqlstate != NULL && strlen(sqlstate) < sizeof(pdo_error_type)) { strcpy(*error_code, sqlstate); goto end; } -#endif } else if (msg && msg_len) { einfo->errmsg_length = msg_len; einfo->errmsg = pestrndup(msg, einfo->errmsg_length, dbh->is_persistent); @@ -730,11 +681,6 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */ if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->in_sqlda)) { break; } - -#if FB_API_VER >= 40 - /* set coercing a data type */ - set_coercing_input_data_types(S->in_sqlda); -#endif } stmt->driver_data = S; @@ -1043,12 +989,6 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; char *new_sql; - /* Firebird allows SQL statements up to 64k, so bail if it doesn't fit */ - if (ZSTR_LEN(sql) > 65536) { - php_firebird_error_with_info(dbh, "01004", strlen("01004"), NULL, 0); - return 0; - } - /* allocate the statement */ if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) { php_firebird_error(dbh); @@ -1333,7 +1273,6 @@ static int pdo_firebird_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) } /* }}} */ -#if FB_API_VER >= 30 /* called by PDO to check liveness */ static zend_result pdo_firebird_check_liveness(pdo_dbh_t *dbh) /* {{{ */ { @@ -1343,7 +1282,6 @@ static zend_result pdo_firebird_check_liveness(pdo_dbh_t *dbh) /* {{{ */ return fb_ping(H->isc_status, &H->db) ? FAILURE : SUCCESS; } /* }}} */ -#endif /* called by PDO to retrieve driver-specific information about an error that has occurred */ static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */ @@ -1383,11 +1321,7 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */ NULL, /* last_id not supported */ pdo_firebird_fetch_error_func, pdo_firebird_get_attribute, -#if FB_API_VER >= 30 pdo_firebird_check_liveness, -#else - NULL, -#endif NULL, /* get driver methods */ NULL, /* request shutdown */ pdo_firebird_in_manually_transaction, diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 5cc8889c65e79..0fbfe77668b57 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -349,11 +349,9 @@ static int pdo_firebird_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, #endif param_type = PDO_PARAM_INT; break; -#ifdef SQL_BOOLEAN case SQL_BOOLEAN: param_type = PDO_PARAM_BOOL; break; -#endif default: param_type = PDO_PARAM_STR; break; @@ -542,11 +540,9 @@ static int pdo_firebird_stmt_get_col( /* TODO: Why is this not returned as the native type? */ ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.16H", php_get_double_from_sqldata(var->sqldata))); break; -#ifdef SQL_BOOLEAN case SQL_BOOLEAN: ZVAL_BOOL(result, *(FB_BOOLEAN*)var->sqldata); break; -#endif case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE*)var->sqldata, &t); fmt = S->H->date_format ? S->H->date_format : PDO_FB_DEF_DATE_FMT; @@ -744,7 +740,6 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param } } -#ifdef SQL_BOOLEAN /* keep native BOOLEAN type */ if ((var->sqltype & ~1) == SQL_BOOLEAN) { switch (Z_TYPE_P(parameter)) { @@ -797,8 +792,6 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param } break; } -#endif - /* check if a NULL should be inserted */ switch (Z_TYPE_P(parameter)) { @@ -829,6 +822,13 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param case SQL_TIMESTAMP: case SQL_TYPE_DATE: case SQL_TYPE_TIME: +#if FB_API_VER >= 40 + case SQL_INT128: + case SQL_DEC16: + case SQL_DEC34: + case SQL_TIMESTAMP_TZ: + case SQL_TIME_TZ: +#endif force_null = (Z_STRLEN_P(parameter) == 0); } if (!force_null) { From 8f3dc78da15d8ea44d726501b55aded3c29df51e Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 27 Aug 2024 23:19:37 +0900 Subject: [PATCH 205/280] [ci skip] Update NEWS for PHP 8.4.0 beta4 --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 14845065252fd..1fc145b8c3ab8 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.4.0beta4 +?? ??? ????, PHP 8.4.0beta5 + + +27 Aug 2024, PHP 8.4.0beta4 - Core: . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). From c4ae645849839b4aa7d9f2948a05d482d3bfbd45 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 27 Aug 2024 05:08:07 +0100 Subject: [PATCH 206/280] Follow-up on GH-15548: curl_multi_select. throws a ValueError on timeout overflow. close GH-15594 --- UPGRADING | 4 ++++ ext/curl/multi.c | 7 ++----- ext/curl/tests/gh15547.phpt | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/UPGRADING b/UPGRADING index 85d231e10d44d..9fe39234e0e0c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -574,6 +574,10 @@ PHP 8.4 UPGRADE NOTES . trigger_error() and user_error() now have a return type of true instead of bool. +- Curl: + . curl_multi_select throws a ValueError if the timeout argument if it's negative + or greater than PHP_INT_MAX. + - DOM: . DOMDocument::registerNodeClass() now has a tentative return type of true. Previously, the return type was bool but only true could be returned in practice. diff --git a/ext/curl/multi.c b/ext/curl/multi.c index a586571f7bf3f..275de581ae106 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -188,11 +188,8 @@ PHP_FUNCTION(curl_multi_select) mh = Z_CURL_MULTI_P(z_mh); if (!(timeout >= 0.0 && timeout <= ((double)INT_MAX / 1000.0))) { - php_error_docref(NULL, E_WARNING, "timeout must be between 0 and %d", (int)ceilf((double)INT_MAX / 1000)); -#ifdef CURLM_BAD_FUNCTION_ARGUMENT - SAVE_CURLM_ERROR(mh, CURLM_BAD_FUNCTION_ARGUMENT); -#endif - RETURN_LONG(-1); + zend_argument_value_error(2, "must be between 0 and %d", (int)ceilf((double)INT_MAX / 1000)); + RETURN_THROWS(); } error = curl_multi_wait(mh->multi, NULL, 0, (int) (timeout * 1000.0), &numfds); diff --git a/ext/curl/tests/gh15547.phpt b/ext/curl/tests/gh15547.phpt index bbb1d5c5b0365..cee3f00cdb9f8 100644 --- a/ext/curl/tests/gh15547.phpt +++ b/ext/curl/tests/gh15547.phpt @@ -6,24 +6,24 @@ curl getMessage() . PHP_EOL; +} curl_multi_close($mh); $mh = curl_multi_init(); -var_dump(curl_multi_select($mh, 2500000)); -var_dump(curl_multi_strerror(curl_multi_errno($mh))); +try { + curl_multi_select($mh, 2500000); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} curl_multi_close($mh); $mh = curl_multi_init(); var_dump(curl_multi_select($mh, 1000000)); -var_dump(curl_multi_strerror(curl_multi_errno($mh))); ?> --EXPECTF-- -Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d -int(-1) -%s - -Warning: curl_multi_select(): timeout must be between 0 and %d in %s on line %d -int(-1) -%s +curl_multi_select(): Argument #2 ($timeout) must be between %d and %d +curl_multi_select(): Argument #2 ($timeout) must be between %d and %d int(0) -string(8) "No error" From f0f1724fb96ab95e73021cccc90aef910d194dfd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 27 Aug 2024 21:11:54 +0300 Subject: [PATCH 207/280] Remove unintended ZEND_EXT_API usage (#15602) --- ext/opcache/jit/zend_jit.c | 28 ++++++++++++++-------------- ext/opcache/jit/zend_jit.h | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 379a5122217d1..0499225de7388 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -706,7 +706,7 @@ static bool zend_may_be_dynamic_property(zend_class_entry *ce, zend_string *memb # endif #endif -ZEND_EXT_API void zend_jit_status(zval *ret) +void zend_jit_status(zval *ret) { zval stats; array_init(&stats); @@ -3046,7 +3046,7 @@ static int zend_jit_setup_hot_counters(zend_op_array *op_array) #include "jit/zend_jit_trace.c" -ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) +int zend_jit_op_array(zend_op_array *op_array, zend_script *script) { if (dasm_ptr == NULL) { return FAILURE; @@ -3123,7 +3123,7 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) return FAILURE; } -ZEND_EXT_API int zend_jit_script(zend_script *script) +int zend_jit_script(zend_script *script) { void *checkpoint; zend_call_graph call_graph; @@ -3235,7 +3235,7 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) return FAILURE; } -ZEND_EXT_API void zend_jit_unprotect(void) +void zend_jit_unprotect(void) { #ifdef HAVE_MPROTECT if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3270,7 +3270,7 @@ ZEND_EXT_API void zend_jit_unprotect(void) #endif } -ZEND_EXT_API void zend_jit_protect(void) +void zend_jit_protect(void) { #ifdef HAVE_MPROTECT if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3362,7 +3362,7 @@ static int zend_jit_parse_config_num(zend_long jit) return SUCCESS; } -ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) +int zend_jit_config(zend_string *jit, int stage) { if (stage != ZEND_INI_STAGE_STARTUP && !JIT_G(enabled)) { if (stage == ZEND_INI_STAGE_RUNTIME) { @@ -3418,7 +3418,7 @@ ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) return FAILURE; } -ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) +int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) { if (stage != ZEND_INI_STAGE_STARTUP) { if (((old_val ^ new_val) & ZEND_JIT_DEBUG_PERSISTENT) != 0) { @@ -3431,7 +3431,7 @@ ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int return SUCCESS; } -ZEND_EXT_API void zend_jit_init(void) +void zend_jit_init(void) { #ifdef ZTS jit_globals_id = ts_allocate_id(&jit_globals_id, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); @@ -3440,7 +3440,7 @@ ZEND_EXT_API void zend_jit_init(void) #endif } -ZEND_EXT_API int zend_jit_check_support(void) +int zend_jit_check_support(void) { int i; @@ -3499,7 +3499,7 @@ ZEND_EXT_API int zend_jit_check_support(void) return SUCCESS; } -ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) +void zend_jit_startup(void *buf, size_t size, bool reattached) { zend_jit_halt_op = zend_get_halt_op(); zend_jit_profile_counter_rid = zend_get_op_array_extension_handle(ACCELERATOR_PRODUCT_NAME); @@ -3582,7 +3582,7 @@ ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) zend_jit_protect(); } -ZEND_EXT_API void zend_jit_shutdown(void) +void zend_jit_shutdown(void) { 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)); @@ -3606,7 +3606,7 @@ static void zend_jit_reset_counters(void) } } -ZEND_EXT_API void zend_jit_activate(void) +void zend_jit_activate(void) { zend_jit_profile_counter = 0; if (JIT_G(on)) { @@ -3619,7 +3619,7 @@ ZEND_EXT_API void zend_jit_activate(void) } } -ZEND_EXT_API void zend_jit_deactivate(void) +void zend_jit_deactivate(void) { if (zend_jit_profile_counter && !CG(unclean_shutdown)) { zend_class_entry *ce; @@ -3702,7 +3702,7 @@ static void zend_jit_restart_preloaded_script(zend_persistent_script *script) } ZEND_HASH_FOREACH_END(); } -ZEND_EXT_API void zend_jit_restart(void) +void zend_jit_restart(void) { if (dasm_buf) { zend_jit_unprotect(); diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 99940cf684ed9..1e0176a4f4f55 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -150,20 +150,20 @@ extern int jit_globals_id; extern zend_jit_globals jit_globals; #endif -ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script); -ZEND_EXT_API int zend_jit_script(zend_script *script); -ZEND_EXT_API void zend_jit_unprotect(void); -ZEND_EXT_API void zend_jit_protect(void); -ZEND_EXT_API void zend_jit_init(void); -ZEND_EXT_API int zend_jit_config(zend_string *jit_options, int stage); -ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage); -ZEND_EXT_API int zend_jit_check_support(void); -ZEND_EXT_API void zend_jit_startup(void *jit_buffer, size_t size, bool reattached); -ZEND_EXT_API void zend_jit_shutdown(void); -ZEND_EXT_API void zend_jit_activate(void); -ZEND_EXT_API void zend_jit_deactivate(void); -ZEND_EXT_API void zend_jit_status(zval *ret); -ZEND_EXT_API void zend_jit_restart(void); +int zend_jit_op_array(zend_op_array *op_array, zend_script *script); +int zend_jit_script(zend_script *script); +void zend_jit_unprotect(void); +void zend_jit_protect(void); +void zend_jit_init(void); +int zend_jit_config(zend_string *jit_options, int stage); +int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage); +int zend_jit_check_support(void); +void zend_jit_startup(void *jit_buffer, size_t size, bool reattached); +void zend_jit_shutdown(void); +void zend_jit_activate(void); +void zend_jit_deactivate(void); +void zend_jit_status(zval *ret); +void zend_jit_restart(void); #define ZREG_LOAD (1<<0) #define ZREG_STORE (1<<1) From eb87de1c87476a2887d23191af500a6f97dc99d1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 27 Aug 2024 21:12:29 +0300 Subject: [PATCH 208/280] Fix GH-15502: Crash with JIT and Excimer (#15601) --- ext/opcache/jit/zend_jit_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index ccf018493e780..e599c335b1b69 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -6959,7 +6959,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par for (i = 0; i < op_array->last_var + op_array->T; i++) { SET_STACK_TYPE(stack, i, IS_UNKNOWN, 1); } - exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + exit_point = zend_jit_trace_get_exit_point(zend_jit_traces[t->link].opline, ZEND_JIT_EXIT_TO_VM); timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!timeout_exit_addr) { goto jit_failure; From 88393cfaf7fc6af86675a9c199210d3298cb8150 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:04:26 +0200 Subject: [PATCH 209/280] Fix GH-13988: Storing DOMElement consume 4 times more memory in PHP 8.1 than in PHP 8.0 We avoid creating backing storage by using the feature introduced in f78d5cfcd2fe06ddd6da33ff880c6823072adc1b. Closes GH-15593. --- NEWS | 3 + UPGRADING | 1 + ext/dom/element.c | 2 +- ext/dom/html_document.c | 2 +- ext/dom/php_dom.stub.php | 686 +++++++++++++++++++++++++++------- ext/dom/php_dom_arginfo.h | 360 +++++++++--------- ext/dom/tests/bug69846.phpt | 12 +- ext/dom/tests/bug80602_3.phpt | 8 +- 8 files changed, 750 insertions(+), 324 deletions(-) diff --git a/NEWS b/NEWS index 1fc145b8c3ab8..dfc0f55e023a1 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.0beta5 +- DOM: + . Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in + PHP 8.1 than in PHP 8.0). (nielsdos) 27 Aug 2024, PHP 8.4.0beta4 diff --git a/UPGRADING b/UPGRADING index 9fe39234e0e0c..9b16369e3e8e6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -1083,6 +1083,7 @@ PHP 8.4 UPGRADE NOTES an xpath query. This can give a time improvement of easily two order of magnitude for documents with tens of thousands of nodes. . Improved performance and reduce memory consumption of XML serialization. + . Reduced memory usage of node classes. - FTP: . Improved the performance of FTP uploads up to a factor of 10x for large diff --git a/ext/dom/element.c b/ext/dom/element.c index 75c772fa2c306..b449555983021 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -182,7 +182,7 @@ URL: https://dom.spec.whatwg.org/#dom-element-classlist */ zend_result dom_element_class_list_read(dom_object *obj, zval *retval) { - const uint32_t PROP_INDEX = 20; + const uint32_t PROP_INDEX = 0; #if ZEND_DEBUG zend_string *class_list_str = ZSTR_INIT_LITERAL("classList", false); diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 55d9fdfe45028..1d606e814554f 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -83,7 +83,7 @@ typedef struct dom_decoding_encoding_ctx { /* https://dom.spec.whatwg.org/#dom-document-implementation */ zend_result dom_modern_document_implementation_read(dom_object *obj, zval *retval) { - const uint32_t PROP_INDEX = 14; + const uint32_t PROP_INDEX = 0; #if ZEND_DEBUG zend_string *implementation_str = ZSTR_INIT_LITERAL("implementation", false); diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index 48d28a3269618..0f7f748410420 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -234,22 +234,40 @@ class DOMDocumentType extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNamedNodeMap $entities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNamedNodeMap $notations; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $internalSubset; } @@ -298,55 +316,103 @@ class DOMNode public const int DOCUMENT_POSITION_CONTAINED_BY = 0x10; public const int DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; + /** @virtual */ public ?string $nodeValue; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $parentElement; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNodeList $childNodes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $firstChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $lastChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $previousSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $nextSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNamedNodeMap $attributes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocument $ownerDocument; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; + /** @virtual */ public string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $baseURI; + /** @virtual */ public string $textContent; /** @return DOMNode|false */ @@ -415,34 +481,64 @@ public function __wakeup(): void {} class DOMNameSpaceNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $nodeValue; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocument $ownerDocument; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $parentElement; /** @implementation-alias DOMNode::__sleep */ @@ -466,13 +562,22 @@ public function createDocument(?string $namespace = null, string $qualifiedName class DOMDocumentFragment extends DOMNode implements DOMParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; public function __construct() {} @@ -501,7 +606,10 @@ public function replaceChildren(...$nodes): void {} class DOMNodeList implements IteratorAggregate, Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @tentative-return-type */ @@ -515,15 +623,25 @@ public function item(int $index) {} class DOMCharacterData extends DOMNode implements DOMChildNode { + /** @virtual */ public string $data; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $nextElementSibling; /** @tentative-return-type */ @@ -565,19 +683,32 @@ public function after(...$nodes): void {} class DOMAttr extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ - public bool $specified = true; + /** + * @readonly + * @virtual + */ + public bool $specified; + /** @virtual */ public string $value; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $ownerElement; - /** @readonly */ - public mixed $schemaTypeInfo = null; + /** + * @readonly + * @virtual + */ + public mixed $schemaTypeInfo; public function __construct(string $name, string $value = "") {} @@ -587,29 +718,52 @@ public function isId(): bool {} class DOMElement extends DOMNode implements \DOMParentNode, \DOMChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $tagName; + /** @virtual */ public string $className; + /** @virtual */ public string $id; - /** @readonly */ - public mixed $schemaTypeInfo = null; + /** + * @readonly + * @virtual + */ + public mixed $schemaTypeInfo; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $nextElementSibling; public function __construct(string $qualifiedName, ?string $value = null, string $namespace = "") {} @@ -699,63 +853,99 @@ public function insertAdjacentText(string $where, string $data): void {} class DOMDocument extends DOMNode implements DOMParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocumentType $doctype; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMImplementation $implementation; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $documentElement; /** * @readonly * @deprecated + * @virtual */ public ?string $actualEncoding; + /** @virtual */ public ?string $encoding; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $xmlEncoding; + /** @virtual */ public bool $standalone; + /** @virtual */ public bool $xmlStandalone; + /** @virtual */ public ?string $version; + /** @virtual */ public ?string $xmlVersion; + /** @virtual */ public bool $strictErrorChecking; + /** @virtual */ public ?string $documentURI; /** * @readonly * @deprecated + * @virtual */ public mixed $config; + /** @virtual */ public bool $formatOutput; + /** @virtual */ public bool $validateOnParse; + /** @virtual */ public bool $resolveExternals; + /** @virtual */ public bool $preserveWhiteSpace; + /** @virtual */ public bool $recover; + /** @virtual */ public bool $substituteEntities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; public function __construct(string $version = "1.0", string $encoding = "") {} @@ -891,7 +1081,10 @@ final class DOMException extends Exception class DOMText extends DOMCharacterData { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $wholeText; public function __construct(string $data = "") {} @@ -911,7 +1104,10 @@ public function splitText(int $offset) {} class DOMNamedNodeMap implements IteratorAggregate, Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @tentative-return-type */ @@ -931,32 +1127,44 @@ public function getIterator(): Iterator {} class DOMEntity extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $notationName; /** * @readonly * @deprecated + * @virtual */ - public ?string $actualEncoding = null; + public ?string $actualEncoding; /** * @readonly * @deprecated + * @virtual */ - public ?string $encoding = null; + public ?string $encoding; /** * @readonly * @deprecated + * @virtual */ - public ?string $version = null; + public ?string $version; } class DOMEntityReference extends DOMNode @@ -966,18 +1174,28 @@ public function __construct(string $name) {} class DOMNotation extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; } class DOMProcessingInstruction extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $target; + /** @virtual */ public string $data; public function __construct(string $name, string $value = "") {} @@ -987,9 +1205,13 @@ public function __construct(string $name, string $value = "") {} /** @not-serializable */ class DOMXPath { - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMDocument $document; + /** @virtual */ public bool $registerNodeNamespaces; public function __construct(DOMDocument $document, bool $registerNodeNS = true) {} @@ -1135,39 +1357,77 @@ class Node { private final function __construct() {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $baseURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Document $ownerDocument; /** @implementation-alias DOMNode::getRootNode */ public function getRootNode(array $options = []): Node {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $parentElement; /** @implementation-alias DOMNode::hasChildNodes */ public function hasChildNodes(): bool {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public NodeList $childNodes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $firstChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $lastChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $previousSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $nextSibling; + /** @virtual */ public ?string $nodeValue; + /** @virtual */ public ?string $textContent; /** @implementation-alias DOMNode::normalize */ public function normalize(): void {} @@ -1213,7 +1473,10 @@ public function __wakeup(): void {} class NodeList implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNodeList::count */ @@ -1228,7 +1491,10 @@ public function item(int $index): ?Node {} class NamedNodeMap implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNamedNodeMap::item */ @@ -1247,7 +1513,10 @@ public function getIterator(): \Iterator {} class DtdNamedNodeMap implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNamedNodeMap::item */ @@ -1266,7 +1535,10 @@ public function getIterator(): \Iterator {} class HTMLCollection implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNodeList::item */ @@ -1291,23 +1563,40 @@ enum AdjacentPosition : string class Element extends Node implements ParentNode, ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $tagName; + /** @virtual */ public string $id; + /** @virtual */ public string $className; /** @readonly */ public TokenList $classList; /** @implementation-alias DOMNode::hasAttributes */ public function hasAttributes(): bool {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public NamedNodeMap $attributes; /** @implementation-alias DOMElement::getAttributeNames */ public function getAttributeNames(): array {} @@ -1344,15 +1633,30 @@ public function getElementsByTagNameNS(?string $namespace, string $localName): H public function insertAdjacentElement(AdjacentPosition $where, Element $element): ?Element {} public function insertAdjacentText(AdjacentPosition $where, string $data): void {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $nextElementSibling; /** @implementation-alias DOMElement::setIdAttribute */ @@ -1381,8 +1685,10 @@ public function querySelectorAll(string $selectors): NodeList {} public function closest(string $selectors): ?Element {} public function matches(string $selectors): bool {} + /** @virtual */ public string $innerHTML; + /** @virtual */ public string $substitutedNodeValue; /** @return list */ @@ -1400,21 +1706,40 @@ class HTMLElement extends Element class Attr extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; + /** @virtual */ public string $value; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $ownerElement; - /** @readonly */ - public bool $specified = true; + /** + * @readonly + * @virtual + */ + public bool $specified; /** @implementation-alias DOMAttr::isId */ public function isId(): bool {} @@ -1425,13 +1750,23 @@ public function rename(?string $namespaceURI, string $qualifiedName): void {} class CharacterData extends Node implements ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $nextElementSibling; + /** @virtual */ public string $data; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMCharacterData::substringData */ public function substringData(int $offset, int $count): string {} @@ -1456,7 +1791,10 @@ class Text extends CharacterData /** @implementation-alias DOMText::splitText */ public function splitText(int $offset): Text {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $wholeText; } @@ -1464,7 +1802,10 @@ class CDATASection extends Text {} class ProcessingInstruction extends CharacterData { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $target; } @@ -1475,17 +1816,35 @@ class Comment extends CharacterData class DocumentType extends Node implements ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DtdNamedNodeMap $entities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DtdNamedNodeMap $notations; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $internalSubset; /** @implementation-alias DOMElement::remove */ @@ -1500,11 +1859,20 @@ public function replaceWith(Node|string ...$nodes): void {} class DocumentFragment extends Node implements ParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; /** @implementation-alias DOMDocumentFragment::appendXML */ @@ -1524,11 +1892,20 @@ public function querySelectorAll(string $selectors): NodeList {} class Entity extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $notationName; } @@ -1536,9 +1913,15 @@ class EntityReference extends Node {} class Notation extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; } @@ -1546,15 +1929,26 @@ abstract class Document extends Node implements ParentNode { /** @readonly */ public Implementation $implementation; + /** @virtual */ public string $URL; + /** @virtual */ public string $documentURI; + /** @virtual */ public string $characterSet; + /** @virtual */ public string $charset; + /** @virtual */ public string $inputEncoding; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DocumentType $doctype; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $documentElement; /** @implementation-alias Dom\Element::getElementsByTagName */ public function getElementsByTagName(string $qualifiedName): HTMLCollection {} @@ -1581,11 +1975,20 @@ public function createAttribute(string $localName): Attr {} /** @implementation-alias DOMDocument::createAttributeNS */ public function createAttributeNS(?string $namespace, string $qualifiedName): Attr {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; /** @implementation-alias DOMDocument::getElementById */ @@ -1618,9 +2021,14 @@ public function querySelector(string $selectors): ?Element {} /** @implementation-alias Dom\Element::querySelectorAll */ public function querySelectorAll(string $selectors): NodeList {} + /** @virtual */ public ?HTMLElement $body; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?HTMLElement $head; + /** @virtual */ public string $title; } @@ -1655,13 +2063,19 @@ public static function createFromFile(string $path, int $options = 0, ?string $o public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): XMLDocument {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $xmlEncoding; + /** @virtual */ public bool $xmlStandalone; + /** @virtual */ public string $xmlVersion; + /** @virtual */ public bool $formatOutput; /** @implementation-alias DOMDocument::createEntityReference */ @@ -1687,7 +2101,10 @@ final class TokenList implements IteratorAggregate, Countable /** @implementation-alias Dom\Node::__construct */ private function __construct() {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; public function item(int $index): ?string {} public function contains(string $token): bool {} @@ -1696,6 +2113,7 @@ public function remove(string ...$tokens): void {} public function toggle(string $token, ?bool $force = null): bool {} public function replace(string $token, string $newToken): bool {} public function supports(string $token): bool {} + /** @virtual */ public string $value; public function count(): int {} @@ -1721,9 +2139,13 @@ private function __construct() {} /** @not-serializable */ final class XPath { - /** @readonly */ + /** + * @readonly + * @virtual + */ public Document $document; + /** @virtual */ public bool $registerNodeNamespaces; public function __construct(Document $document, bool $registerNodeNS = true) {} diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index c87020e700942..7839671b14b23 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 085c060d5a6f3d0c3db1cdbe5c5a3ec4ca261d5c */ + * Stub hash: b79ad2b70757f7d65a6b4fd907222a4955264bf6 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 0) ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0) @@ -2011,39 +2011,39 @@ static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_ zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_entities_default_value; ZVAL_UNDEF(&property_entities_default_value); zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, 1); zend_string *property_entities_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0)); zend_string_release(property_entities_name); zval property_notations_default_value; ZVAL_UNDEF(&property_notations_default_value); zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, 1); zend_string *property_notations_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0)); zend_string_release(property_notations_name); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); zval property_internalSubset_default_value; ZVAL_UNDEF(&property_internalSubset_default_value); zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, 1); - zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_internalSubset_name); return class_entry; @@ -2135,118 +2135,118 @@ static zend_class_entry *register_class_DOMNode(void) zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); zval property_childNodes_default_value; ZVAL_UNDEF(&property_childNodes_default_value); zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, 1); zend_string *property_childNodes_class_DOMNodeList = zend_string_init("DOMNodeList", sizeof("DOMNodeList")-1, 1); - zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0)); + zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0)); zend_string_release(property_childNodes_name); zval property_firstChild_default_value; ZVAL_UNDEF(&property_firstChild_default_value); zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, 1); zend_string *property_firstChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_firstChild_name); zval property_lastChild_default_value; ZVAL_UNDEF(&property_lastChild_default_value); zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, 1); zend_string *property_lastChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_lastChild_name); zval property_previousSibling_default_value; ZVAL_UNDEF(&property_previousSibling_default_value); zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, 1); zend_string *property_previousSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_previousSibling_name); zval property_nextSibling_default_value; ZVAL_UNDEF(&property_nextSibling_default_value); zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, 1); zend_string *property_nextSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_nextSibling_name); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_string *property_attributes_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL)); zend_string_release(property_attributes_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_localName_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_baseURI_name); zval property_textContent_default_value; ZVAL_UNDEF(&property_textContent_default_value); zend_string *property_textContent_name = zend_string_init("textContent", sizeof("textContent") - 1, 1); - zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_textContent_name); return class_entry; @@ -2262,64 +2262,64 @@ static zend_class_entry *register_class_DOMNameSpaceNode(void) zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_localName_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); return class_entry; @@ -2347,20 +2347,20 @@ static zend_class_entry *register_class_DOMDocumentFragment(zend_class_entry *cl ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -2377,7 +2377,7 @@ static zend_class_entry *register_class_DOMNodeList(zend_class_entry *class_entr zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -2394,27 +2394,27 @@ static zend_class_entry *register_class_DOMCharacterData(zend_class_entry *class zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); return class_entry; @@ -2430,32 +2430,32 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_specified_default_value; - ZVAL_TRUE(&property_specified_default_value); + ZVAL_UNDEF(&property_specified_default_value); zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, 1); - zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_specified_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_ownerElement_default_value; ZVAL_UNDEF(&property_ownerElement_default_value); zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, 1); zend_string *property_ownerElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_ownerElement_name); zval property_schemaTypeInfo_default_value; - ZVAL_NULL(&property_schemaTypeInfo_default_value); + ZVAL_UNDEF(&property_schemaTypeInfo_default_value); zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, 1); - zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_schemaTypeInfo_name); return class_entry; @@ -2472,59 +2472,59 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry zval property_tagName_default_value; ZVAL_UNDEF(&property_tagName_default_value); zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, 1); - zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_tagName_name); zval property_className_default_value; ZVAL_UNDEF(&property_className_default_value); zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); - zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_className_name); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); - zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_id_name); zval property_schemaTypeInfo_default_value; - ZVAL_NULL(&property_schemaTypeInfo_default_value); + ZVAL_UNDEF(&property_schemaTypeInfo_default_value); zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, 1); - zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_schemaTypeInfo_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); return class_entry; @@ -2542,137 +2542,137 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr ZVAL_UNDEF(&property_doctype_default_value); zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1); zend_string *property_doctype_class_DOMDocumentType = zend_string_init("DOMDocumentType", sizeof("DOMDocumentType")-1, 1); - zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL)); zend_string_release(property_doctype_name); zval property_implementation_default_value; ZVAL_UNDEF(&property_implementation_default_value); zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, 1); zend_string *property_implementation_class_DOMImplementation = zend_string_init("DOMImplementation", sizeof("DOMImplementation")-1, 1); - zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0)); + zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0)); zend_string_release(property_implementation_name); zval property_documentElement_default_value; ZVAL_UNDEF(&property_documentElement_default_value); zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1); zend_string *property_documentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_documentElement_name); zval property_actualEncoding_default_value; ZVAL_UNDEF(&property_actualEncoding_default_value); zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_actualEncoding_name); zval property_encoding_default_value; ZVAL_UNDEF(&property_encoding_default_value); zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1); - zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_encoding_name); zval property_xmlEncoding_default_value; ZVAL_UNDEF(&property_xmlEncoding_default_value); zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_xmlEncoding_name); zval property_standalone_default_value; ZVAL_UNDEF(&property_standalone_default_value); zend_string *property_standalone_name = zend_string_init("standalone", sizeof("standalone") - 1, 1); - zend_declare_typed_property(class_entry, property_standalone_name, &property_standalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_standalone_name, &property_standalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_standalone_name); zval property_xmlStandalone_default_value; ZVAL_UNDEF(&property_xmlStandalone_default_value); zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_xmlStandalone_name); zval property_version_default_value; ZVAL_UNDEF(&property_version_default_value); zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_version_name); zval property_xmlVersion_default_value; ZVAL_UNDEF(&property_xmlVersion_default_value); zend_string *property_xmlVersion_name = zend_string_init("xmlVersion", sizeof("xmlVersion") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_xmlVersion_name); zval property_strictErrorChecking_default_value; ZVAL_UNDEF(&property_strictErrorChecking_default_value); zend_string *property_strictErrorChecking_name = zend_string_init("strictErrorChecking", sizeof("strictErrorChecking") - 1, 1); - zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_strictErrorChecking_name); zval property_documentURI_default_value; ZVAL_UNDEF(&property_documentURI_default_value); zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1); - zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_documentURI_name); zval property_config_default_value; ZVAL_UNDEF(&property_config_default_value); zend_string *property_config_name = zend_string_init("config", sizeof("config") - 1, 1); - zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_config_name); zval property_formatOutput_default_value; ZVAL_UNDEF(&property_formatOutput_default_value); zend_string *property_formatOutput_name = zend_string_init("formatOutput", sizeof("formatOutput") - 1, 1); - zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_formatOutput_name); zval property_validateOnParse_default_value; ZVAL_UNDEF(&property_validateOnParse_default_value); zend_string *property_validateOnParse_name = zend_string_init("validateOnParse", sizeof("validateOnParse") - 1, 1); - zend_declare_typed_property(class_entry, property_validateOnParse_name, &property_validateOnParse_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_validateOnParse_name, &property_validateOnParse_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_validateOnParse_name); zval property_resolveExternals_default_value; ZVAL_UNDEF(&property_resolveExternals_default_value); zend_string *property_resolveExternals_name = zend_string_init("resolveExternals", sizeof("resolveExternals") - 1, 1); - zend_declare_typed_property(class_entry, property_resolveExternals_name, &property_resolveExternals_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_resolveExternals_name, &property_resolveExternals_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_resolveExternals_name); zval property_preserveWhiteSpace_default_value; ZVAL_UNDEF(&property_preserveWhiteSpace_default_value); zend_string *property_preserveWhiteSpace_name = zend_string_init("preserveWhiteSpace", sizeof("preserveWhiteSpace") - 1, 1); - zend_declare_typed_property(class_entry, property_preserveWhiteSpace_name, &property_preserveWhiteSpace_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_preserveWhiteSpace_name, &property_preserveWhiteSpace_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_preserveWhiteSpace_name); zval property_recover_default_value; ZVAL_UNDEF(&property_recover_default_value); zend_string *property_recover_name = zend_string_init("recover", sizeof("recover") - 1, 1); - zend_declare_typed_property(class_entry, property_recover_name, &property_recover_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_recover_name, &property_recover_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_recover_name); zval property_substituteEntities_default_value; ZVAL_UNDEF(&property_substituteEntities_default_value); zend_string *property_substituteEntities_name = zend_string_init("substituteEntities", sizeof("substituteEntities") - 1, 1); - zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_substituteEntities_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -2705,7 +2705,7 @@ static zend_class_entry *register_class_DOMText(zend_class_entry *class_entry_DO zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, 1); - zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_wholeText_name); return class_entry; @@ -2722,7 +2722,7 @@ static zend_class_entry *register_class_DOMNamedNodeMap(zend_class_entry *class_ zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -2738,37 +2738,37 @@ static zend_class_entry *register_class_DOMEntity(zend_class_entry *class_entry_ zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_systemId_name); zval property_notationName_default_value; ZVAL_UNDEF(&property_notationName_default_value); zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, 1); - zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_notationName_name); zval property_actualEncoding_default_value; - ZVAL_NULL(&property_actualEncoding_default_value); + ZVAL_UNDEF(&property_actualEncoding_default_value); zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_actualEncoding_name); zval property_encoding_default_value; - ZVAL_NULL(&property_encoding_default_value); + ZVAL_UNDEF(&property_encoding_default_value); zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1); - zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_encoding_name); zval property_version_default_value; - ZVAL_NULL(&property_version_default_value); + ZVAL_UNDEF(&property_version_default_value); zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_version_name); return class_entry; @@ -2794,13 +2794,13 @@ static zend_class_entry *register_class_DOMNotation(zend_class_entry *class_entr zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); return class_entry; @@ -2816,13 +2816,13 @@ static zend_class_entry *register_class_DOMProcessingInstruction(zend_class_entr zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, 1); - zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_target_name); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); return class_entry; @@ -2840,13 +2840,13 @@ static zend_class_entry *register_class_DOMXPath(void) ZVAL_UNDEF(&property_document_default_value); zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1); zend_string *property_document_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0)); + zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0)); zend_string_release(property_document_name); zval property_registerNodeNamespaces_default_value; ZVAL_UNDEF(&property_registerNodeNamespaces_default_value); zend_string *property_registerNodeNamespaces_name = zend_string_init("registerNodeNamespaces", sizeof("registerNodeNamespaces") - 1, 1); - zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_registerNodeNamespaces_name); return class_entry; @@ -2929,93 +2929,93 @@ static zend_class_entry *register_class_Dom_Node(void) zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_baseURI_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); zval property_childNodes_default_value; ZVAL_UNDEF(&property_childNodes_default_value); zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, 1); zend_string *property_childNodes_class_Dom_NodeList = zend_string_init("Dom\\\116odeList", sizeof("Dom\\\116odeList")-1, 1); - zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0)); + zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0)); zend_string_release(property_childNodes_name); zval property_firstChild_default_value; ZVAL_UNDEF(&property_firstChild_default_value); zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, 1); zend_string *property_firstChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_firstChild_name); zval property_lastChild_default_value; ZVAL_UNDEF(&property_lastChild_default_value); zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, 1); zend_string *property_lastChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_lastChild_name); zval property_previousSibling_default_value; ZVAL_UNDEF(&property_previousSibling_default_value); zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, 1); zend_string *property_previousSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_previousSibling_name); zval property_nextSibling_default_value; ZVAL_UNDEF(&property_nextSibling_default_value); zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, 1); zend_string *property_nextSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_nextSibling_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_textContent_default_value; ZVAL_UNDEF(&property_textContent_default_value); zend_string *property_textContent_name = zend_string_init("textContent", sizeof("textContent") - 1, 1); - zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_textContent_name); return class_entry; @@ -3032,7 +3032,7 @@ static zend_class_entry *register_class_Dom_NodeList(zend_class_entry *class_ent zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3049,7 +3049,7 @@ static zend_class_entry *register_class_Dom_NamedNodeMap(zend_class_entry *class zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3066,7 +3066,7 @@ static zend_class_entry *register_class_Dom_DtdNamedNodeMap(zend_class_entry *cl zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3083,7 +3083,7 @@ static zend_class_entry *register_class_Dom_HTMLCollection(zend_class_entry *cla zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3127,37 +3127,37 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_tagName_default_value; ZVAL_UNDEF(&property_tagName_default_value); zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, 1); - zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_tagName_name); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); - zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_id_name); zval property_className_default_value; ZVAL_UNDEF(&property_className_default_value); zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); - zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_className_name); zval property_classList_default_value; @@ -3171,53 +3171,53 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr ZVAL_UNDEF(&property_attributes_default_value); zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_string *property_attributes_class_Dom_NamedNodeMap = zend_string_init("Dom\\\116amedNodeMap", sizeof("Dom\\\116amedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); zend_string_release(property_attributes_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); zval property_innerHTML_default_value; ZVAL_UNDEF(&property_innerHTML_default_value); zend_string *property_innerHTML_name = zend_string_init("innerHTML", sizeof("innerHTML") - 1, 1); - zend_declare_typed_property(class_entry, property_innerHTML_name, &property_innerHTML_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_innerHTML_name, &property_innerHTML_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_innerHTML_name); zval property_substitutedNodeValue_default_value; ZVAL_UNDEF(&property_substitutedNodeValue_default_value); zend_string *property_substitutedNodeValue_name = zend_string_init("substitutedNodeValue", sizeof("substitutedNodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_substitutedNodeValue_name, &property_substitutedNodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_substitutedNodeValue_name, &property_substitutedNodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_substitutedNodeValue_name); return class_entry; @@ -3243,44 +3243,44 @@ static zend_class_entry *register_class_Dom_Attr(zend_class_entry *class_entry_D zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_ownerElement_default_value; ZVAL_UNDEF(&property_ownerElement_default_value); zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, 1); zend_string *property_ownerElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_ownerElement_name); zval property_specified_default_value; - ZVAL_TRUE(&property_specified_default_value); + ZVAL_UNDEF(&property_specified_default_value); zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, 1); - zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_specified_name); return class_entry; @@ -3298,26 +3298,26 @@ static zend_class_entry *register_class_Dom_CharacterData(zend_class_entry *clas ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3333,7 +3333,7 @@ static zend_class_entry *register_class_Dom_Text(zend_class_entry *class_entry_D zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, 1); - zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_wholeText_name); return class_entry; @@ -3359,7 +3359,7 @@ static zend_class_entry *register_class_Dom_ProcessingInstruction(zend_class_ent zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, 1); - zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_target_name); return class_entry; @@ -3386,39 +3386,39 @@ static zend_class_entry *register_class_Dom_DocumentType(zend_class_entry *class zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_entities_default_value; ZVAL_UNDEF(&property_entities_default_value); zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, 1); zend_string *property_entities_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0)); zend_string_release(property_entities_name); zval property_notations_default_value; ZVAL_UNDEF(&property_notations_default_value); zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, 1); zend_string *property_notations_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0)); zend_string_release(property_notations_name); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); zval property_internalSubset_default_value; ZVAL_UNDEF(&property_internalSubset_default_value); zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, 1); - zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_internalSubset_name); return class_entry; @@ -3436,20 +3436,20 @@ static zend_class_entry *register_class_Dom_DocumentFragment(zend_class_entry *c ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -3465,19 +3465,19 @@ static zend_class_entry *register_class_Dom_Entity(zend_class_entry *class_entry zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_systemId_name); zval property_notationName_default_value; ZVAL_UNDEF(&property_notationName_default_value); zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, 1); - zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_notationName_name); return class_entry; @@ -3503,13 +3503,13 @@ static zend_class_entry *register_class_Dom_Notation(zend_class_entry *class_ent zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); return class_entry; @@ -3533,85 +3533,85 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent zval property_URL_default_value; ZVAL_UNDEF(&property_URL_default_value); zend_string *property_URL_name = zend_string_init("URL", sizeof("URL") - 1, 1); - zend_declare_typed_property(class_entry, property_URL_name, &property_URL_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_URL_name, &property_URL_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_URL_name); zval property_documentURI_default_value; ZVAL_UNDEF(&property_documentURI_default_value); zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1); - zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_documentURI_name); zval property_characterSet_default_value; ZVAL_UNDEF(&property_characterSet_default_value); zend_string *property_characterSet_name = zend_string_init("characterSet", sizeof("characterSet") - 1, 1); - zend_declare_typed_property(class_entry, property_characterSet_name, &property_characterSet_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_characterSet_name, &property_characterSet_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_characterSet_name); zval property_charset_default_value; ZVAL_UNDEF(&property_charset_default_value); zend_string *property_charset_name = zend_string_init("charset", sizeof("charset") - 1, 1); - zend_declare_typed_property(class_entry, property_charset_name, &property_charset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_charset_name, &property_charset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_charset_name); zval property_inputEncoding_default_value; ZVAL_UNDEF(&property_inputEncoding_default_value); zend_string *property_inputEncoding_name = zend_string_init("inputEncoding", sizeof("inputEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_inputEncoding_name, &property_inputEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_inputEncoding_name, &property_inputEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_inputEncoding_name); zval property_doctype_default_value; ZVAL_UNDEF(&property_doctype_default_value); zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1); zend_string *property_doctype_class_Dom_DocumentType = zend_string_init("Dom\\DocumentType", sizeof("Dom\\DocumentType")-1, 1); - zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL)); zend_string_release(property_doctype_name); zval property_documentElement_default_value; ZVAL_UNDEF(&property_documentElement_default_value); zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1); zend_string *property_documentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_documentElement_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_body_default_value; ZVAL_UNDEF(&property_body_default_value); zend_string *property_body_name = zend_string_init("body", sizeof("body") - 1, 1); zend_string *property_body_class_Dom_HTMLElement = zend_string_init("Dom\\HTMLElement", sizeof("Dom\\HTMLElement")-1, 1); - zend_declare_typed_property(class_entry, property_body_name, &property_body_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_body_class_Dom_HTMLElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_body_name, &property_body_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_body_class_Dom_HTMLElement, 0, MAY_BE_NULL)); zend_string_release(property_body_name); zval property_head_default_value; ZVAL_UNDEF(&property_head_default_value); zend_string *property_head_name = zend_string_init("head", sizeof("head") - 1, 1); zend_string *property_head_class_Dom_HTMLElement = zend_string_init("Dom\\HTMLElement", sizeof("Dom\\HTMLElement")-1, 1); - zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL)); zend_string_release(property_head_name); zval property_title_default_value; ZVAL_UNDEF(&property_title_default_value); zend_string *property_title_name = zend_string_init("title", sizeof("title") - 1, 1); - zend_declare_typed_property(class_entry, property_title_name, &property_title_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_title_name, &property_title_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_title_name); return class_entry; @@ -3637,25 +3637,25 @@ static zend_class_entry *register_class_Dom_XMLDocument(zend_class_entry *class_ zval property_xmlEncoding_default_value; ZVAL_UNDEF(&property_xmlEncoding_default_value); zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlEncoding_name); zval property_xmlStandalone_default_value; ZVAL_UNDEF(&property_xmlStandalone_default_value); zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_xmlStandalone_name); zval property_xmlVersion_default_value; ZVAL_UNDEF(&property_xmlVersion_default_value); zend_string *property_xmlVersion_name = zend_string_init("xmlVersion", sizeof("xmlVersion") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlVersion_name); zval property_formatOutput_default_value; ZVAL_UNDEF(&property_formatOutput_default_value); zend_string *property_formatOutput_name = zend_string_init("formatOutput", sizeof("formatOutput") - 1, 1); - zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_formatOutput_name); return class_entry; @@ -3672,13 +3672,13 @@ static zend_class_entry *register_class_Dom_TokenList(zend_class_entry *class_en zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); return class_entry; @@ -3725,13 +3725,13 @@ static zend_class_entry *register_class_Dom_XPath(void) ZVAL_UNDEF(&property_document_default_value); zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1); zend_string *property_document_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1); - zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0)); + zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0)); zend_string_release(property_document_name); zval property_registerNodeNamespaces_default_value; ZVAL_UNDEF(&property_registerNodeNamespaces_default_value); zend_string *property_registerNodeNamespaces_name = zend_string_init("registerNodeNamespaces", sizeof("registerNodeNamespaces") - 1, 1); - zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_registerNodeNamespaces_name); return class_entry; diff --git a/ext/dom/tests/bug69846.phpt b/ext/dom/tests/bug69846.phpt index 04631444e898c..2f41433e35021 100644 --- a/ext/dom/tests/bug69846.phpt +++ b/ext/dom/tests/bug69846.phpt @@ -28,9 +28,9 @@ foreach ($dataNodes AS $node) { } ?> ---EXPECT-- +--EXPECTF-- int(3) -object(DOMText)#7 (23) { +object(DOMText)#%d (23) { ["wholeText"]=> string(3) " " @@ -82,15 +82,15 @@ object(DOMText)#7 (23) { string(3) " " } -object(DOMElement)#7 (27) { - ["schemaTypeInfo"]=> - NULL +object(DOMElement)#%d (27) { ["tagName"]=> string(5) "form1" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> @@ -146,7 +146,7 @@ object(DOMElement)#7 (27) { Value C " } -object(DOMText)#7 (23) { +object(DOMText)#%d (23) { ["wholeText"]=> string(1) " " diff --git a/ext/dom/tests/bug80602_3.phpt b/ext/dom/tests/bug80602_3.phpt index 3409533fed2d6..8f4626e433ace 100644 --- a/ext/dom/tests/bug80602_3.phpt +++ b/ext/dom/tests/bug80602_3.phpt @@ -24,14 +24,14 @@ var_dump($target); --EXPECTF-- barfoobaz object(DOMElement)#3 (27) { - ["schemaTypeInfo"]=> - NULL ["tagName"]=> string(4) "last" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> NULL ["lastElementChild"]=> @@ -81,14 +81,14 @@ object(DOMElement)#3 (27) { } barfoobaz object(DOMElement)#2 (27) { - ["schemaTypeInfo"]=> - NULL ["tagName"]=> string(4) "last" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> NULL ["lastElementChild"]=> From 067eb8c0d7b5f0b1aa60a45684d6be38f833a25e Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:24:39 +0200 Subject: [PATCH 210/280] [ci skip] Remove confusing comments They are readonly / not readonly depending on the class where they're used. However, the comment makes this confusing [1]. [1] https://github.com/php/php-src/issues/15578#issuecomment-2310389300 --- ext/dom/node.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/dom/node.c b/ext/dom/node.c index 97c77b7665e88..57009a539a1cd 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -133,7 +133,6 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval) /* }}} */ /* {{{ nodeValue string -readonly=no URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080 Modern spec URL: https://dom.spec.whatwg.org/#dom-node-nodevalue Since: @@ -671,7 +670,6 @@ zend_result dom_node_base_uri_read(dom_object *obj, zval *retval) /* }}} */ /* {{{ textContent string -readonly=no URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent Modern spec URL: https://dom.spec.whatwg.org/#dom-node-textcontent Since: DOM Level 3 From 9b73d591c6b00ef962229ee565a85bd9b1e9305c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:07:20 +0200 Subject: [PATCH 211/280] Avoid string duplication if possible in SimpleXMLElement::addAttribute() (#15606) --- ext/simplexml/simplexml.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index c98aa9381126a..218fd69000b32 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1753,7 +1753,8 @@ PHP_METHOD(SimpleXMLElement, addAttribute) } localname = xmlSplitQName2((xmlChar *)qname, &prefix); - if (localname == NULL) { + bool free_localname = localname != NULL; + if (!free_localname) { if (nsuri_len > 0) { if (prefix != NULL) { xmlFree(prefix); @@ -1761,17 +1762,13 @@ PHP_METHOD(SimpleXMLElement, addAttribute) php_error_docref(NULL, E_WARNING, "Attribute requires prefix for namespace"); return; } - localname = xmlStrdup((xmlChar *)qname); + localname = (xmlChar *) qname; } attrp = xmlHasNsProp(node, localname, (xmlChar *)nsuri); if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) { - xmlFree(localname); - if (prefix != NULL) { - xmlFree(prefix); - } php_error_docref(NULL, E_WARNING, "Attribute already exists"); - return; + goto out; } if (nsuri != NULL) { @@ -1783,7 +1780,10 @@ PHP_METHOD(SimpleXMLElement, addAttribute) attrp = xmlNewNsProp(node, nsptr, localname, (xmlChar *)value); - xmlFree(localname); +out: + if (free_localname) { + xmlFree(localname); + } if (prefix != NULL) { xmlFree(prefix); } From 674ec02e543c155601fb3398aabc6fd57fd8b6ea Mon Sep 17 00:00:00 2001 From: Saki Takamachi <34942839+SakiTakamachi@users.noreply.github.com> Date: Wed, 28 Aug 2024 08:48:33 +0900 Subject: [PATCH 212/280] Fixed the sign to be PLUS if the result is 0 (#15599) --- ext/bcmath/libbcmath/src/div.c | 6 +++++- ext/bcmath/libbcmath/src/floor_or_ceil.c | 13 ++++++++++--- ext/bcmath/libbcmath/src/round.c | 21 +++++++++++++-------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 14477f35fb391..809d887f68b9d 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -478,8 +478,12 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) /* do divide */ bc_do_div(numeratorend, numerator_readable_len, numerator_bottom_extension, divisorend, divisor_len, quot, quot_full_len); - (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; _bc_rm_leading_zeros(*quot); + if (bc_is_zero(*quot)) { + (*quot)->n_sign = PLUS; + } else { + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + } return true; } diff --git a/ext/bcmath/libbcmath/src/floor_or_ceil.c b/ext/bcmath/libbcmath/src/floor_or_ceil.c index b0ff811f0a223..98dc94601ac75 100644 --- a/ext/bcmath/libbcmath/src/floor_or_ceil.c +++ b/ext/bcmath/libbcmath/src/floor_or_ceil.c @@ -30,7 +30,7 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If the number is positive and we are flooring, then nothing else needs to be done. * Similarly, if the number is negative and we are ceiling, then nothing else needs to be done. */ if (num->n_scale == 0 || result->n_sign == (is_floor ? PLUS : MINUS)) { - return result; + goto check_zero; } /* check fractional part. */ @@ -43,12 +43,19 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If all digits past the decimal point are 0 */ if (count == 0) { - return result; + goto check_zero; } /* Increment the absolute value of the result by 1 and add sign information */ bc_num tmp = _bc_do_add(result, BCG(_one_)); tmp->n_sign = result->n_sign; bc_free_num(&result); - return tmp; + result = tmp; + +check_zero: + if (bc_is_zero(result)) { + result->n_sign = PLUS; + } + + return result; } diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c index 7ece5ef6b85c4..3a4892cc7079e 100644 --- a/ext/bcmath/libbcmath/src/round.c +++ b/ext/bcmath/libbcmath/src/round.c @@ -76,7 +76,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr >= 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } break; @@ -86,14 +86,14 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr > 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } /* if *nptr == 5, we need to look-up further digits before making a decision. */ break; case PHP_ROUND_CEILING: if (num->n_sign != PLUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -102,7 +102,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_FLOOR: if (num->n_sign != MINUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -110,7 +110,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) break; case PHP_ROUND_TOWARD_ZERO: - return; + goto check_zero; case PHP_ROUND_AWAY_FROM_ZERO: if (*nptr > 0) { @@ -139,17 +139,17 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_CEILING: case PHP_ROUND_FLOOR: case PHP_ROUND_AWAY_FROM_ZERO: - return; + goto check_zero; case PHP_ROUND_HALF_EVEN: if (rounded_len == 0 || num->n_value[rounded_len - 1] % 2 == 0) { - return; + goto check_zero; } break; case PHP_ROUND_HALF_ODD: if (rounded_len != 0 && num->n_value[rounded_len - 1] % 2 == 1) { - return; + goto check_zero; } break; @@ -176,4 +176,9 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) bc_free_num(result); *result = tmp; } + +check_zero: + if (bc_is_zero(*result)) { + (*result)->n_sign = PLUS; + } } From a7695d146a33eb18d1c10a435168502641da0ab6 Mon Sep 17 00:00:00 2001 From: DanielEScherzer Date: Wed, 28 Aug 2024 02:30:02 -0700 Subject: [PATCH 213/280] [skip ci] Zend/tests/assert/expect_015.phpt: fix typo in test name (GH-15609) `peinter` -> `printer` --- Zend/tests/assert/expect_015.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 5a4bbecbe9147..695c4c166a83c 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -1,5 +1,5 @@ --TEST-- -AST pretty-peinter +AST pretty-printer --INI-- zend.assertions=1 --FILE-- From 7878a2c322c7f394f3900a59e36a12002fdc55a5 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 28 Aug 2024 14:29:49 +0200 Subject: [PATCH 214/280] Fix iconv_open basic test (#15611) Transliteration works differently across the iconv implementations and the system. When using GNU libiconv the output in this test is: string(16) "Zlutouck'y kun\n" (like on Windows). On glibc's built-in iconv output is: string(15) "Zlutoucky kun\n" --- ext/iconv/tests/iconv_basic_001.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/iconv/tests/iconv_basic_001.phpt b/ext/iconv/tests/iconv_basic_001.phpt index 518b8a885ba73..a66d8b6d33037 100644 --- a/ext/iconv/tests/iconv_basic_001.phpt +++ b/ext/iconv/tests/iconv_basic_001.phpt @@ -21,5 +21,5 @@ $string_out = iconv($in_charset, $out_charset, $string_to_translate); var_dump($string_out); ?> ---EXPECT-- -string(15) "Zlutoucky kun\n" +--EXPECTF-- +string(1%d) "Zlutouck%Sy kun\n" From 4f6f4fb7d53feb1a1319e1ff78156e05ed555362 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Wed, 28 Aug 2024 14:52:24 +0200 Subject: [PATCH 215/280] Autotools: Sync CS in ext/dba (#15608) - Macro headers synced with current PHP style (a minor description added and parameters) - macro arguments quoted - redundant double quotes reduces - AS_VAR_IF macros used - Redundant check message removed because there is already error thrown right after it --- ext/dba/config.m4 | 194 +++++++++++++++++++++++++--------------------- 1 file changed, 104 insertions(+), 90 deletions(-) diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 index 040b826fa0478..1a977152bd02a 100644 --- a/ext/dba/config.m4 +++ b/ext/dba/config.m4 @@ -1,8 +1,16 @@ +dnl +dnl PHP_DBA_STD_BEGIN +dnl dnl Suppose we need FlatFile if no support or only CDB is used. -AC_DEFUN([PHP_DBA_STD_BEGIN],[ - unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT -]) +dnl +AC_DEFUN([PHP_DBA_STD_BEGIN], + [unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT]) +dnl +dnl PHP_TEMP_LDFLAGS(ldflags, libs) +dnl +dnl Save and restore linker flags. +dnl AC_DEFUN([PHP_TEMP_LDFLAGS],[ old_LDFLAGS=$LDFLAGS LDFLAGS="$1 $LDFLAGS" @@ -13,32 +21,45 @@ AC_DEFUN([PHP_TEMP_LDFLAGS],[ LIBS=$old_LIBS ]) -dnl Assign INCLUDE/LFLAGS from PREFIX +dnl +dnl PHP_DBA_STD_ASSIGN +dnl +dnl Assign INCLUDE/LFLAGS from PREFIX. +dnl AC_DEFUN([PHP_DBA_STD_ASSIGN],[ if test -n "$THIS_PREFIX" && test "$THIS_PREFIX" != "/usr"; then THIS_LFLAGS=$THIS_PREFIX/$PHP_LIBDIR fi ]) -dnl Standard check +dnl +dnl PHP_DBA_STD_CHECK +dnl +dnl Check if includes and libraries are set. +dnl AC_DEFUN([PHP_DBA_STD_CHECK],[ THIS_RESULT=yes - if test -z "$THIS_INCLUDE"; then - AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) - fi - if test -z "$THIS_LIBS"; then - AC_MSG_ERROR([DBA: Could not find necessary library.]) - fi + AS_VAR_IF([THIS_INCLUDE],, + [AC_MSG_ERROR([DBA: Could not find necessary header file(s).])]) + AS_VAR_IF([THIS_LIBS],, + [AC_MSG_ERROR([DBA: Could not find necessary library.])]) ]) -dnl Attach THIS_x to DBA_x +dnl +dnl PHP_DBA_STD_ATTACH +dnl +dnl Attach THIS_x to DBA_x. +dnl AC_DEFUN([PHP_DBA_STD_ATTACH],[ PHP_ADD_LIBRARY_WITH_PATH([$THIS_LIBS], [$THIS_LFLAGS], [DBA_SHARED_LIBADD]) unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX ]) -dnl Print the result message -dnl parameters(name [, full name [, empty or error message]]) +dnl +dnl PHP_DBA_STD_RESULT(name [, full name [, empty or error message]]) +dnl +dnl Print the result message. +dnl AC_DEFUN([PHP_DBA_STD_RESULT],[ THIS_NAME=[]translit($1,a-z0-9-,A-Z0-9_) if test -n "$2"; then @@ -167,14 +188,15 @@ if test "$PHP_QDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(qdbm) +PHP_DBA_STD_RESULT([qdbm]) dnl GDBM if test "$PHP_GDBM" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_QDBM" = "1"; then - PHP_DBA_STD_RESULT(gdbm, gdbm, [You cannot combine --with-gdbm with --with-qdbm]) - fi + AS_VAR_IF([HAVE_QDBM], [1], + [PHP_DBA_STD_RESULT([gdbm], + [gdbm], + [You cannot combine --with-gdbm with --with-qdbm])]) for i in $PHP_GDBM /usr/local /usr; do if test -f "$i/include/gdbm.h"; then THIS_PREFIX=$i @@ -197,7 +219,7 @@ if test "$PHP_GDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(gdbm) +PHP_DBA_STD_RESULT([gdbm]) dnl NDBM if test "$PHP_NDBM" != "no"; then @@ -233,7 +255,7 @@ if test "$PHP_NDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(ndbm) +PHP_DBA_STD_RESULT([ndbm]) dnl TCADB if test "$PHP_TCADB" != "no"; then @@ -266,7 +288,7 @@ if test "$PHP_TCADB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(tcadb) +PHP_DBA_STD_RESULT([tcadb]) dnl LMDB if test "$PHP_LMDB" != "no"; then @@ -299,24 +321,23 @@ if test "$PHP_LMDB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(lmdb) +PHP_DBA_STD_RESULT([lmdb]) -dnl Berkeley specific (library and version test) -dnl parameters(version, library list, function) +dnl +dnl PHP_DBA_DB_CHECK(version, library list, function) +dnl +dnl Berkeley specific (library and version test). +dnl AC_DEFUN([PHP_DBA_DB_CHECK],[ - if test -z "$THIS_INCLUDE"; then - AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) - fi + AS_VAR_IF([THIS_INCLUDE],, + [AC_MSG_ERROR([DBA: Could not find necessary header file(s).])]) for LIB in $2; do if test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.a || test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.$SHLIB_SUFFIX_NAME; then lib_found=""; - PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$LIB,[ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include "$THIS_INCLUDE" - ]],[[ - $3; - ]])],[ - AC_EGREP_CPP(yes,[ + PHP_TEMP_LDFLAGS([-L$THIS_PREFIX/$PHP_LIBDIR], [-l$LIB], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$THIS_INCLUDE"], + [$3;])], + [AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR == $1 || ($1 == 4 && DB_VERSION_MAJOR == 5) yes @@ -324,45 +345,41 @@ AC_DEFUN([PHP_DBA_DB_CHECK],[ ],[ THIS_LIBS=$LIB lib_found=1 - ]) - ],[]) - ]) + ])], + [])]) if test -n "$lib_found"; then lib_found=""; break; fi fi done - if test -z "$THIS_LIBS"; then - AC_MSG_CHECKING([for DB$1 major version]) - AC_MSG_ERROR([Header contains different version]) - fi + + AS_VAR_IF([THIS_LIBS],, [AC_MSG_FAILURE(m4_text_wrap([ + DB$1 major version check failed: header contains different version + ]))]) + if test "$1" = "4"; then AC_MSG_CHECKING([for DB4 minor version and patch level]) - AC_EGREP_CPP(yes,[ + AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR != 1) || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1 && DB_VERSION_PATCH >= 25) yes #endif - ],[ - AC_MSG_RESULT([ok]) - ],[ - AC_MSG_ERROR([Version 4.1 requires patch level 25]) - ]) + ], + [AC_MSG_RESULT([ok])], + [AC_MSG_ERROR([Version 4.1 requires patch level 25])]) fi - if test "$ext_shared" = "yes"; then + AS_VAR_IF([ext_shared], [yes], [ AC_MSG_CHECKING([if dba can be used as shared extension]) - AC_EGREP_CPP(yes,[ + AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) yes #endif - ],[ - AC_MSG_RESULT([yes]) - ],[ - AC_MSG_ERROR([At least version 3.3 is required]) - ]) - fi + ], + [AC_MSG_RESULT([yes])], + [AC_MSG_ERROR([At least version 3.3 is required])]) + ]) if test -n "$THIS_LIBS"; then AC_DEFINE_UNQUOTED([DBA_DB$1], [1], [Define to 1 if the dba extension uses the Berkeley DB version $1 (DB$1) @@ -444,14 +461,15 @@ if test "$PHP_DB4" != "no"; then done PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db4,Berkeley DB4) +PHP_DBA_STD_RESULT([db4], [Berkeley DB4]) dnl DB3 if test "$PHP_DB3" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_DB4" = "1"; then - PHP_DBA_STD_RESULT(db3, Berkeley DB3, [You cannot combine --with-db3 with --with-db4]) - fi + AS_VAR_IF([HAVE_DB4], [1], + [PHP_DBA_STD_RESULT([db3], + [Berkeley DB3], + [You cannot combine --with-db3 with --with-db4])]) for i in $PHP_DB3 /usr/local/BerkeleyDB.3.3 /usr/local/BerkeleyDB.3.2 /usr/local/BerkeleyDB.3.1 /usr/local/BerkeleyDB.3.0 /usr/local /usr; do if test -f "$i/db3/db.h"; then THIS_PREFIX=$i @@ -477,13 +495,15 @@ if test "$PHP_DB3" != "no"; then done PHP_DBA_DB_CHECK(3, db-3.3 db-3.2 db-3.1 db-3.0 db-3 db3 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db3,Berkeley DB3) +PHP_DBA_STD_RESULT([db3], [Berkeley DB3]) dnl DB2 if test "$PHP_DB2" != "no"; then PHP_DBA_STD_BEGIN if test "$HAVE_DB3" = "1" || test "$HAVE_DB4" = "1"; then - PHP_DBA_STD_RESULT(db2, Berkeley DB2, [You cannot combine --with-db2 with --with-db3 or --with-db4]) + PHP_DBA_STD_RESULT([db2], + [Berkeley DB2], + [You cannot combine --with-db2 with --with-db3 or --with-db4]) fi for i in $PHP_DB2 $PHP_DB2/BerkeleyDB /usr/BerkeleyDB /usr/local /usr; do if test -f "$i/db2/db.h"; then @@ -510,7 +530,7 @@ if test "$PHP_DB2" != "no"; then done PHP_DBA_DB_CHECK(2, db-2 db2 db, [(void)db_appinit("", NULL, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db2, Berkeley DB2) +PHP_DBA_STD_RESULT([db2], [Berkeley DB2]) dnl DB1 if test "$PHP_DB1" != "no"; then @@ -562,35 +582,31 @@ if test "$PHP_DB1" != "no"; then AC_MSG_CHECKING([for DB1 in header]) AC_MSG_RESULT([$THIS_INCLUDE]) if test -n "$THIS_INCLUDE"; then - PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$THIS_LIBS,[ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include "$THIS_INCLUDE" - ]],[[ - DB * dbp = dbopen("", 0, 0, DB_HASH, 0); - ]])],[ - AC_DEFINE_UNQUOTED([DB1_INCLUDE_FILE], ["$THIS_INCLUDE"], + PHP_TEMP_LDFLAGS([-L$THIS_PREFIX/$PHP_LIBDIR], [-l$THIS_LIBS], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$THIS_INCLUDE"], + [DB * dbp = dbopen("", 0, 0, DB_HASH, 0);])], + [AC_DEFINE_UNQUOTED([DB1_INCLUDE_FILE], ["$THIS_INCLUDE"], [The DB1 handler header file.]) AC_DEFINE([DBA_DB1], [1], [Define to 1 if the dba extension uses the Berkeley DB version 1 (DB1) handler.]) THIS_RESULT=yes - ],[ - THIS_RESULT=no - ]) - ]) + ], + [THIS_RESULT=no])]) fi PHP_DBA_STD_ASSIGN PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(db1, DB1) +PHP_DBA_STD_RESULT([db1], [DB1]) dnl DBM if test "$PHP_DBM" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_QDBM" = "1"; then - PHP_DBA_STD_RESULT(dbm, dbm, [You cannot combine --with-dbm with --with-qdbm]) - fi + AS_VAR_IF([HAVE_QDBM], [1], + [PHP_DBA_STD_RESULT([dbm], + [dbm], + [You cannot combine --with-dbm with --with-qdbm])]) for i in $PHP_DBM /usr/local /usr; do if test -f "$i/include/dbm.h"; then THIS_PREFIX=$i @@ -632,7 +648,7 @@ if test "$PHP_DBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(dbm) +PHP_DBA_STD_RESULT([dbm]) dnl Bundled modules that should be enabled by default if any other option is dnl enabled @@ -697,7 +713,7 @@ elif test "$PHP_CDB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(cdb) +PHP_DBA_STD_RESULT([cdb]) dnl INIFILE if test "$PHP_INIFILE" != "no"; then @@ -706,7 +722,7 @@ if test "$PHP_INIFILE" != "no"; then ini_sources="libinifile/inifile.c" THIS_RESULT="builtin" fi -PHP_DBA_STD_RESULT(inifile, [INI File]) +PHP_DBA_STD_RESULT([inifile], [INI File]) dnl FLATFILE if test "$PHP_FLATFILE" != "no"; then @@ -715,18 +731,17 @@ if test "$PHP_FLATFILE" != "no"; then flat_sources="libflatfile/flatfile.c" THIS_RESULT="builtin" fi -PHP_DBA_STD_RESULT(FlatFile, FlatFile) +PHP_DBA_STD_RESULT([FlatFile], [FlatFile]) dnl dnl Extension setup dnl AC_MSG_CHECKING([whether to enable DBA interface]) -if test "$HAVE_DBA" = "1"; then - if test "$ext_shared" = "yes"; then - AC_MSG_RESULT([yes, shared]) - else - AC_MSG_RESULT([yes]) - fi +AS_VAR_IF([HAVE_DBA], [1], [ + AS_VAR_IF([ext_shared], [yes], + [AC_MSG_RESULT([yes, shared])], + [AC_MSG_RESULT([yes])]) + AC_DEFINE([HAVE_DBA], [1], [Define to 1 if the PHP extension 'dba' is available.]) PHP_NEW_EXTENSION([dba], m4_normalize([ @@ -754,6 +769,5 @@ if test "$HAVE_DBA" = "1"; then PHP_ADD_BUILD_DIR([$ext_builddir/libflatfile]) PHP_ADD_BUILD_DIR([$ext_builddir/libinifile]) PHP_SUBST([DBA_SHARED_LIBADD]) -else - AC_MSG_RESULT([no]) -fi +], +[AC_MSG_RESULT([no])]) From 5b482b706e9d3e8e185928cf5838ac7e80442877 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:28:07 +0200 Subject: [PATCH 216/280] Alpine/Musl nightly job (#13925) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Voříšek --- .github/actions/apk/action.yml | 61 ++++++++++++++++ .github/actions/configure-alpine/action.yml | 79 +++++++++++++++++++++ .github/actions/install-alpine/action.yml | 10 +++ .github/actions/test-alpine/action.yml | 25 +++++++ .github/nightly_matrix.php | 22 ++++++ .github/workflows/nightly.yml | 60 ++++++++++++++++ Zend/zend.c | 2 +- 7 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 .github/actions/apk/action.yml create mode 100644 .github/actions/configure-alpine/action.yml create mode 100644 .github/actions/install-alpine/action.yml create mode 100644 .github/actions/test-alpine/action.yml diff --git a/.github/actions/apk/action.yml b/.github/actions/apk/action.yml new file mode 100644 index 0000000000000..49e336aa0fecb --- /dev/null +++ b/.github/actions/apk/action.yml @@ -0,0 +1,61 @@ +name: apk +runs: + using: composite + steps: + - shell: sh + run: | + set -x + + apk update -q + apk add \ + util-linux \ + bash \ + sudo \ + build-base \ + autoconf \ + unzip \ + tar \ + bison \ + re2c \ + pkgconf \ + mysql-client \ + aspell-dev \ + hunspell-dev \ + hunspell-en \ + bzip2-dev \ + curl-dev \ + freetype-dev \ + gettext-dev \ + gnu-libiconv-dev \ + gmp-dev \ + icu-dev \ + icu-data-full \ + jpeg-dev \ + libffi-dev \ + libpng-dev \ + libsodium-dev \ + libwebp-dev \ + libxml2-dev \ + libxpm-dev \ + libxslt-dev \ + libzip-dev \ + oniguruma-dev \ + openssl-dev \ + readline-dev \ + sqlite-dev \ + tidyhtml-dev \ + krb5-dev \ + gdbm-dev \ + lmdb-dev \ + argon2-dev \ + enchant2-dev \ + enchant2-hunspell \ + freetds-dev \ + imap-dev \ + net-snmp-dev \ + openldap-dev \ + unixodbc-dev \ + postgresql14-dev \ + tzdata \ + musl-locales \ + musl-locales-lang diff --git a/.github/actions/configure-alpine/action.yml b/.github/actions/configure-alpine/action.yml new file mode 100644 index 0000000000000..fe02dacfcdaf6 --- /dev/null +++ b/.github/actions/configure-alpine/action.yml @@ -0,0 +1,79 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false + skipSlow: + default: false + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + ${{ inputs.skipSlow == 'false' && '--with-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-sqlite' || '' }} \ + --enable-intl \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --with-xpm \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + ${{ inputs.skipSlow == 'false' && '--with-tidy' || '' }} \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline \ + --enable-mbstring \ + --with-iconv=/usr \ + --with-curl \ + --with-gettext \ + --enable-sockets \ + --with-bz2 \ + --with-openssl \ + --with-gmp \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + ${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + ${{ inputs.skipSlow == 'false' && '--enable-dl-test=shared' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap-sasl' || '' }} \ + --with-password-argon2 \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --with-cdb \ + --enable-flatfile \ + --enable-inifile \ + --with-lmdb \ + --with-gdbm \ + ${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-dblib' || '' }} \ + --enable-werror \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/install-alpine/action.yml b/.github/actions/install-alpine/action.yml new file mode 100644 index 0000000000000..3bb26c8cf35d5 --- /dev/null +++ b/.github/actions/install-alpine/action.yml @@ -0,0 +1,10 @@ +name: Install +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo make install + sudo mkdir -p /etc/php.d + sudo chmod 777 /etc/php.d diff --git a/.github/actions/test-alpine/action.yml b/.github/actions/test-alpine/action.yml new file mode 100644 index 0000000000000..e14e3176b8efd --- /dev/null +++ b/.github/actions/test-alpine/action.yml @@ -0,0 +1,25 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false + jitType: + default: 'disable' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export STACK_LIMIT_DEFAULTS_CHECK=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -d opcache.jit=${{ inputs.jitType }} \ + -d opcache.jit_buffer_size=64M \ + -j$(nproc) \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/nightly_matrix.php b/.github/nightly_matrix.php index a5804eaa02456..f0603dd97d73e 100644 --- a/.github/nightly_matrix.php +++ b/.github/nightly_matrix.php @@ -121,6 +121,26 @@ function get_macos_matrix_include(array $branches) { return $jobs; } +function get_alpine_matrix_include(array $branches) { + $jobs = []; + foreach ($branches as $branch) { + if ([$branch['version']['major'], $branch['version']['minor']] < [8, 4]) { + continue; + } + $jobs[] = [ + 'name' => '_ASAN_UBSAN', + 'branch' => $branch, + 'debug' => true, + 'zts' => true, + 'asan' => true, + 'test_jit' => true, + 'configuration_parameters' => "CFLAGS='-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC' LDFLAGS='-fsanitize=undefined,address -fno-sanitize=function' CC=clang-17 CXX=clang++-17", + 'run_tests_parameters' => '--asan -x', + ]; + } + return $jobs; +} + function get_current_version(): array { $file = dirname(__DIR__) . '/main/php_version.h'; $content = file_get_contents($file); @@ -145,10 +165,12 @@ function get_current_version(): array { $matrix_include = get_matrix_include($branches); $windows_matrix_include = get_windows_matrix_include($branches); $macos_matrix_include = get_macos_matrix_include($branches); +$alpine_matrix_include = get_alpine_matrix_include($branches); $f = fopen(getenv('GITHUB_OUTPUT'), 'a'); fwrite($f, 'branches=' . json_encode($branches, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'matrix-include=' . json_encode($matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'windows-matrix-include=' . json_encode($windows_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'macos-matrix-include=' . json_encode($macos_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); +fwrite($f, 'alpine-matrix-include=' . json_encode($alpine_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fclose($f); diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 6899045c196d8..d4da1fdc84eb0 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -15,6 +15,7 @@ jobs: matrix-include: ${{ steps.set-matrix.outputs.matrix-include }} windows-matrix-include: ${{ steps.set-matrix.outputs.windows-matrix-include }} macos-matrix-include: ${{ steps.set-matrix.outputs.macos-matrix-include }} + alpine-matrix-include: ${{ steps.set-matrix.outputs.alpine-matrix-include }} steps: - uses: actions/checkout@v4 with: @@ -39,6 +40,65 @@ jobs: uses: ./.github/actions/notify-slack with: token: ${{ secrets.ACTION_MONITORING_SLACK }} + ALPINE: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.GENERATE_MATRIX.outputs.alpine-matrix-include) }} + name: "${{ matrix.branch.name }}_ALPINE_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-22.04 + container: + image: 'alpine:3.20.1' + steps: + - name: git checkout + uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch.ref }} + - name: apk + uses: ./.github/actions/apk + - name: LLVM 17 (ASAN-only) + if: ${{ matrix.asan }} + # libclang_rt.asan-x86_64.a is provided by compiler-rt, and only for clang17: + # https://pkgs.alpinelinux.org/contents?file=libclang_rt.asan-x86_64.a&path=&name=&branch=v3.20 + run: | + apk add clang17 compiler-rt + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed package versions" + apk list + echo "::endgroup::" + - name: ./configure + uses: ./.github/actions/configure-alpine + with: + configurationParameters: >- + ${{ matrix.configuration_parameters }} + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + skipSlow: ${{ matrix.asan }} + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-alpine + - name: Test Tracing JIT + if: matrix.test_jit + uses: ./.github/actions/test-alpine + with: + jitType: tracing + runTestsParameters: >- + ${{ matrix.run_tests_parameters }} + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + - name: Notify Slack + if: failure() + uses: ./.github/actions/notify-slack + with: + token: ${{ secrets.ACTION_MONITORING_SLACK }} + LINUX_X64: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} diff --git a/Zend/zend.c b/Zend/zend.c index ef5ea8cebc78b..9f6e709efbecf 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1410,7 +1410,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zval retval; zval orig_user_error_handler; bool in_compilation; - zend_class_entry *saved_class_entry; + zend_class_entry *saved_class_entry = NULL; zend_stack loop_var_stack; zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; From cd25500766e23667196391e2f801d68fe7f151f5 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:43:17 +0200 Subject: [PATCH 217/280] Do not scan generator frames more than once (#15330) --- Zend/tests/gh15330-001.phpt | 38 ++++++++++++++++++++++++ Zend/tests/gh15330-002.phpt | 33 +++++++++++++++++++++ Zend/tests/gh15330-003.phpt | 57 ++++++++++++++++++++++++++++++++++++ Zend/tests/gh15330-004.phpt | 52 +++++++++++++++++++++++++++++++++ Zend/tests/gh15330-005.phpt | 53 +++++++++++++++++++++++++++++++++ Zend/tests/gh15330-006.phpt | 56 +++++++++++++++++++++++++++++++++++ Zend/zend_execute.c | 21 +++++++++----- Zend/zend_fibers.c | 22 +++++++++++++- Zend/zend_generators.c | 58 ++++++++++++++++++++----------------- Zend/zend_generators.h | 2 ++ 10 files changed, 357 insertions(+), 35 deletions(-) create mode 100644 Zend/tests/gh15330-001.phpt create mode 100644 Zend/tests/gh15330-002.phpt create mode 100644 Zend/tests/gh15330-003.phpt create mode 100644 Zend/tests/gh15330-004.phpt create mode 100644 Zend/tests/gh15330-005.phpt create mode 100644 Zend/tests/gh15330-006.phpt diff --git a/Zend/tests/gh15330-001.phpt b/Zend/tests/gh15330-001.phpt new file mode 100644 index 0000000000000..dafc31d8b8e22 --- /dev/null +++ b/Zend/tests/gh15330-001.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-15330 001: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$ref = $fiber; + +$fiber->start(); + +gc_collect_cycles(); + +?> +==DONE== +--EXPECT-- +string(3) "foo" +==DONE== diff --git a/Zend/tests/gh15330-002.phpt b/Zend/tests/gh15330-002.phpt new file mode 100644 index 0000000000000..cb2fdc560c5eb --- /dev/null +++ b/Zend/tests/gh15330-002.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-15330 002: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$ref = $fiber; + +$fiber->start(); + +gc_collect_cycles(); + +?> +==DONE== +--EXPECT-- +string(3) "foo" +==DONE== diff --git a/Zend/tests/gh15330-003.phpt b/Zend/tests/gh15330-003.phpt new file mode 100644 index 0000000000000..f4208c544550e --- /dev/null +++ b/Zend/tests/gh15330-003.phpt @@ -0,0 +1,57 @@ +--TEST-- +GH-15330 003: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-004.phpt b/Zend/tests/gh15330-004.phpt new file mode 100644 index 0000000000000..9e971da7f98c9 --- /dev/null +++ b/Zend/tests/gh15330-004.phpt @@ -0,0 +1,52 @@ +--TEST-- +GH-15330 004: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-005.phpt b/Zend/tests/gh15330-005.phpt new file mode 100644 index 0000000000000..774b141baf93b --- /dev/null +++ b/Zend/tests/gh15330-005.phpt @@ -0,0 +1,53 @@ +--TEST-- +GH-15330 005: Do not scan generator frames more than once +--FILE-- +current()); + $f = $iterable->next(...); + $f(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-006.phpt b/Zend/tests/gh15330-006.phpt new file mode 100644 index 0000000000000..fb9195663de65 --- /dev/null +++ b/Zend/tests/gh15330-006.phpt @@ -0,0 +1,56 @@ +--TEST-- +GH-15330 006: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 716756ad93ba2..7b7d618c37d27 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4437,7 +4437,20 @@ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield) { - if (!EX(func) || !ZEND_USER_CODE(EX(func)->common.type)) { + if (!EX(func)) { + return NULL; + } + + if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) { + zend_get_gc_buffer_add_obj(gc_buffer, Z_OBJ(execute_data->This)); + } + + if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { + zend_get_gc_buffer_add_obj(gc_buffer, ZEND_CLOSURE_OBJECT(EX(func))); + } + + if (!ZEND_USER_CODE(EX(func)->common.type)) { + ZEND_ASSERT(!(EX_CALL_INFO() & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS))); return NULL; } @@ -4458,12 +4471,6 @@ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_d } } - if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) { - zend_get_gc_buffer_add_obj(gc_buffer, Z_OBJ(execute_data->This)); - } - if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { - zend_get_gc_buffer_add_obj(gc_buffer, ZEND_CLOSURE_OBJECT(EX(func))); - } if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { zval extra_named_params; ZVAL_ARR(&extra_named_params, EX(extra_named_params)); diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 81e6e8832a064..62d589233eb57 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -19,6 +19,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_gc.h" #include "zend_ini.h" #include "zend_vm.h" #include "zend_exceptions.h" @@ -27,6 +28,7 @@ #include "zend_mmap.h" #include "zend_compile.h" #include "zend_closures.h" +#include "zend_generators.h" #include "zend_fibers.h" #include "zend_fibers_arginfo.h" @@ -682,7 +684,25 @@ static HashTable *zend_fiber_object_gc(zend_object *object, zval **table, int *n HashTable *lastSymTable = NULL; zend_execute_data *ex = fiber->execute_data; for (; ex; ex = ex->prev_execute_data) { - HashTable *symTable = zend_unfinished_execution_gc_ex(ex, ex->func && ZEND_USER_CODE(ex->func->type) ? ex->call : NULL, buf, false); + HashTable *symTable; + if (ZEND_CALL_INFO(ex) & ZEND_CALL_GENERATOR) { + /* The generator object is stored in ex->return_value */ + zend_generator *generator = (zend_generator*)ex->return_value; + /* There are two cases to consider: + * - If the generator is currently running, the Generator's GC + * handler will ignore it because it is not collectable. However, + * in this context the generator is suspended in Fiber::suspend() + * and may be collectable, so we can inspect it. + * - If the generator is not running, the Generator's GC handler + * will inspect it. In this case we have to skip the frame. + */ + if (!(generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING)) { + continue; + } + symTable = zend_generator_frame_gc(buf, generator); + } else { + symTable = zend_unfinished_execution_gc_ex(ex, ex->func && ZEND_USER_CODE(ex->func->type) ? ex->call : NULL, buf, false); + } if (symTable) { if (lastSymTable) { zval *val; diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 85127025679d6..4ac45949bd34a 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -398,32 +398,11 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */ } /* }}} */ -static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *n) /* {{{ */ +HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator *generator) { - zend_generator *generator = (zend_generator*)object; zend_execute_data *execute_data = generator->execute_data; zend_execute_data *call = NULL; - if (!execute_data) { - /* If the generator has been closed, it can only hold on to three values: The value, key - * and retval. These three zvals are stored sequentially starting at &generator->value. */ - *table = &generator->value; - *n = 3; - return NULL; - } - - if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { - /* If the generator is currently running, we certainly won't be able to GC any values it - * holds on to. The execute_data state might be inconsistent during execution (e.g. because - * GC has been triggered in the middle of a variable reassignment), so we should not try - * to inspect it here. */ - *table = NULL; - *n = 0; - return NULL; - } - - - zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); zend_get_gc_buffer_add_zval(gc_buffer, &generator->value); zend_get_gc_buffer_add_zval(gc_buffer, &generator->key); zend_get_gc_buffer_add_zval(gc_buffer, &generator->retval); @@ -434,7 +413,7 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int * call = zend_generator_revert_call_stack(generator->frozen_call_stack); } - zend_unfinished_execution_gc_ex(execute_data, call, gc_buffer, true); + HashTable *ht = zend_unfinished_execution_gc_ex(execute_data, call, gc_buffer, true); if (UNEXPECTED(generator->frozen_call_stack)) { zend_generator_revert_call_stack(call); @@ -444,12 +423,37 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int * zend_get_gc_buffer_add_obj(gc_buffer, &generator->node.parent->std); } - zend_get_gc_buffer_use(gc_buffer, table, n); - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - return execute_data->symbol_table; - } else { + return ht; +} + +static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *n) /* {{{ */ +{ + zend_generator *generator = (zend_generator*)object; + zend_execute_data *execute_data = generator->execute_data; + + if (!execute_data) { + /* If the generator has been closed, it can only hold on to three values: The value, key + * and retval. These three zvals are stored sequentially starting at &generator->value. */ + *table = &generator->value; + *n = 3; return NULL; } + + if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { + /* If the generator is currently running, we certainly won't be able to GC any values it + * holds on to. The execute_data state might be inconsistent during execution (e.g. because + * GC has been triggered in the middle of a variable reassignment), so we should not try + * to inspect it here. */ + *table = NULL; + *n = 0; + return NULL; + } + + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + HashTable *ht = zend_generator_frame_gc(gc_buffer, generator); + zend_get_gc_buffer_use(gc_buffer, table, n); + + return ht; } /* }}} */ diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index a3daba3a839bb..a41fb7699d842 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -127,6 +127,8 @@ static zend_always_inline zend_generator *zend_generator_get_current(zend_genera return zend_generator_update_current(generator); } +HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator *generator); + END_EXTERN_C() #endif From 4db78140a0f9e82654e3b110fc3d4913d36d6733 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:44:12 +0200 Subject: [PATCH 218/280] [ci skip] NEWS for GH-15330 --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 3be42abdd2b8e..2e29e33cc6443 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS EAI_SYSTEM not found). (nielsdos) . Fixed bug GH-15587 (CRC32 API build error on arm 32-bit). (Bernd Kuhls, Thomas Petazzoni) + . Fixed bug GH-15330 (Do not scan generator frames more than once). (Arnaud) - Curl: . FIxed bug GH-15547 (curl_multi_select overflow on timeout argument). From 0e9e5912c190a2be05004eda031380c04379e309 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:44:52 +0200 Subject: [PATCH 219/280] [ci skip] NEWS for GH-15330 --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index bdfe9990080df..ce5057f35fb5e 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS EAI_SYSTEM not found). (nielsdos) . Fixed bug GH-15587 (CRC32 API build error on arm 32-bit). (Bernd Kuhls, Thomas Petazzoni) + . Fixed bug GH-15330 (Do not scan generator frames more than once). (Arnaud) - Curl: . FIxed bug GH-15547 (curl_multi_select overflow on timeout argument). From 180a5c3cccd7cb0db72ecec27617eac9b97718cb Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:46:22 +0200 Subject: [PATCH 220/280] [ci skip] NEWS for GH-15330 --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index dfc0f55e023a1..27c25de5709f7 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.0beta5 +- Core: + . Fixed bug GH-15330 (Do not scan generator frames more than once). (Arnaud) + - DOM: . Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in PHP 8.1 than in PHP 8.0). (nielsdos) From 7f37c22d2246c23e110f37f81733c2cf110cce46 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:59:11 +0200 Subject: [PATCH 221/280] Cleanup php_sxe_count_elements_helper() --- ext/simplexml/simplexml.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 218fd69000b32..e81c1f7bc9f35 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1899,19 +1899,18 @@ PHP_METHOD(SimpleXMLElement, __toString) } /* }}} */ -static zend_result php_sxe_count_elements_helper(php_sxe_object *sxe, zend_long *count) /* {{{ */ +static zend_long php_sxe_count_elements_helper(php_sxe_object *sxe) /* {{{ */ { - *count = 0; - + zend_long count = 0; xmlNodePtr node = php_sxe_reset_iterator_no_clear_iter_data(sxe, 0); while (node) { - (*count)++; + count++; node = php_sxe_iterator_fetch(sxe, node->next, 0); } - return SUCCESS; + return count; } /* }}} */ @@ -1929,23 +1928,21 @@ static zend_result sxe_count_elements(zend_object *object, zend_long *count) /* } return FAILURE; } - return php_sxe_count_elements_helper(intern, count); + *count = php_sxe_count_elements_helper(intern); + return SUCCESS; } /* }}} */ /* {{{ Get number of child elements */ PHP_METHOD(SimpleXMLElement, count) { - zend_long count = 0; php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } - php_sxe_count_elements_helper(sxe, &count); - - RETURN_LONG(count); + RETURN_LONG(php_sxe_count_elements_helper(sxe)); } /* }}} */ From 2fe8dd105495b3f43c2a27d63b2829ce568a7073 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:01:06 +0200 Subject: [PATCH 222/280] Remove unused parameter of php_sxe_reset_iterator() --- ext/simplexml/simplexml.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index e81c1f7bc9f35..b44f6563a465c 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -42,7 +42,7 @@ PHP_SXE_API zend_class_entry *sxe_get_element_class_entry(void) /* {{{ */ /* }}} */ static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count); -static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data); +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe); static xmlNodePtr php_sxe_reset_iterator_no_clear_iter_data(php_sxe_object *sxe, int use_data); static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data); static void php_sxe_iterator_dtor(zend_object_iterator *iter); @@ -2428,14 +2428,14 @@ static xmlNodePtr php_sxe_reset_iterator_no_clear_iter_data(php_sxe_object *sxe, return NULL; } -static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data) /* {{{ */ +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe) /* {{{ */ { if (!Z_ISUNDEF(sxe->iter.data)) { zval_ptr_dtor(&sxe->iter.data); ZVAL_UNDEF(&sxe->iter.data); } - return php_sxe_reset_iterator_no_clear_iter_data(sxe, use_data); + return php_sxe_reset_iterator_no_clear_iter_data(sxe, 1); } /* }}} */ @@ -2531,7 +2531,7 @@ static void php_sxe_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ PHP_SXE_API void php_sxe_rewind_iterator(php_sxe_object *sxe) /* {{{ */ { - php_sxe_reset_iterator(sxe, 1); + php_sxe_reset_iterator(sxe); } /* }}} */ @@ -2542,7 +2542,7 @@ static void php_sxe_iterator_rewind(zend_object_iterator *iter) /* {{{ */ php_sxe_iterator *iterator = (php_sxe_iterator *)iter; sxe = iterator->sxe; - php_sxe_reset_iterator(sxe, 1); + php_sxe_reset_iterator(sxe); } /* }}} */ From 9979f4748c5fec1fc42b5a2187313de019bae242 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:04:08 +0200 Subject: [PATCH 223/280] Remove unused parameter from match_ns() --- ext/simplexml/simplexml.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index b44f6563a465c..ef52df4f825bb 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -96,7 +96,7 @@ static xmlNodePtr php_sxe_get_first_node_non_destructive(php_sxe_object *sxe, xm } } -static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, const zend_string *name, int prefix) /* {{{ */ +static inline int match_ns(xmlNodePtr node, const zend_string *name, int prefix) /* {{{ */ { if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) { return 1; @@ -125,7 +125,7 @@ static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, zend_long offse } } while (node && nodendx <= offset) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (sxe->iter.type == SXE_ITER_CHILD || ( sxe->iter.type == SXE_ITER_ELEMENT && xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)))) { if (nodendx == offset) { @@ -149,7 +149,7 @@ static xmlNodePtr sxe_find_element_by_name(php_sxe_object *sxe, xmlNodePtr node, { const xmlChar *raw_name = BAD_CAST ZSTR_VAL(name); while (node) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (xmlStrEqual(node->name, raw_name)) { return node; } @@ -183,7 +183,7 @@ static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node, } while (node) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (xmlStrEqual(node->name, (xmlChar *)name)) { *type = SXE_ITER_ELEMENT; return orgnode; @@ -265,7 +265,7 @@ static zval *sxe_prop_dim_read(zend_object *object, zval *member, bool elements, if (Z_TYPE_P(member) != IS_LONG || sxe->iter.type == SXE_ITER_ATTRLIST) { if (Z_TYPE_P(member) == IS_LONG) { while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix); break; @@ -276,7 +276,7 @@ static zval *sxe_prop_dim_read(zend_object *object, zval *member, bool elements, } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(name)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix); break; } @@ -491,7 +491,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, if (attribs) { if (Z_TYPE_P(member) == IS_LONG) { while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { is_attr = 1; ++counter; @@ -503,7 +503,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { is_attr = 1; ++counter; break; @@ -542,7 +542,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, while (node) { SKIP_TEXT(node); - if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { newnode = node; ++counter; } @@ -707,7 +707,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt int nodendx = 0; while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { exists = 1; break; @@ -718,7 +718,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { exists = 1; break; } @@ -831,7 +831,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements int nodendx = 0; while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { xmlUnlinkNode((xmlNodePtr) attr); php_libxml_node_free_resource((xmlNodePtr) attr); @@ -844,7 +844,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements } else { while (attr) { anext = attr->next; - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { xmlUnlinkNode((xmlNodePtr) attr); php_libxml_node_free_resource((xmlNodePtr) attr); break; @@ -871,7 +871,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements SKIP_TEXT(node); - if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { xmlUnlinkNode(node); php_libxml_node_free_resource(node); } @@ -995,7 +995,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */ attr = node->properties; test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { return 0; } attr = attr->next; @@ -1031,7 +1031,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */ } } - if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) { + if (node->type == XML_ELEMENT_NODE && (! match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix))) { goto next_iter; } @@ -1092,7 +1092,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */ ZVAL_UNDEF(&zattr); test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { ZVAL_STR(&value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1)); namelen = xmlStrlen(attr->name); if (Z_ISUNDEF(zattr)) { @@ -1138,7 +1138,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */ } } - if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) { + if (node->type == XML_ELEMENT_NODE && (! match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix))) { goto next_iter; } @@ -2361,7 +2361,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i if (sxe->iter.name) { while (node) { if (node->type == XML_ATTRIBUTE_NODE) { - if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(node, prefix, isprefix)) { break; } } @@ -2370,7 +2370,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else { while (node) { if (node->type == XML_ATTRIBUTE_NODE) { - if (match_ns(sxe, node, prefix, isprefix)) { + if (match_ns(node, prefix, isprefix)) { break; } } @@ -2380,7 +2380,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else if (sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name) { while (node) { if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(node, prefix, isprefix)) { break; } } @@ -2389,7 +2389,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else { while (node) { if (node->type == XML_ELEMENT_NODE) { - if (match_ns(sxe, node, prefix, isprefix)) { + if (match_ns(node, prefix, isprefix)) { break; } } From 51d93c194720b2ec0945236667eb9dd0a91d64a2 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:06:29 +0200 Subject: [PATCH 224/280] Remove failure paths for infallible code in simplexml For IS_STRING, sxe_object_cast_ex() will call cast_object() which cannot fail for IS_STRING. --- ext/simplexml/simplexml.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index ef52df4f825bb..e22a625bf9603 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -467,10 +467,9 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, case IS_OBJECT: if (Z_OBJCE_P(value) == ce_SimpleXMLElement) { zval zval_copy; - if (sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING) == FAILURE) { - zend_throw_error(NULL, "Unable to cast node to string"); - return &EG(error_zval); - } + zend_result rv = sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING); + ZEND_IGNORE_VALUE(rv); + ZEND_ASSERT(rv == SUCCESS); value_str = Z_STR(zval_copy); break; @@ -1892,10 +1891,9 @@ PHP_METHOD(SimpleXMLElement, __toString) RETURN_THROWS(); } - if (sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING) != SUCCESS) { - zval_ptr_dtor(return_value); - RETURN_EMPTY_STRING(); - } + zend_result rv = sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING); + ZEND_IGNORE_VALUE(rv); + ZEND_ASSERT(rv == SUCCESS); } /* }}} */ From 8347adada1dd28d0b28fe131f4e5e18ab1b26ea6 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 19 May 2023 12:55:05 +0200 Subject: [PATCH 225/280] Lazy objects --- Zend/tests/lazy_objects/003.phpt | 65 ++ Zend/tests/lazy_objects/004.phpt | 65 ++ Zend/tests/lazy_objects/005.phpt | 164 +++++ Zend/tests/lazy_objects/006.phpt | 48 ++ Zend/tests/lazy_objects/007.phpt | 64 ++ Zend/tests/lazy_objects/008.phpt | 47 ++ Zend/tests/lazy_objects/009.phpt | 43 ++ Zend/tests/lazy_objects/010.phpt | 42 ++ Zend/tests/lazy_objects/011.phpt | 62 ++ Zend/tests/lazy_objects/012.phpt | 58 ++ Zend/tests/lazy_objects/013.phpt | 65 ++ Zend/tests/lazy_objects/014.phpt | 34 + Zend/tests/lazy_objects/015.phpt | 37 + Zend/tests/lazy_objects/016.phpt | 45 ++ Zend/tests/lazy_objects/017.phpt | 74 ++ Zend/tests/lazy_objects/018.phpt | 57 ++ Zend/tests/lazy_objects/019.phpt | 56 ++ Zend/tests/lazy_objects/020.phpt | 80 +++ Zend/tests/lazy_objects/021.phpt | 81 +++ Zend/tests/lazy_objects/024.phpt | 36 + Zend/tests/lazy_objects/025.phpt | 55 ++ Zend/tests/lazy_objects/026.phpt | 59 ++ Zend/tests/lazy_objects/027.phpt | 63 ++ Zend/tests/lazy_objects/clone_001.phpt | 71 ++ Zend/tests/lazy_objects/clone_002.phpt | 77 ++ Zend/tests/lazy_objects/clone_003.phpt | 56 ++ Zend/tests/lazy_objects/clone_004.phpt | 73 ++ Zend/tests/lazy_objects/clone_007.phpt | 35 + Zend/tests/lazy_objects/clone_008.phpt | 56 ++ Zend/tests/lazy_objects/clone_009.phpt | 40 ++ Zend/tests/lazy_objects/feedback_001.phpt | 49 ++ Zend/tests/lazy_objects/feedback_002.phpt | 36 + Zend/tests/lazy_objects/feedback_003.phpt | 33 + Zend/tests/lazy_objects/feedback_004.phpt | 29 + Zend/tests/lazy_objects/feedback_005.phpt | 50 ++ Zend/tests/lazy_objects/feedback_006.phpt | 29 + Zend/tests/lazy_objects/feedback_007.phpt | 31 + Zend/tests/lazy_objects/feedback_008.phpt | 53 ++ Zend/tests/lazy_objects/feedback_009.phpt | 29 + Zend/tests/lazy_objects/fetch_001.phpt | 72 ++ Zend/tests/lazy_objects/fetch_002.phpt | 65 ++ Zend/tests/lazy_objects/fetch_003.phpt | 65 ++ Zend/tests/lazy_objects/fetch_004.phpt | 69 ++ Zend/tests/lazy_objects/fetch_005.phpt | 60 ++ Zend/tests/lazy_objects/fetch_006.phpt | 66 ++ Zend/tests/lazy_objects/fetch_007.phpt | 70 ++ Zend/tests/lazy_objects/fetch_008.phpt | 63 ++ Zend/tests/lazy_objects/fetch_009.phpt | 63 ++ Zend/tests/lazy_objects/fetch_010.phpt | 65 ++ Zend/tests/lazy_objects/fetch_011.phpt | 62 ++ Zend/tests/lazy_objects/fetch_012.phpt | 62 ++ Zend/tests/lazy_objects/fetch_013.phpt | 93 +++ Zend/tests/lazy_objects/fetch_014.phpt | 91 +++ Zend/tests/lazy_objects/fetch_015.phpt | 87 +++ Zend/tests/lazy_objects/fetch_016.phpt | 75 ++ Zend/tests/lazy_objects/fetch_017.phpt | 76 ++ Zend/tests/lazy_objects/fetch_018.phpt | 62 ++ Zend/tests/lazy_objects/gc_001.phpt | 54 ++ Zend/tests/lazy_objects/gc_002.phpt | 59 ++ Zend/tests/lazy_objects/gc_003.phpt | 59 ++ Zend/tests/lazy_objects/gc_004.phpt | 67 ++ Zend/tests/lazy_objects/gc_005.phpt | 68 ++ Zend/tests/lazy_objects/get_initializer.phpt | 52 ++ Zend/tests/lazy_objects/ghost_001.phpt | 46 ++ Zend/tests/lazy_objects/ghost_002.phpt | 45 ++ .../lazy_objects/init_exception_001.phpt | 51 ++ .../lazy_objects/init_exception_002.phpt | 72 ++ .../lazy_objects/init_exception_003.phpt | 83 +++ .../lazy_objects/init_exception_005.phpt | 77 ++ .../lazy_objects/init_exception_006.phpt | 84 +++ .../lazy_objects/init_exception_009.phpt | 95 +++ .../lazy_objects/init_exception_010.phpt | 100 +++ .../lazy_objects/init_exception_011.phpt | 108 +++ .../lazy_objects/init_exception_012.phpt | 59 ++ Zend/tests/lazy_objects/initialize_001.phpt | 62 ++ Zend/tests/lazy_objects/initialize_002.phpt | 60 ++ Zend/tests/lazy_objects/initialize_005.phpt | 51 ++ .../lazy_objects/is_initialized_001.phpt | 26 + .../is_uninitialized_lazy_object.phpt | 31 + Zend/tests/lazy_objects/isset_001.phpt | 72 ++ Zend/tests/lazy_objects/isset_002.phpt | 75 ++ Zend/tests/lazy_objects/isset_003.phpt | 64 ++ .../make_lazy_already_exception.phpt | 55 ++ .../make_lazy_destructor_001.phpt | 59 ++ .../make_lazy_destructor_002.phpt | 57 ++ .../make_lazy_destructor_003.phpt | 55 ++ .../lazy_objects/mark_as_initialized_001.phpt | 66 ++ .../lazy_objects/new_instance_lazy_001.phpt | 20 + .../lazy_objects/new_instance_lazy_002.phpt | 21 + .../lazy_objects/new_instance_lazy_003.phpt | 22 + .../lazy_objects/new_instance_lazy_004.phpt | 18 + .../lazy_objects/new_instance_lazy_005.phpt | 21 + .../object_with_ast_const_001.phpt | 27 + .../object_with_ast_const_002.phpt | 26 + .../props_of_proxy_must_not_be_lazy_004.phpt | 90 +++ Zend/tests/lazy_objects/realize_001.phpt | 95 +++ Zend/tests/lazy_objects/realize_002.phpt | 100 +++ Zend/tests/lazy_objects/realize_003.phpt | 78 ++ ...lection_lazy_object_skip_property_001.phpt | 349 +++++++++ .../reflection_to_string_does_not_init.phpt | 45 ++ ...as_lazy_can_reset_initialized_proxies.phpt | 55 ++ ...eset_as_lazy_ignores_additional_props.phpt | 103 +++ .../lazy_objects/reset_readonly_001.phpt | 71 ++ Zend/tests/lazy_objects/rfc_example_001.phpt | 40 ++ Zend/tests/lazy_objects/rfc_example_002.phpt | 44 ++ Zend/tests/lazy_objects/rfc_example_003.phpt | 51 ++ Zend/tests/lazy_objects/rfc_example_004.phpt | 69 ++ Zend/tests/lazy_objects/rfc_example_005.phpt | 71 ++ Zend/tests/lazy_objects/rfc_example_006.phpt | 64 ++ Zend/tests/lazy_objects/rfc_example_007.phpt | 31 + Zend/tests/lazy_objects/rfc_example_008.phpt | 25 + Zend/tests/lazy_objects/rfc_example_009.phpt | 40 ++ Zend/tests/lazy_objects/rfc_example_010.phpt | 25 + Zend/tests/lazy_objects/rfc_example_011.phpt | 81 +++ Zend/tests/lazy_objects/rfc_example_012.phpt | 80 +++ Zend/tests/lazy_objects/serialize_001.phpt | 44 ++ Zend/tests/lazy_objects/serialize_002.phpt | 47 ++ Zend/tests/lazy_objects/serialize_003.phpt | 52 ++ Zend/tests/lazy_objects/serialize_004.phpt | 55 ++ Zend/tests/lazy_objects/serialize_005.phpt | 48 ++ Zend/tests/lazy_objects/serialize_006.phpt | 53 ++ Zend/tests/lazy_objects/serialize_007.phpt | 53 ++ Zend/tests/lazy_objects/serialize_008.phpt | 49 ++ Zend/tests/lazy_objects/serialize_009.phpt | 56 ++ Zend/tests/lazy_objects/serialize_010.phpt | 47 ++ .../tests/lazy_objects/set_raw_value_001.phpt | 47 ++ .../tests/lazy_objects/set_raw_value_002.phpt | 50 ++ .../tests/lazy_objects/set_raw_value_003.phpt | 52 ++ .../tests/lazy_objects/set_raw_value_004.phpt | 51 ++ .../tests/lazy_objects/set_raw_value_005.phpt | 68 ++ .../tests/lazy_objects/set_raw_value_006.phpt | 71 ++ .../tests/lazy_objects/set_raw_value_007.phpt | 54 ++ .../tests/lazy_objects/set_raw_value_008.phpt | 43 ++ .../tests/lazy_objects/set_raw_value_009.phpt | 54 ++ .../lazy_objects/skip_initialization_001.phpt | 59 ++ .../lazy_objects/skip_initialization_002.phpt | 53 ++ .../lazy_objects/skip_initialization_003.phpt | 52 ++ .../lazy_objects/skip_initialization_004.phpt | 54 ++ .../lazy_objects/skip_initialization_005.phpt | 54 ++ .../lazy_objects/skip_initialization_006.phpt | 61 ++ .../lazy_objects/skip_initialization_007.phpt | 75 ++ .../lazy_objects/skip_initialization_008.phpt | 76 ++ .../lazy_objects/skip_initialization_009.phpt | 67 ++ .../lazy_objects/skip_initialization_010.phpt | 43 ++ Zend/tests/lazy_objects/unclean_shutdown.phpt | 17 + Zend/tests/lazy_objects/unset_001.phpt | 66 ++ Zend/tests/lazy_objects/unset_003.phpt | 60 ++ Zend/tests/lazy_objects/unset_004.phpt | 70 ++ Zend/tests/lazy_objects/unset_005.phpt | 68 ++ Zend/tests/lazy_objects/unset_006.phpt | 65 ++ Zend/tests/lazy_objects/unset_007.phpt | 60 ++ Zend/tests/lazy_objects/unset_008.phpt | 60 ++ Zend/tests/lazy_objects/unset_009.phpt | 78 ++ Zend/tests/lazy_objects/unset_010.phpt | 68 ++ Zend/tests/lazy_objects/use_case_001.phpt | 44 ++ Zend/tests/lazy_objects/use_case_001b.phpt | 44 ++ Zend/tests/lazy_objects/use_case_002.phpt | 52 ++ Zend/tests/lazy_objects/write_001.phpt | 69 ++ Zend/tests/lazy_objects/write_002.phpt | 74 ++ Zend/tests/lazy_objects/write_003.phpt | 64 ++ Zend/tests/lazy_objects/write_004.phpt | 64 ++ Zend/tests/lazy_objects/write_005.phpt | 48 ++ Zend/tests/lazy_objects/write_006.phpt | 81 +++ Zend/zend_builtin_functions.c | 2 +- Zend/zend_execute_API.c | 2 + Zend/zend_globals.h | 2 + Zend/zend_lazy_objects.c | 668 ++++++++++++++++++ Zend/zend_lazy_objects.h | 107 +++ Zend/zend_object_handlers.c | 175 ++++- Zend/zend_object_handlers.h | 9 + Zend/zend_objects.c | 83 ++- Zend/zend_objects.h | 4 + Zend/zend_operators.c | 3 +- Zend/zend_types.h | 9 + Zend/zend_vm_def.h | 3 +- Zend/zend_vm_execute.h | 12 +- configure.ac | 1 + ext/ffi/ffi.c | 1 + ext/json/json_encoder.c | 9 + ext/reflection/php_reflection.c | 337 ++++++++- ext/reflection/php_reflection.h | 1 + ext/reflection/php_reflection.stub.php | 26 + ext/reflection/php_reflection_arginfo.h | 72 +- .../tests/ReflectionClass_toString_001.phpt | 76 +- ext/standard/var.c | 40 +- 185 files changed, 11416 insertions(+), 53 deletions(-) create mode 100644 Zend/tests/lazy_objects/003.phpt create mode 100644 Zend/tests/lazy_objects/004.phpt create mode 100644 Zend/tests/lazy_objects/005.phpt create mode 100644 Zend/tests/lazy_objects/006.phpt create mode 100644 Zend/tests/lazy_objects/007.phpt create mode 100644 Zend/tests/lazy_objects/008.phpt create mode 100644 Zend/tests/lazy_objects/009.phpt create mode 100644 Zend/tests/lazy_objects/010.phpt create mode 100644 Zend/tests/lazy_objects/011.phpt create mode 100644 Zend/tests/lazy_objects/012.phpt create mode 100644 Zend/tests/lazy_objects/013.phpt create mode 100644 Zend/tests/lazy_objects/014.phpt create mode 100644 Zend/tests/lazy_objects/015.phpt create mode 100644 Zend/tests/lazy_objects/016.phpt create mode 100644 Zend/tests/lazy_objects/017.phpt create mode 100644 Zend/tests/lazy_objects/018.phpt create mode 100644 Zend/tests/lazy_objects/019.phpt create mode 100644 Zend/tests/lazy_objects/020.phpt create mode 100644 Zend/tests/lazy_objects/021.phpt create mode 100644 Zend/tests/lazy_objects/024.phpt create mode 100644 Zend/tests/lazy_objects/025.phpt create mode 100644 Zend/tests/lazy_objects/026.phpt create mode 100644 Zend/tests/lazy_objects/027.phpt create mode 100644 Zend/tests/lazy_objects/clone_001.phpt create mode 100644 Zend/tests/lazy_objects/clone_002.phpt create mode 100644 Zend/tests/lazy_objects/clone_003.phpt create mode 100644 Zend/tests/lazy_objects/clone_004.phpt create mode 100644 Zend/tests/lazy_objects/clone_007.phpt create mode 100644 Zend/tests/lazy_objects/clone_008.phpt create mode 100644 Zend/tests/lazy_objects/clone_009.phpt create mode 100644 Zend/tests/lazy_objects/feedback_001.phpt create mode 100644 Zend/tests/lazy_objects/feedback_002.phpt create mode 100644 Zend/tests/lazy_objects/feedback_003.phpt create mode 100644 Zend/tests/lazy_objects/feedback_004.phpt create mode 100644 Zend/tests/lazy_objects/feedback_005.phpt create mode 100644 Zend/tests/lazy_objects/feedback_006.phpt create mode 100644 Zend/tests/lazy_objects/feedback_007.phpt create mode 100644 Zend/tests/lazy_objects/feedback_008.phpt create mode 100644 Zend/tests/lazy_objects/feedback_009.phpt create mode 100644 Zend/tests/lazy_objects/fetch_001.phpt create mode 100644 Zend/tests/lazy_objects/fetch_002.phpt create mode 100644 Zend/tests/lazy_objects/fetch_003.phpt create mode 100644 Zend/tests/lazy_objects/fetch_004.phpt create mode 100644 Zend/tests/lazy_objects/fetch_005.phpt create mode 100644 Zend/tests/lazy_objects/fetch_006.phpt create mode 100644 Zend/tests/lazy_objects/fetch_007.phpt create mode 100644 Zend/tests/lazy_objects/fetch_008.phpt create mode 100644 Zend/tests/lazy_objects/fetch_009.phpt create mode 100644 Zend/tests/lazy_objects/fetch_010.phpt create mode 100644 Zend/tests/lazy_objects/fetch_011.phpt create mode 100644 Zend/tests/lazy_objects/fetch_012.phpt create mode 100644 Zend/tests/lazy_objects/fetch_013.phpt create mode 100644 Zend/tests/lazy_objects/fetch_014.phpt create mode 100644 Zend/tests/lazy_objects/fetch_015.phpt create mode 100644 Zend/tests/lazy_objects/fetch_016.phpt create mode 100644 Zend/tests/lazy_objects/fetch_017.phpt create mode 100644 Zend/tests/lazy_objects/fetch_018.phpt create mode 100644 Zend/tests/lazy_objects/gc_001.phpt create mode 100644 Zend/tests/lazy_objects/gc_002.phpt create mode 100644 Zend/tests/lazy_objects/gc_003.phpt create mode 100644 Zend/tests/lazy_objects/gc_004.phpt create mode 100644 Zend/tests/lazy_objects/gc_005.phpt create mode 100644 Zend/tests/lazy_objects/get_initializer.phpt create mode 100644 Zend/tests/lazy_objects/ghost_001.phpt create mode 100644 Zend/tests/lazy_objects/ghost_002.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_001.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_002.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_003.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_005.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_006.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_009.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_010.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_011.phpt create mode 100644 Zend/tests/lazy_objects/init_exception_012.phpt create mode 100644 Zend/tests/lazy_objects/initialize_001.phpt create mode 100644 Zend/tests/lazy_objects/initialize_002.phpt create mode 100644 Zend/tests/lazy_objects/initialize_005.phpt create mode 100644 Zend/tests/lazy_objects/is_initialized_001.phpt create mode 100644 Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt create mode 100644 Zend/tests/lazy_objects/isset_001.phpt create mode 100644 Zend/tests/lazy_objects/isset_002.phpt create mode 100644 Zend/tests/lazy_objects/isset_003.phpt create mode 100644 Zend/tests/lazy_objects/make_lazy_already_exception.phpt create mode 100644 Zend/tests/lazy_objects/make_lazy_destructor_001.phpt create mode 100644 Zend/tests/lazy_objects/make_lazy_destructor_002.phpt create mode 100644 Zend/tests/lazy_objects/make_lazy_destructor_003.phpt create mode 100644 Zend/tests/lazy_objects/mark_as_initialized_001.phpt create mode 100644 Zend/tests/lazy_objects/new_instance_lazy_001.phpt create mode 100644 Zend/tests/lazy_objects/new_instance_lazy_002.phpt create mode 100644 Zend/tests/lazy_objects/new_instance_lazy_003.phpt create mode 100644 Zend/tests/lazy_objects/new_instance_lazy_004.phpt create mode 100644 Zend/tests/lazy_objects/new_instance_lazy_005.phpt create mode 100644 Zend/tests/lazy_objects/object_with_ast_const_001.phpt create mode 100644 Zend/tests/lazy_objects/object_with_ast_const_002.phpt create mode 100644 Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt create mode 100644 Zend/tests/lazy_objects/realize_001.phpt create mode 100644 Zend/tests/lazy_objects/realize_002.phpt create mode 100644 Zend/tests/lazy_objects/realize_003.phpt create mode 100644 Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt create mode 100644 Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt create mode 100644 Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt create mode 100644 Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt create mode 100644 Zend/tests/lazy_objects/reset_readonly_001.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_001.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_002.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_003.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_004.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_005.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_006.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_007.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_008.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_009.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_010.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_011.phpt create mode 100644 Zend/tests/lazy_objects/rfc_example_012.phpt create mode 100644 Zend/tests/lazy_objects/serialize_001.phpt create mode 100644 Zend/tests/lazy_objects/serialize_002.phpt create mode 100644 Zend/tests/lazy_objects/serialize_003.phpt create mode 100644 Zend/tests/lazy_objects/serialize_004.phpt create mode 100644 Zend/tests/lazy_objects/serialize_005.phpt create mode 100644 Zend/tests/lazy_objects/serialize_006.phpt create mode 100644 Zend/tests/lazy_objects/serialize_007.phpt create mode 100644 Zend/tests/lazy_objects/serialize_008.phpt create mode 100644 Zend/tests/lazy_objects/serialize_009.phpt create mode 100644 Zend/tests/lazy_objects/serialize_010.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_001.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_002.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_003.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_004.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_005.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_006.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_007.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_008.phpt create mode 100644 Zend/tests/lazy_objects/set_raw_value_009.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_001.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_002.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_003.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_004.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_005.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_006.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_007.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_008.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_009.phpt create mode 100644 Zend/tests/lazy_objects/skip_initialization_010.phpt create mode 100644 Zend/tests/lazy_objects/unclean_shutdown.phpt create mode 100644 Zend/tests/lazy_objects/unset_001.phpt create mode 100644 Zend/tests/lazy_objects/unset_003.phpt create mode 100644 Zend/tests/lazy_objects/unset_004.phpt create mode 100644 Zend/tests/lazy_objects/unset_005.phpt create mode 100644 Zend/tests/lazy_objects/unset_006.phpt create mode 100644 Zend/tests/lazy_objects/unset_007.phpt create mode 100644 Zend/tests/lazy_objects/unset_008.phpt create mode 100644 Zend/tests/lazy_objects/unset_009.phpt create mode 100644 Zend/tests/lazy_objects/unset_010.phpt create mode 100644 Zend/tests/lazy_objects/use_case_001.phpt create mode 100644 Zend/tests/lazy_objects/use_case_001b.phpt create mode 100644 Zend/tests/lazy_objects/use_case_002.phpt create mode 100644 Zend/tests/lazy_objects/write_001.phpt create mode 100644 Zend/tests/lazy_objects/write_002.phpt create mode 100644 Zend/tests/lazy_objects/write_003.phpt create mode 100644 Zend/tests/lazy_objects/write_004.phpt create mode 100644 Zend/tests/lazy_objects/write_005.phpt create mode 100644 Zend/tests/lazy_objects/write_006.phpt create mode 100644 Zend/zend_lazy_objects.c create mode 100644 Zend/zend_lazy_objects.h diff --git a/Zend/tests/lazy_objects/003.phpt b/Zend/tests/lazy_objects/003.phpt new file mode 100644 index 0000000000000..589f5535a7324 --- /dev/null +++ b/Zend/tests/lazy_objects/003.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: readonly properties can be lazily initialized +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/004.phpt b/Zend/tests/lazy_objects/004.phpt new file mode 100644 index 0000000000000..bc71f687f05d7 --- /dev/null +++ b/Zend/tests/lazy_objects/004.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: readonly classes can be lazily initialized +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/005.phpt b/Zend/tests/lazy_objects/005.phpt new file mode 100644 index 0000000000000..050b55871e2d1 --- /dev/null +++ b/Zend/tests/lazy_objects/005.phpt @@ -0,0 +1,164 @@ +--TEST-- +Lazy objects: initializer must return the right type +--FILE-- +b = 1; + } + public function __destruct() { + } +} + +class C extends B { +} + +class D extends C { + public int $b; // override +} + +class E extends B { + public function __destruct() { // override + } +} + +print "# Ghost initializer must return NULL or no value:\n"; + +$obj = (new ReflectionClass(C::class))->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + return new stdClass; +}); + +var_dump($obj); +try { + var_dump($obj->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +var_dump($obj); + +print "# Virtual initializer must return an instance of a compatible class:\n"; +print "## Valid cases:\n"; + +$tests = [ + [C::class, new C()], + [C::class, new B()], + [D::class, new B()], +]; + +foreach ($tests as [$class, $instance]) { + $reflector = new ReflectionClass($class); + $obj = $reflector->newLazyProxy(function ($obj) use ($instance) { + var_dump("initializer"); + $instance->b = 1; + return $instance; + }); + + printf("## %s vs %s\n", get_class($obj), is_object($instance) ? get_class($instance) : gettype($instance)); + var_dump($obj->b); + var_dump($obj); +} + +print "## Invalid cases:\n"; + +$tests = [ + [C::class, new stdClass], + [C::class, new DateTime()], + [C::class, null], + [C::class, new D()], + [E::class, new B()], +]; + +foreach ($tests as [$class, $instance]) { + $obj = (new ReflectionClass($class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) use ($instance) { + var_dump("initializer"); + return $instance; + }); + + try { + printf("## %s vs %s\n", get_class($obj), is_object($instance) ? get_class($instance) : gettype($instance)); + var_dump($obj->a); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = (new ReflectionClass(C::class))->newLazyProxy(function ($obj) { + var_dump("initializer"); + return $obj; +}); + +try { + printf("## %s vs itself\n", get_class($obj)); + var_dump($obj->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost initializer must return NULL or no value: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +TypeError: Lazy object initializer must return NULL or no value +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Virtual initializer must return an instance of a compatible class: +## Valid cases: +## C vs C +string(11) "initializer" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(1) + } +} +## C vs B +string(11) "initializer" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(B)#%d (1) { + ["b"]=> + int(1) + } +} +## D vs B +string(11) "initializer" +int(1) +lazy proxy object(D)#%d (1) { + ["instance"]=> + object(B)#%d (1) { + ["b"]=> + int(1) + } +} +## Invalid cases: +## C vs stdClass +string(11) "initializer" +TypeError: The real instance class stdClass is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs DateTime +string(11) "initializer" +TypeError: The real instance class DateTime is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs NULL +string(11) "initializer" +TypeError: The real instance class null is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs D +string(11) "initializer" +TypeError: The real instance class D is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## E vs B +string(11) "initializer" +TypeError: The real instance class B is not compatible with the proxy class E. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs itself +string(11) "initializer" +Error: Lazy proxy factory must return a non-lazy object diff --git a/Zend/tests/lazy_objects/006.phpt b/Zend/tests/lazy_objects/006.phpt new file mode 100644 index 0000000000000..43211fa38e117 --- /dev/null +++ b/Zend/tests/lazy_objects/006.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: Foreach initializes object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) diff --git a/Zend/tests/lazy_objects/007.phpt b/Zend/tests/lazy_objects/007.phpt new file mode 100644 index 0000000000000..6dfdf1457f4cf --- /dev/null +++ b/Zend/tests/lazy_objects/007.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: var_dump does not initialize object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +$reflector->initializeLazyObject($obj); +var_dump($obj); + +print "# Virtual:\n"; + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +$reflector->initializeLazyObject($obj); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/008.phpt b/Zend/tests/lazy_objects/008.phpt new file mode 100644 index 0000000000000..56b1b30219b14 --- /dev/null +++ b/Zend/tests/lazy_objects/008.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: var_export initializes object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_export($obj); +print "\n"; + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_export($obj); +print "\n"; +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +\C::__set_state(array( + 'a' => 1, +)) +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +\C::__set_state(array( + 'a' => 1, +)) diff --git a/Zend/tests/lazy_objects/009.phpt b/Zend/tests/lazy_objects/009.phpt new file mode 100644 index 0000000000000..7f1263a50af70 --- /dev/null +++ b/Zend/tests/lazy_objects/009.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: serialize initializes object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(serialize($obj)); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(serialize($obj)); + + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/010.phpt b/Zend/tests/lazy_objects/010.phpt new file mode 100644 index 0000000000000..ad996a5a21191 --- /dev/null +++ b/Zend/tests/lazy_objects/010.phpt @@ -0,0 +1,42 @@ +--TEST-- +Lazy objects: json_encode initializes object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(json_encode($obj)); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(json_encode($obj)); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(7) "{"a":1}" +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(7) "{"a":1}" diff --git a/Zend/tests/lazy_objects/011.phpt b/Zend/tests/lazy_objects/011.phpt new file mode 100644 index 0000000000000..3636a53d19831 --- /dev/null +++ b/Zend/tests/lazy_objects/011.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: get_object_vars initializes object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(get_object_vars($obj)); + +$obj->a = 2; +var_dump(get_object_vars($obj)); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(get_object_vars($obj)); + +$obj->a = 2; +var_dump(get_object_vars($obj)); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["a"]=> + int(2) +} +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/012.phpt b/Zend/tests/lazy_objects/012.phpt new file mode 100644 index 0000000000000..ab8e5c5c3fcbe --- /dev/null +++ b/Zend/tests/lazy_objects/012.phpt @@ -0,0 +1,58 @@ +--TEST-- +Lazy objects: array cast does not initialize object +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump((array)$obj); + +$obj->a = 2; +var_dump((array)$obj); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump((array)$obj); + +$obj->a = 2; +var_dump((array)$obj); + +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} +# Virtual: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/013.phpt b/Zend/tests/lazy_objects/013.phpt new file mode 100644 index 0000000000000..8e92692169bc1 --- /dev/null +++ b/Zend/tests/lazy_objects/013.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: final classes can be initialized lazily +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/014.phpt b/Zend/tests/lazy_objects/014.phpt new file mode 100644 index 0000000000000..ec16a8bf9571c --- /dev/null +++ b/Zend/tests/lazy_objects/014.phpt @@ -0,0 +1,34 @@ +--TEST-- +Lazy objects: internal classes can not be initialized lazily +--FILE-- +newInstanceWithoutConstructor(); +try { + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(DateTime::class))->newInstanceWithoutConstructor(); +try { + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost: +Error: Cannot make instance of internal class lazy: DateTime is internal +# Virtual: +Error: Cannot make instance of internal class lazy: DateTime is internal diff --git a/Zend/tests/lazy_objects/015.phpt b/Zend/tests/lazy_objects/015.phpt new file mode 100644 index 0000000000000..727beb63ecb86 --- /dev/null +++ b/Zend/tests/lazy_objects/015.phpt @@ -0,0 +1,37 @@ +--TEST-- +Lazy objects: sub-classes of internal classes can not be initialized lazily +--FILE-- +newInstanceWithoutConstructor(); +try { + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Virtual:\n"; + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +try { + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost: +Error: Cannot make instance of internal class lazy: C inherits internal class DateTime +# Virtual: +Error: Cannot make instance of internal class lazy: C inherits internal class DateTime diff --git a/Zend/tests/lazy_objects/016.phpt b/Zend/tests/lazy_objects/016.phpt new file mode 100644 index 0000000000000..5efd48bdebff1 --- /dev/null +++ b/Zend/tests/lazy_objects/016.phpt @@ -0,0 +1,45 @@ +--TEST-- +Lazy objects: destructor of lazy objets is not called if not initialized +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { + var_dump("initializer"); +}); +print "After makeLazy\n"; + +// Does not call destructor +$obj = null; + +print "# Virtual:\n"; + +print "In makeLazy\n"; +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { + var_dump("initializer"); +}); +print "After makeLazy\n"; + +// Does not call destructor +$obj = null; + +--EXPECT-- +# Ghost: +In makeLazy +string(13) "C::__destruct" +After makeLazy +# Virtual: +In makeLazy +string(13) "C::__destruct" +After makeLazy diff --git a/Zend/tests/lazy_objects/017.phpt b/Zend/tests/lazy_objects/017.phpt new file mode 100644 index 0000000000000..e5ebc8aa50ad5 --- /dev/null +++ b/Zend/tests/lazy_objects/017.phpt @@ -0,0 +1,74 @@ +--TEST-- +Lazy objects: destructor of initialized objets is called +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { + var_dump("initializer"); + }); + print "After makeLazy\n"; + + var_dump($obj->a); +} + +function virtual() { + print "# Virtual:\n"; + + print "In makeLazy\n"; + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { + var_dump("initializer"); + return new C(); + }); + print "After makeLazy\n"; + + var_dump($obj->a); +} + +ghost(); +virtual(); + +--EXPECTF-- +# Ghost: +In makeLazy +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +In makeLazy +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/018.phpt b/Zend/tests/lazy_objects/018.phpt new file mode 100644 index 0000000000000..2ee1b6e2db630 --- /dev/null +++ b/Zend/tests/lazy_objects/018.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: exception during initializer leaves object uninitialized +--FILE-- +a); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + var_dump((new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + try { + var_dump($obj->a); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + var_dump((new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +initializer exception +bool(true) +string(11) "initializer" +initializer exception +bool(true) +# Virtual: +string(11) "initializer" +initializer exception +bool(true) +string(11) "initializer" +initializer exception +bool(true) diff --git a/Zend/tests/lazy_objects/019.phpt b/Zend/tests/lazy_objects/019.phpt new file mode 100644 index 0000000000000..819421f60afd4 --- /dev/null +++ b/Zend/tests/lazy_objects/019.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: get_mangled_object_vars does not initialize object +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump(get_mangled_object_vars($obj)); + + $obj->a = 2; + var_dump(get_mangled_object_vars($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} +# Virtual: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/020.phpt b/Zend/tests/lazy_objects/020.phpt new file mode 100644 index 0000000000000..a05f9a32d00ff --- /dev/null +++ b/Zend/tests/lazy_objects/020.phpt @@ -0,0 +1,80 @@ +--TEST-- +Lazy objects: dymamic properties are unset when object is made lazy +--FILE-- +a = new Canary(); + } +} + +print "# Ghost:\n"; + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +string(18) "Canary::__destruct" +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +object(Canary)#%d (0) { +} +object(C)#%d (2) { + ["b"]=> + NULL + ["a"]=> + object(Canary)#%d (0) { + } +} +# Virtual: +string(18) "Canary::__destruct" +string(18) "Canary::__destruct" +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +object(Canary)#%d (0) { +} +object(Canary)#%d (0) { +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + NULL + ["a"]=> + object(Canary)#%d (0) { + } + } +} +string(18) "Canary::__destruct" diff --git a/Zend/tests/lazy_objects/021.phpt b/Zend/tests/lazy_objects/021.phpt new file mode 100644 index 0000000000000..c4cc63c4a9743 --- /dev/null +++ b/Zend/tests/lazy_objects/021.phpt @@ -0,0 +1,81 @@ +--TEST-- +Lazy objects: reference source type is deleted by makeLazy() +--FILE-- +a = 1; + } +} + +print "# Ghost:\n"; + +$obj = new C(); +$ref = &$obj->a; +try { + $ref = 'string'; +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +$ref = 'string'; +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = new C(); +$ref = &$obj->a; +try { + $ref = 'string'; +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +$ret = 'string'; +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +TypeError: Cannot assign string to reference held by property C::$a of type int +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +TypeError: Cannot assign string to reference held by property C::$a of type int +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/024.phpt b/Zend/tests/lazy_objects/024.phpt new file mode 100644 index 0000000000000..548088394a650 --- /dev/null +++ b/Zend/tests/lazy_objects/024.phpt @@ -0,0 +1,36 @@ +--TEST-- +Lazy objects: fatal error during initialization of ghost object +--FILE-- +newInstanceWithoutConstructor(); +$reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +$reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, new stdClass); + +var_dump($obj); +var_dump($obj->c); +var_dump($obj); + +--EXPECTF-- +lazy ghost object(C)#%d (1) { + ["b"]=> + object(stdClass)#%d (0) { + } +} +string(11) "initializer" + +Parse error: Unclosed '{' in %s on line %d diff --git a/Zend/tests/lazy_objects/025.phpt b/Zend/tests/lazy_objects/025.phpt new file mode 100644 index 0000000000000..3f101dc5a2060 --- /dev/null +++ b/Zend/tests/lazy_objects/025.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: var_dump may not initialize object with __debugInfo() method +--FILE-- +a = 1; + } + public function __debugInfo() { + return ['hello']; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + var_dump($obj); + printf("Initialized:\n"); + var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost +lazy ghost object(C)#%d (1) { + [0]=> + string(5) "hello" +} +Initialized: +bool(false) +# Virtual +lazy proxy object(C)#%d (1) { + [0]=> + string(5) "hello" +} +Initialized: +bool(false) diff --git a/Zend/tests/lazy_objects/026.phpt b/Zend/tests/lazy_objects/026.phpt new file mode 100644 index 0000000000000..aea4a5003cf0c --- /dev/null +++ b/Zend/tests/lazy_objects/026.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: var_dump may initialize object with __debugInfo() method +--FILE-- +a = 1; + } + public function __debugInfo() { + return [$this->a]; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + var_dump($obj); + printf("Initialized:\n"); + var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + [0]=> + int(1) +} +Initialized: +bool(true) +# Virtual +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + [0]=> + int(1) +} +Initialized: +bool(true) diff --git a/Zend/tests/lazy_objects/027.phpt b/Zend/tests/lazy_objects/027.phpt new file mode 100644 index 0000000000000..0909942bcb284 --- /dev/null +++ b/Zend/tests/lazy_objects/027.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: debug_zval_dump does not initialize object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +debug_zval_dump($obj); +$reflector->initializeLazyObject($obj); +debug_zval_dump($obj); + +print "# Virtual:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +debug_zval_dump($obj); +$reflector->initializeLazyObject($obj); +debug_zval_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) refcount(2){ + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) refcount(2){ + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) refcount(2){ + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) refcount(2){ + ["instance"]=> + object(C)#%d (1) refcount(2){ + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_001.phpt b/Zend/tests/lazy_objects/clone_001.phpt new file mode 100644 index 0000000000000..c7ca01ba1168b --- /dev/null +++ b/Zend/tests/lazy_objects/clone_001.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: clone initializes object +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_002.phpt b/Zend/tests/lazy_objects/clone_002.phpt new file mode 100644 index 0000000000000..f2af4b241250e --- /dev/null +++ b/Zend/tests/lazy_objects/clone_002.phpt @@ -0,0 +1,77 @@ +--TEST-- +Lazy objects: clone calls __clone() once +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(5) "clone" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +string(5) "clone" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_003.phpt b/Zend/tests/lazy_objects/clone_003.phpt new file mode 100644 index 0000000000000..8334e6eadd84e --- /dev/null +++ b/Zend/tests/lazy_objects/clone_003.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: clone: initializer exception +--FILE-- +getMessage()); + } + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception('initializer'); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +Exception: initializer +bool(true) +lazy ghost object(C)#%d (0) { +} +# Virtual: +Exception: initializer +bool(true) +lazy proxy object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/clone_004.phpt b/Zend/tests/lazy_objects/clone_004.phpt new file mode 100644 index 0000000000000..30f802a7fd5f3 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_004.phpt @@ -0,0 +1,73 @@ +--TEST-- +Lazy objects: clone of initialized lazy object does not initialize twice +--FILE-- +initializeLazyObject($obj); + + $clone = clone $obj; + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_007.phpt b/Zend/tests/lazy_objects/clone_007.phpt new file mode 100644 index 0000000000000..9a350e6f01cd8 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_007.phpt @@ -0,0 +1,35 @@ +--TEST-- +Lazy objects: clone semantics +--FILE-- +newLazyProxy($initializer); +$reflector->getProperty('foo')->skipLazyInitialization($myProxy); + +$clonedProxy = clone $myProxy; +var_dump($clonedProxy->foo); + +$reflector->initializeLazyObject($myProxy); +$myProxy->foo = 'B'; + +$reflector->initializeLazyObject($clonedProxy); + +var_dump($myProxy->foo); +var_dump($clonedProxy->foo); + +--EXPECT-- +string(1) "A" +string(1) "B" +string(1) "A" diff --git a/Zend/tests/lazy_objects/clone_008.phpt b/Zend/tests/lazy_objects/clone_008.phpt new file mode 100644 index 0000000000000..7d0a73b135197 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_008.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: clone semantics +--FILE-- +value = new Value(); + } + public function __clone() { + $this->value = clone $this->value; + } +} + +class Value { + public string $value = 'A'; +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass(SomeObj::class); + + $clonedObj = clone $obj; + var_dump($clonedObj->value->value); + + $reflector->initializeLazyObject($obj); + $obj->value->value = 'B'; + + $reflector->initializeLazyObject($clonedObj); + + var_dump($obj->value->value); + var_dump($clonedObj->value->value); +} + +$reflector = new ReflectionClass(SomeObj::class); + +test('Ghost', $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +})); + +test('Proxy', $reflector->newLazyProxy(function () { + return new SomeObj(); +})); + +?> +--EXPECT-- +# Ghost: +string(1) "A" +string(1) "B" +string(1) "A" +# Proxy: +string(1) "A" +string(1) "B" +string(1) "A" diff --git a/Zend/tests/lazy_objects/clone_009.phpt b/Zend/tests/lazy_objects/clone_009.phpt new file mode 100644 index 0000000000000..3afad3e8104c1 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_009.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: clone semantics +--FILE-- +initializeLazyObject($obj); + $reflector->getProperty('foo')->setRawValueWithoutLazyInitialization($clonedObj, 'Y'); + + $reflector->initializeLazyObject($clonedObj); + + var_dump($clonedObj->foo); +} + +$reflector = new ReflectionClass(SomeObj::class); + +test('Ghost', $reflector->newLazyGhost(function ($obj) { +})); + +test('Proxy', $reflector->newLazyProxy(function () { + return new SomeObj(); +})); + +?> +--EXPECT-- +# Ghost: +string(1) "Y" +# Proxy: +string(1) "Y" diff --git a/Zend/tests/lazy_objects/feedback_001.phpt b/Zend/tests/lazy_objects/feedback_001.phpt new file mode 100644 index 0000000000000..f33549b84922a --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_001.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: feedback 001 +--FILE-- +foo = new Foo(); + +$reflector = new ReflectionClass(Bar::class); + +print "Reset\n"; + +$reflector->resetAsLazyProxy($bar, function (Bar $bar) { + $result = new Bar(); + $result->foo = null; + $result->s = 'init'; + return $result; +}); + +print "Dump\n"; + +var_dump($bar->s); + +print "Done\n"; + +?> +--EXPECT-- +Reset +Bar::__destruct +Foo::__destruct +Dump +string(4) "init" +Done +Bar::__destruct diff --git a/Zend/tests/lazy_objects/feedback_002.phpt b/Zend/tests/lazy_objects/feedback_002.phpt new file mode 100644 index 0000000000000..76138e8656a75 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_002.phpt @@ -0,0 +1,36 @@ +--TEST-- +Lazy objects: feedback 002 +--FILE-- +foo = $this; + var_dump(__METHOD__); + } + public function __destruct() { + var_dump(__METHOD__); + } +} + +$reflector = new ReflectionClass(Foo::class); +$foo = $reflector->newLazyGhost(new Initializer()); + +print "Dump\n"; + +var_dump($foo->foo); + +print "Done\n"; + +?> +--EXPECTF-- +Dump +string(21) "Initializer::__invoke" +object(Initializer)#%d (0) { +} +Done +string(23) "Initializer::__destruct" diff --git a/Zend/tests/lazy_objects/feedback_003.phpt b/Zend/tests/lazy_objects/feedback_003.phpt new file mode 100644 index 0000000000000..e3b16703fdf23 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_003.phpt @@ -0,0 +1,33 @@ +--TEST-- +Lazy objects: feedback 003 +--FILE-- +newLazyProxy(function (B $o) { + return new A(); +}); + +var_dump(get_class($o)); +$o->foo(); +$o->s = 'init'; +var_dump(get_class($o)); +$o->foo(); + + +?> +--EXPECT-- +string(1) "B" +string(6) "B::foo" +string(1) "B" +string(6) "B::foo" diff --git a/Zend/tests/lazy_objects/feedback_004.phpt b/Zend/tests/lazy_objects/feedback_004.phpt new file mode 100644 index 0000000000000..fb6d2e31fe0e0 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_004.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: feedback 004 +--FILE-- +resetAsLazyProxy($object, function (MyObject $object) use (&$object2Id) { + $object2 = new MyObject(); + $object2Id = spl_object_id($object2); + return $object2; +}); +var_dump(spl_object_id($object) === $objectId); +$reflector->initializeLazyObject($object); +var_dump(spl_object_id($object) === $objectId); +var_dump(spl_object_id($object) !== $object2Id); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/lazy_objects/feedback_005.phpt b/Zend/tests/lazy_objects/feedback_005.phpt new file mode 100644 index 0000000000000..83454e70a7c96 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_005.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: feedback 005 +--FILE-- +newLazyGhost(function ($c) { + $c->c = 1; +}); + +$b = $bReflector->newLazyGhost(function () { + throw new \Exception('xxx'); +}); + +$a = $aReflector->newLazyGhost(function ($a) use ($b, $c) { + $a->a = $c->c + $b->b; +}); + +try { + $a->init = 'please'; +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +var_dump($a, $b, $c); + +?> +--EXPECTF-- +Exception: xxx +lazy ghost object(A)#%d (0) { +} +lazy ghost object(B)#%d (0) { +} +object(C)#%d (1) { + ["c"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/feedback_006.phpt b/Zend/tests/lazy_objects/feedback_006.phpt new file mode 100644 index 0000000000000..64d1ae00938e3 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_006.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: feedback 006 +--FILE-- +foo; + } +} + +$r = new ReflectionClass(B::class); +$obj = $r->newLazyProxy(function ($obj) { + return new A(); +}); + +try { + $obj->getFoo(); +} catch (\Throwable $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECT-- +TypeError: The real instance class A is not compatible with the proxy class B. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. diff --git a/Zend/tests/lazy_objects/feedback_007.phpt b/Zend/tests/lazy_objects/feedback_007.phpt new file mode 100644 index 0000000000000..f59e56b2fd500 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_007.phpt @@ -0,0 +1,31 @@ +--TEST-- +Lazy objects: feedback 007 +--FILE-- +foo(); } + +$r = new ReflectionClass(B::class); +$b = $r->newLazyProxy(function ($obj) { + return new A('value'); +}); + +$b->property = 'init_please'; + +$clone = clone $b; +only_b($b); +only_b($clone); + +?> +==DONE== +--EXPECT-- +==DONE== diff --git a/Zend/tests/lazy_objects/feedback_008.phpt b/Zend/tests/lazy_objects/feedback_008.phpt new file mode 100644 index 0000000000000..d309a2cd67d91 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_008.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: feedback 008 +--FILE-- +resetAsLazyProxy($obj, function () { + return new Obj('obj2'); +}); +$r->initializeLazyObject($obj); +var_dump($obj); +$r->resetAsLazyProxy($obj, function () { + return new Obj('obj3'); +}); +var_dump($obj); +$r->initializeLazyObject($obj); +var_dump($obj); + +?> +==DONE== +--EXPECTF-- +object(Obj)#%d (1) { + ["name"]=> + string(4) "obj1" +} +lazy proxy object(Obj)#%d (1) { + ["instance"]=> + object(Obj)#%d (1) { + ["name"]=> + string(4) "obj2" + } +} +lazy proxy object(Obj)#%d (0) { + ["name"]=> + uninitialized(string) +} +lazy proxy object(Obj)#%d (1) { + ["instance"]=> + object(Obj)#%d (1) { + ["name"]=> + string(4) "obj3" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/feedback_009.phpt b/Zend/tests/lazy_objects/feedback_009.phpt new file mode 100644 index 0000000000000..f5da04cd6d320 --- /dev/null +++ b/Zend/tests/lazy_objects/feedback_009.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: feedback 009 +--FILE-- +resetAsLazyProxy($obj1, function () use (&$obj2) { + $obj2 = new Obj('obj2'); + return $obj2; +}); +$r->initializeLazyObject($obj1); +$r->resetAsLazyProxy($obj2, function () { + return new Obj('obj3'); +}); +var_dump($obj1->name); + +?> +==DONE== +--EXPECT-- +string(4) "obj3" +==DONE== diff --git a/Zend/tests/lazy_objects/fetch_001.phpt b/Zend/tests/lazy_objects/fetch_001.phpt new file mode 100644 index 0000000000000..d89cba11d4481 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_001.phpt @@ -0,0 +1,72 @@ +--TEST-- +Lazy objects: property fetch initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_002.phpt b/Zend/tests/lazy_objects/fetch_002.phpt new file mode 100644 index 0000000000000..fda287265948e --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_002.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property fetch of dynamic property initializes object +--FILE-- +dynamic); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (0) { + ["a"]=> + uninitialized(int) + } +} diff --git a/Zend/tests/lazy_objects/fetch_003.phpt b/Zend/tests/lazy_objects/fetch_003.phpt new file mode 100644 index 0000000000000..d24af36221a0f --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_003.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property op initializes object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a++); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%s (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/fetch_004.phpt b/Zend/tests/lazy_objects/fetch_004.phpt new file mode 100644 index 0000000000000..892850fed5f0f --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_004.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: dynamic property op initializes object +--FILE-- +dynamic++); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (2) { + ["a"]=> + int(1) + ["dynamic"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["dynamic"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_005.phpt b/Zend/tests/lazy_objects/fetch_005.phpt new file mode 100644 index 0000000000000..11b8d463ced95 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_005.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: magic property fetch may not initialize object +--FILE-- +magic); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(5) "magic" +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(5) "magic" +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_006.phpt b/Zend/tests/lazy_objects/fetch_006.phpt new file mode 100644 index 0000000000000..ecf5ab123b4bf --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_006.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: magic property fetch may initialize object +--FILE-- +a; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->magic); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_007.phpt b/Zend/tests/lazy_objects/fetch_007.phpt new file mode 100644 index 0000000000000..abdb8212a11b2 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_007.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: recursive magic property fetch may initialize object +--FILE-- +$name; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->magic); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" + +Warning: Undefined property: C::$magic in %s on line %d +NULL +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" + +Warning: Undefined property: C::$magic in %s on line %d +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_008.phpt b/Zend/tests/lazy_objects/fetch_008.phpt new file mode 100644 index 0000000000000..1a87364e8ded5 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_008.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: property fetch coalesce initializes object +--FILE-- +a ?? null); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_009.phpt b/Zend/tests/lazy_objects/fetch_009.phpt new file mode 100644 index 0000000000000..d4316320c6e9d --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_009.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: property fetch coalesce on non existing property initializes object +--FILE-- +unknown ?? null); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_010.phpt b/Zend/tests/lazy_objects/fetch_010.phpt new file mode 100644 index 0000000000000..6fb013c3ff1b2 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_010.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property fetch ref initializes object +--FILE-- +a; + var_dump($ref); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + &int(1) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + &int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_011.phpt b/Zend/tests/lazy_objects/fetch_011.phpt new file mode 100644 index 0000000000000..077a11a2f60ff --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_011.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: dynamic property op error +--FILE-- +dynamic++); + } catch(Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + throw new Error("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + throw new Error("initializer"); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_012.phpt b/Zend/tests/lazy_objects/fetch_012.phpt new file mode 100644 index 0000000000000..8c3b591350f80 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_012.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: property op error +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + + try { + var_dump($obj->a++); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + throw new Error("initializer"); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + throw new Error("initializer"); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_013.phpt b/Zend/tests/lazy_objects/fetch_013.phpt new file mode 100644 index 0000000000000..96faaf3f19d10 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_013.phpt @@ -0,0 +1,93 @@ +--TEST-- +Lazy objects: fetch skipped property does not initialize object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj->b); + try { + var_dump($obj->c); + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +# Virtual: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_014.phpt b/Zend/tests/lazy_objects/fetch_014.phpt new file mode 100644 index 0000000000000..0320a073039b6 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_014.phpt @@ -0,0 +1,91 @@ +--TEST-- +Lazy objects: property op on skipped property does not initialize object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + var_dump($obj->a++); + var_dump($obj->b++); + try { + var_dump($obj->c++); + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new c(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + uninitialized(int) +} +# Virtual: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_015.phpt b/Zend/tests/lazy_objects/fetch_015.phpt new file mode 100644 index 0000000000000..c4c77a679329b --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_015.phpt @@ -0,0 +1,87 @@ +--TEST-- +Lazy objects: fetch ref on skipped property does not initialize object +--FILE-- +a; + $ref = &$obj->b; + try { + $ref = &$obj->c; + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($ref); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +Cannot access uninitialized non-nullable property C::$c by reference +int(1) +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + &int(1) + ["c"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +Cannot access uninitialized non-nullable property C::$c by reference +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + &int(1) + ["c"]=> + uninitialized(int) + } +} diff --git a/Zend/tests/lazy_objects/fetch_016.phpt b/Zend/tests/lazy_objects/fetch_016.phpt new file mode 100644 index 0000000000000..5e27cb77a5abc --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_016.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: hooked property fetch may initialize object +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_017.phpt b/Zend/tests/lazy_objects/fetch_017.phpt new file mode 100644 index 0000000000000..88d40a59101ac --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_017.phpt @@ -0,0 +1,76 @@ +--TEST-- +Lazy objects: virtual hooked property fetch may initialize object +--FILE-- +_a; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->_a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $a = &$obj->a; + var_dump($a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["_a"]=> + &int(1) + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["_a"]=> + &int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_018.phpt b/Zend/tests/lazy_objects/fetch_018.phpt new file mode 100644 index 0000000000000..c66d657dfcd0f --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_018.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: virtual hooked property fetch may not initialize object +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +int(1) +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +int(1) +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/gc_001.phpt b/Zend/tests/lazy_objects/gc_001.phpt new file mode 100644 index 0000000000000..db4ab41b8587e --- /dev/null +++ b/Zend/tests/lazy_objects/gc_001.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: GC 001 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +function virtual() { + printf("# Virtual:\n"); + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +ghost(); +virtual(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Virtual: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_002.phpt b/Zend/tests/lazy_objects/gc_002.phpt new file mode 100644 index 0000000000000..004907c483adb --- /dev/null +++ b/Zend/tests/lazy_objects/gc_002.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: GC 002 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary->value = $obj; + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +function virtual() { + printf("# Virtual:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary->value = $obj; + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +ghost(); +virtual(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Virtual: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_003.phpt b/Zend/tests/lazy_objects/gc_003.phpt new file mode 100644 index 0000000000000..a17765a503d7a --- /dev/null +++ b/Zend/tests/lazy_objects/gc_003.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: GC 003 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function virtual() { + printf("# Virtual:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +virtual(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Virtual: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_004.phpt b/Zend/tests/lazy_objects/gc_004.phpt new file mode 100644 index 0000000000000..f0e64f39de698 --- /dev/null +++ b/Zend/tests/lazy_objects/gc_004.phpt @@ -0,0 +1,67 @@ +--TEST-- +Lazy objects: GC 004 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + var_dump($obj); // initializes property hash + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function virtual() { + printf("# Virtual:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + var_dump($obj); // initializes property hash + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +virtual(); + +?> +==DONE== +--EXPECTF-- +# Ghost: +object(C)#%d (0) { +} +string(10) "__destruct" +# Virtual: +object(C)#%d (0) { +} +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_005.phpt b/Zend/tests/lazy_objects/gc_005.phpt new file mode 100644 index 0000000000000..70a20759248bf --- /dev/null +++ b/Zend/tests/lazy_objects/gc_005.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: GC 005 +--FILE-- +newInstanceWithoutConstructor(); + $reflector->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $reflector->getProperty('value')->setRawValueWithoutLazyInitialization($obj, $obj); + $reflector = null; + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function virtual() { + printf("# Virtual:\n"); + + $canary = new Canary(); + + $reflector = new ReflectionClass(C::class); + $obj = $reflector->newInstanceWithoutConstructor(); + $reflector->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $reflector->getProperty('value')->setRawValueWithoutLazyInitialization($obj, $obj); + $reflector = null; + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +virtual(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Virtual: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/get_initializer.phpt b/Zend/tests/lazy_objects/get_initializer.phpt new file mode 100644 index 0000000000000..30b410be0a6f9 --- /dev/null +++ b/Zend/tests/lazy_objects/get_initializer.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: getLazyInitializer() returns initializer +--FILE-- +init(...), +]; + +foreach ($initializers as $i => $initializer) { + $c = $reflector->newLazyGhost($initializer); + if ($reflector->getLazyInitializer($c) !== $initializer) { + printf("Initializer %d: failed\n", $i); + continue; + } + + $reflector->initializeLazyObject($c); + if ($reflector->getLazyInitializer($c) !== null) { + printf("Initializer %d: failed\n", $i); + continue; + } + + printf("Initializer %d: ok\n", $i); +} + +?> +--EXPECT-- +Initializer 0: ok +Initializer 1: ok +Initializer 2: ok +Initializer 3: ok +Initializer 4: ok +Initializer 5: ok +Initializer 6: ok diff --git a/Zend/tests/lazy_objects/ghost_001.phpt b/Zend/tests/lazy_objects/ghost_001.phpt new file mode 100644 index 0000000000000..c7c116e487356 --- /dev/null +++ b/Zend/tests/lazy_objects/ghost_001.phpt @@ -0,0 +1,46 @@ +--TEST-- +Lazy objects: default values are initialized before calling initializer +--FILE-- +a = 3; + $this->b = 4; + } +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + var_dump($obj); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); +--EXPECTF-- +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +string(14) "C::__construct" +int(3) +object(C)#%d (2) { + ["a"]=> + int(3) + ["b"]=> + int(4) +} diff --git a/Zend/tests/lazy_objects/ghost_002.phpt b/Zend/tests/lazy_objects/ghost_002.phpt new file mode 100644 index 0000000000000..8c818c035a841 --- /dev/null +++ b/Zend/tests/lazy_objects/ghost_002.phpt @@ -0,0 +1,45 @@ +--TEST-- +Lazy objects: properties may be left uninitialized by the initializer +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +try { + var_dump($obj->b); +} catch (Error $e) { + printf("%s\n", $e); +} +var_dump($obj); +--EXPECTF-- +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +Error: Typed property C::$b must not be accessed before initialization in %s:%d +Stack trace: +#0 {main} +object(C)#%d (1) { + ["a"]=> + NULL + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/init_exception_001.phpt b/Zend/tests/lazy_objects/init_exception_001.phpt new file mode 100644 index 0000000000000..f2e994fc05292 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_001.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: Object is still lazy after initializer exception +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +initializer exception +Is lazy: 1 +# Virtual: +string(11) "initializer" +initializer exception +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_002.phpt b/Zend/tests/lazy_objects/init_exception_002.phpt new file mode 100644 index 0000000000000..e14a873b3f9cb --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_002.phpt @@ -0,0 +1,72 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + (new ReflectionClass($obj))->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the virtual proxy are not reverted +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Virtual: +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_003.phpt b/Zend/tests/lazy_objects/init_exception_003.phpt new file mode 100644 index 0000000000000..26eabc8bf4204 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_003.phpt @@ -0,0 +1,83 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (properties hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + // Builds properties hashtable + var_dump(get_mangled_object_vars($obj)); + + try { + (new ReflectionClass($obj))->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the virtual proxy are not reverted +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Virtual: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_005.phpt b/Zend/tests/lazy_objects/init_exception_005.phpt new file mode 100644 index 0000000000000..db5b6dabefb6d --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_005.phpt @@ -0,0 +1,77 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (dynamic properties) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + (new ReflectionClass($obj))->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the virtual proxy are not reverted +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Virtual: +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (4) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) + ["d"]=> + int(6) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_006.phpt b/Zend/tests/lazy_objects/init_exception_006.phpt new file mode 100644 index 0000000000000..28ff9331ceb20 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_006.phpt @@ -0,0 +1,84 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (dynamic properties, initialized hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + (new ReflectionClass($obj))->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the virtual proxy are not reverted +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Virtual: +array(0) { +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (4) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) + ["d"]=> + int(6) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_009.phpt b/Zend/tests/lazy_objects/init_exception_009.phpt new file mode 100644 index 0000000000000..ad6c4232214a6 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_009.phpt @@ -0,0 +1,95 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (properties hashtable referenced after initializer) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + // Builds properties hashtable + var_dump(get_mangled_object_vars($obj)); + + try { + (new ReflectionClass($obj))->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + + var_dump($table); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + global $table; + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $table = (array) $obj; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + global $table; + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $table = (array) $obj; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the virtual proxy are not reverted +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 + +Warning: Undefined variable $table in %s on line %d +NULL +# Virtual: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 + +Warning: Undefined variable $table in %s on line %d +NULL diff --git a/Zend/tests/lazy_objects/init_exception_010.phpt b/Zend/tests/lazy_objects/init_exception_010.phpt new file mode 100644 index 0000000000000..788d92ec6e6b5 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_010.phpt @@ -0,0 +1,100 @@ +--TEST-- +Lazy objects: Pre-initialization reference source types are properly handled (no initialization exception) +--FILE-- +a = null; + unset($this->b); + $this->b = null; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $r = new ReflectionClass($obj); + $r->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $refA = &$obj->a; + $r->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $refB = &$obj->b; + + var_dump($obj); + var_dump($obj->c); + var_dump($obj); + + try { + // $refA retained its reference source type (except for the virtual + // case: its the responsibility of the initializer to propagate + // pre-initialized properties to the instance) + $refA = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->a); + $refA = 1; + + $refB = 1; + +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +$r = (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(null); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +NULL +object(C)#%d (3) { + ["a"]=> + &NULL + ["b"]=> + NULL + ["c"]=> + NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +# Virtual: +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (3) { + ["a"]=> + NULL + ["b"]=> + NULL + ["c"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/init_exception_011.phpt b/Zend/tests/lazy_objects/init_exception_011.phpt new file mode 100644 index 0000000000000..de6c5ff5fd61e --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_011.phpt @@ -0,0 +1,108 @@ +--TEST-- +Lazy objects: Pre-initialization reference source types are properly handled after initializer exception +--FILE-- +b); + throw new \Exception('initializer exception'); + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $r = new ReflectionClass($obj); + $r->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $refA = &$obj->a; + $r->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $refB = &$obj->b; + + var_dump($obj); + try { + var_dump($obj->c); + } catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump($obj); + + try { + // $refA retained its reference source type (except for the virtual + // case: it is the responsibility of the initializer to propagate + // pre-initialized properties to the instance) + $refA = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->a); + $refA = 1; + + try { + // $refB retained its reference source type + $refB = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->b); + $refB = 1; + +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +$r = (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(null); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +Exception: initializer exception +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +TypeError: Cannot assign int to reference held by property C::$b of type ?C +# Virtual: +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +Exception: initializer exception +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +TypeError: Cannot assign int to reference held by property C::$b of type ?C diff --git a/Zend/tests/lazy_objects/init_exception_012.phpt b/Zend/tests/lazy_objects/init_exception_012.phpt new file mode 100644 index 0000000000000..245cfa64e0470 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_012.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: Object is still lazy after initializer exception (overridden prop) +--FILE-- +getProperty('b')->skipLazyInitialization($obj); + $i = 5; + $obj->b = &$i; + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +initializer exception +Is lazy: 1 +# Virtual: +string(11) "initializer" +initializer exception +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/initialize_001.phpt b/Zend/tests/lazy_objects/initialize_001.phpt new file mode 100644 index 0000000000000..5f1966974af3e --- /dev/null +++ b/Zend/tests/lazy_objects/initialize_001.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() +--FILE-- +isUninitializedLazyObject($obj)); + + var_dump($reflector?->initializeLazyObject($obj)); + + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +Initialized: +bool(false) +string(11) "initializer" +object(C)#%d (1) { + ["a"]=> + int(1) +} +Initialized: +bool(true) +# Virtual: +Initialized: +bool(false) +string(11) "initializer" +object(C)#%d (1) { + ["a"]=> + int(1) +} +Initialized: +bool(true) diff --git a/Zend/tests/lazy_objects/initialize_002.phpt b/Zend/tests/lazy_objects/initialize_002.phpt new file mode 100644 index 0000000000000..867b2d54b53d9 --- /dev/null +++ b/Zend/tests/lazy_objects/initialize_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() on an initialized object is a no-op +--FILE-- +a); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($reflector?->initializeLazyObject($obj)); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +int(1) +bool(true) +object(C)#2 (1) { + ["a"]=> + int(1) +} +bool(true) +# Virtual: +string(11) "initializer" +int(1) +bool(true) +object(C)#4 (1) { + ["a"]=> + int(1) +} +bool(true) diff --git a/Zend/tests/lazy_objects/initialize_005.phpt b/Zend/tests/lazy_objects/initialize_005.phpt new file mode 100644 index 0000000000000..a2449aec79125 --- /dev/null +++ b/Zend/tests/lazy_objects/initialize_005.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() error +--FILE-- +isUninitializedLazyObject($obj)); + + try { + var_dump($reflector?->initializeLazyObject($obj)); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +bool(false) +string(11) "initializer" +initializer exception +bool(false) +# Virtual: +bool(false) +string(11) "initializer" +initializer exception +bool(false) diff --git a/Zend/tests/lazy_objects/is_initialized_001.phpt b/Zend/tests/lazy_objects/is_initialized_001.phpt new file mode 100644 index 0000000000000..d121417a889db --- /dev/null +++ b/Zend/tests/lazy_objects/is_initialized_001.phpt @@ -0,0 +1,26 @@ +--TEST-- +Lazy objects: ReflectionClass::isInitialized +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +$reflector = new ReflectionClass($obj); +var_dump(!$reflector->isUninitializedLazyObject($obj)); + +var_dump($obj->a); + +var_dump(!$reflector->isUninitializedLazyObject($obj)); +--EXPECTF-- +bool(false) +string(11) "initializer" +int(1) +bool(true) diff --git a/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt b/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt new file mode 100644 index 0000000000000..62fd7c1c70542 --- /dev/null +++ b/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt @@ -0,0 +1,31 @@ +--TEST-- +Lazy objects: isUninitializedLazyObject() +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function () {}); +var_dump($reflector->isUninitializedLazyObject($obj)); +$reflector->initializeLazyObject($obj); +var_dump($reflector->isUninitializedLazyObject($obj)); + +$obj = $reflector->newLazyProxy(function () { return new C(); }); +var_dump($reflector->isUninitializedLazyObject($obj)); +$reflector->initializeLazyObject($obj); +var_dump($reflector->isUninitializedLazyObject($obj)); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) diff --git a/Zend/tests/lazy_objects/isset_001.phpt b/Zend/tests/lazy_objects/isset_001.phpt new file mode 100644 index 0000000000000..3f9c918c9ebfc --- /dev/null +++ b/Zend/tests/lazy_objects/isset_001.phpt @@ -0,0 +1,72 @@ +--TEST-- +Lazy objects: property isset initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/isset_002.phpt b/Zend/tests/lazy_objects/isset_002.phpt new file mode 100644 index 0000000000000..39722791e5687 --- /dev/null +++ b/Zend/tests/lazy_objects/isset_002.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: hooked property isset may initialize object +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/isset_003.phpt b/Zend/tests/lazy_objects/isset_003.phpt new file mode 100644 index 0000000000000..9ade21d693e1e --- /dev/null +++ b/Zend/tests/lazy_objects/isset_003.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: hooked property isset may not initialize object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +bool(true) +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +bool(true) +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/make_lazy_already_exception.phpt b/Zend/tests/lazy_objects/make_lazy_already_exception.phpt new file mode 100644 index 0000000000000..5dc8fb675d550 --- /dev/null +++ b/Zend/tests/lazy_objects/make_lazy_already_exception.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: makeLazy() on already lazy object is not allowed +--FILE-- +resetAsLazyGhost($obj, function () {}); + +try { + $r->resetAsLazyGhost($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +printf("# Virtual:\n"); + +$obj = new C(); +$r->resetAsLazyProxy($obj, function () {}); + +try { + $r->resetAsLazyProxy($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +$obj = new C(); +$r->resetAsLazyProxy($obj, function () { + return new C(); +}); +$r->initializeLazyObject($obj); + +try { + $r->resetAsLazyProxy($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +==DONE== +--EXPECT-- +# Ghost: +ReflectionException: Object is already lazy +# Virtual: +ReflectionException: Object is already lazy +==DONE== diff --git a/Zend/tests/lazy_objects/make_lazy_destructor_001.phpt b/Zend/tests/lazy_objects/make_lazy_destructor_001.phpt new file mode 100644 index 0000000000000..e5400d7f51126 --- /dev/null +++ b/Zend/tests/lazy_objects/make_lazy_destructor_001.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: makeLazy calls destructor of pre-existing object +--FILE-- +a = 1; + } + + public function __destruct() { + var_dump(__METHOD__); + } +} + +print "# Ghost:\n"; + +$obj = new C(); +print "In makeLazy\n"; +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +print "# Virtual:\n"; + +$obj = new C(); +print "In makeLazy\n"; +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +?> +--EXPECT-- +# Ghost: +In makeLazy +string(13) "C::__destruct" +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +# Virtual: +In makeLazy +string(13) "C::__destruct" +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" diff --git a/Zend/tests/lazy_objects/make_lazy_destructor_002.phpt b/Zend/tests/lazy_objects/make_lazy_destructor_002.phpt new file mode 100644 index 0000000000000..bc964d5ea2925 --- /dev/null +++ b/Zend/tests/lazy_objects/make_lazy_destructor_002.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: makeLazy calls destructor of pre-existing object, unless SKIP_DESTRUCTOR flag is used +--FILE-- +a = 1; + } + + public function __destruct() { + var_dump(__METHOD__); + } +} + +print "# Ghost:\n"; + +$obj = new C(); +print "In makeLazy\n"; +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}, ReflectionClass::SKIP_DESTRUCTOR); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +print "# Virtual:\n"; + +$obj = new C(); +print "In makeLazy\n"; +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}, ReflectionClass::SKIP_DESTRUCTOR); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +?> +--EXPECT-- +# Ghost: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +# Virtual: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" diff --git a/Zend/tests/lazy_objects/make_lazy_destructor_003.phpt b/Zend/tests/lazy_objects/make_lazy_destructor_003.phpt new file mode 100644 index 0000000000000..4a0653ba327ec --- /dev/null +++ b/Zend/tests/lazy_objects/make_lazy_destructor_003.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: Destructor exception in makeLazy +--FILE-- +a = 1; + } + + public function __destruct() { + throw new \Exception(__METHOD__); + } +} + +print "# Ghost:\n"; + +$obj = new C(); +try { + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +// Object was not made lazy +var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + +print "# Virtual:\n"; + +$obj = new C(); +try { + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +// Object was not made lazy +var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + +?> +--EXPECT-- +# Ghost: +Exception: C::__destruct +bool(true) +# Virtual: +Exception: C::__destruct +bool(true) diff --git a/Zend/tests/lazy_objects/mark_as_initialized_001.phpt b/Zend/tests/lazy_objects/mark_as_initialized_001.phpt new file mode 100644 index 0000000000000..b31852b49ff35 --- /dev/null +++ b/Zend/tests/lazy_objects/mark_as_initialized_001.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: markLazyObjectAsInitialized() initializes properties to their default value and skips initializer +--FILE-- +isUninitializedLazyObject($obj)); + + printf("markLazyObjectAsInitialized(true) returns \$obj:\n"); + var_dump($reflector?->markLazyObjectAsInitialized($obj) === $obj); + + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +Initialized: +bool(false) +markLazyObjectAsInitialized(true) returns $obj: +bool(true) +Initialized: +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +Initialized: +bool(false) +markLazyObjectAsInitialized(true) returns $obj: +bool(true) +Initialized: +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/new_instance_lazy_001.phpt b/Zend/tests/lazy_objects/new_instance_lazy_001.phpt new file mode 100644 index 0000000000000..32c2e1680c65c --- /dev/null +++ b/Zend/tests/lazy_objects/new_instance_lazy_001.phpt @@ -0,0 +1,20 @@ +--TEST-- +Lazy objects: newInstanceLazy can not instantiate internal classes +--FILE-- +newInstanceWithoutConstructor(); + +foreach (['resetAsLazyGhost', 'resetAsLazyProxy'] as $strategy) { + try { + $reflector->$strategy($obj, function ($obj) { + var_dump("initializer"); + }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} +--EXPECT-- +Error: Cannot make instance of internal class lazy: ReflectionClass is internal +Error: Cannot make instance of internal class lazy: ReflectionClass is internal diff --git a/Zend/tests/lazy_objects/new_instance_lazy_002.phpt b/Zend/tests/lazy_objects/new_instance_lazy_002.phpt new file mode 100644 index 0000000000000..c8f3463c94edc --- /dev/null +++ b/Zend/tests/lazy_objects/new_instance_lazy_002.phpt @@ -0,0 +1,21 @@ +--TEST-- +Lazy objects: newInstanceLazy can not instantiate sub-class of internal classes +--FILE-- +newInstanceWithoutConstructor(); + try { + $reflector->$strategy($obj, function ($obj) { + var_dump("initializer"); + }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} +--EXPECT-- +Error: Cannot make instance of internal class lazy: C inherits internal class ReflectionClass +Error: Cannot make instance of internal class lazy: C inherits internal class ReflectionClass diff --git a/Zend/tests/lazy_objects/new_instance_lazy_003.phpt b/Zend/tests/lazy_objects/new_instance_lazy_003.phpt new file mode 100644 index 0000000000000..00516a19b737f --- /dev/null +++ b/Zend/tests/lazy_objects/new_instance_lazy_003.phpt @@ -0,0 +1,22 @@ +--TEST-- +Lazy objects: newInstanceLazy can instantiate sub-class of user classes +--FILE-- +newInstanceWithoutConstructor(); + $reflector->$strategy($obj, function ($obj) { + var_dump("initializer"); + }); + var_dump($obj); +} + +--EXPECTF-- +object(C)#%d (0) { +} +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/new_instance_lazy_004.phpt b/Zend/tests/lazy_objects/new_instance_lazy_004.phpt new file mode 100644 index 0000000000000..c4782b46b943d --- /dev/null +++ b/Zend/tests/lazy_objects/new_instance_lazy_004.phpt @@ -0,0 +1,18 @@ +--TEST-- +Lazy objects: newInstanceLazy can instantiate stdClass +--FILE-- +newInstanceWithoutConstructor(); + $reflector->$strategy($obj, function ($obj) { + var_dump("initializer"); + }); + var_dump($obj); +} +--EXPECTF-- +object(stdClass)#%d (0) { +} +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/new_instance_lazy_005.phpt b/Zend/tests/lazy_objects/new_instance_lazy_005.phpt new file mode 100644 index 0000000000000..fb028149c021b --- /dev/null +++ b/Zend/tests/lazy_objects/new_instance_lazy_005.phpt @@ -0,0 +1,21 @@ +--TEST-- +Lazy objects: newInstanceLazy can instantiate sub-class of stdClass +--FILE-- +newInstanceWithoutConstructor(); + $reflector->$strategy($obj, function ($obj) { + var_dump("initializer"); + }); + var_dump($obj); +} + +--EXPECTF-- +object(C)#%d (0) { +} +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/object_with_ast_const_001.phpt b/Zend/tests/lazy_objects/object_with_ast_const_001.phpt new file mode 100644 index 0000000000000..018c46e4915e5 --- /dev/null +++ b/Zend/tests/lazy_objects/object_with_ast_const_001.phpt @@ -0,0 +1,27 @@ +--TEST-- +Lazy objects: Class constants are updated before initialization +--FILE-- +newLazyGhost(function () { }); + +function f() { + define('FOO', new stdClass); +} + +f(); + +try { + var_dump($c->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/object_with_ast_const_002.phpt b/Zend/tests/lazy_objects/object_with_ast_const_002.phpt new file mode 100644 index 0000000000000..d3f1ca0f35f5c --- /dev/null +++ b/Zend/tests/lazy_objects/object_with_ast_const_002.phpt @@ -0,0 +1,26 @@ +--TEST-- +Lazy objects: Class constants are updated before initialization: update constant failure +--FILE-- +newLazyGhost(function () { }); + +function f() { + define('FOO', new stdClass); +} + +f(); + +try { + var_dump($c->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +TypeError: Cannot assign stdClass to property C::$a of type C diff --git a/Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt b/Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt new file mode 100644 index 0000000000000..3858f3ff4216c --- /dev/null +++ b/Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt @@ -0,0 +1,90 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been assigned a value (overridden prop) +--FILE-- +b = 'b'; + } +} + +class C extends B { + public string $a; + public readonly string $b; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a2'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + (new ReflectionProperty(B::class, 'b'))->setRawValueWithoutLazyInitialization($obj, 'b'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b"]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} +# Virtual: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b"]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} diff --git a/Zend/tests/lazy_objects/realize_001.phpt b/Zend/tests/lazy_objects/realize_001.phpt new file mode 100644 index 0000000000000..69d78cdbe1f8f --- /dev/null +++ b/Zend/tests/lazy_objects/realize_001.phpt @@ -0,0 +1,95 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been assigned a value +--FILE-- +b = 'b'; + } +} + +#[AllowDynamicProperties] +class C extends B { + public string $a; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a2'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Should not count a prop initialization + //$reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, 'dynamic B'); + //var_dump(!$reflector->isUninitializedLazyObject($obj)); + + (new ReflectionProperty(B::class, 'b'))->setRawValueWithoutLazyInitialization($obj, 'b'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b":"B":private]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} +# Virtual: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b":"B":private]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} diff --git a/Zend/tests/lazy_objects/realize_002.phpt b/Zend/tests/lazy_objects/realize_002.phpt new file mode 100644 index 0000000000000..6451b5e0127de --- /dev/null +++ b/Zend/tests/lazy_objects/realize_002.phpt @@ -0,0 +1,100 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been skipped +--FILE-- +b = 'b'; + } +} + +#[AllowDynamicProperties] +class C extends B { + public string $a; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('xxx')->skipLazyInitialization($obj); + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + // Should not count a prop initialization + $reflector->getProperty('b')->skipLazyInitialization($obj); + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + (new ReflectionProperty(B::class, 'b'))->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +ReflectionException: Property C::$xxx does not exist +ReflectionException: Property C::$b does not exist +bool(true) +object(C)#%d (0) { + ["b":"B":private]=> + uninitialized(string) + ["a"]=> + uninitialized(string) +} +# Virtual: +bool(false) +bool(false) +bool(false) +ReflectionException: Property C::$xxx does not exist +ReflectionException: Property C::$b does not exist +bool(true) +object(C)#%d (0) { + ["b":"B":private]=> + uninitialized(string) + ["a"]=> + uninitialized(string) +} diff --git a/Zend/tests/lazy_objects/realize_003.phpt b/Zend/tests/lazy_objects/realize_003.phpt new file mode 100644 index 0000000000000..5450eda1aeba1 --- /dev/null +++ b/Zend/tests/lazy_objects/realize_003.phpt @@ -0,0 +1,78 @@ +--TEST-- +Lazy objects: Object with no props is never lazy +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + + var_dump((new ReflectionClass($obj2::class))->isUninitializedLazyObject($obj2)); + var_dump($obj2); + + var_dump((new ReflectionClass($obj3::class))->isUninitializedLazyObject($obj3)); + var_dump($obj3); +} + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); +}); + +$obj2 = new D(); +$obj2->dynamic = 'value'; +(new ReflectionClass($obj2))->resetAsLazyGhost($obj2, function ($obj2) { + var_dump("initializer"); +}); + +$obj3 = (new ReflectionClass(C::class))->newLazyGhost(function () { + var_dump("initializer"); +}); + +test('Ghost', $obj, $obj2, $obj3); + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); +}); + +$obj2 = new D(); +$obj2->dynamic = 'value'; +(new ReflectionClass($obj2))->resetAsLazyProxy($obj2, function ($obj2) { + var_dump("initializer"); +}); + +$obj3 = (new ReflectionClass(C::class))->newLazyGhost(function () { + var_dump("initializer"); +}); + +test('Virtual', $obj, $obj2, $obj3); + +--EXPECTF-- +# Ghost: +bool(false) +object(C)#%d (0) { +} +bool(false) +object(D)#%d (0) { +} +bool(false) +object(C)#%d (0) { +} +# Virtual: +bool(false) +object(C)#%d (0) { +} +bool(false) +object(D)#%d (0) { +} +bool(false) +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt b/Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt new file mode 100644 index 0000000000000..ea4cfda907646 --- /dev/null +++ b/Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt @@ -0,0 +1,349 @@ +--TEST-- +Lazy objects: ReflectionClass::skipInitializerForProperty() prevent properties from triggering initializer +--FILE-- +hooked; } + set ($value) { $this->hooked = strtoupper($value); } + } + + public $virtual { + get { return 'virtual'; } + set ($value) { } + } +} + +class B extends A { + private $priv = 'privB'; + public $pubB = 'pubB'; + + private readonly string $readonly; +} + +set_error_handler(function ($errno, $errstr) { + throw new Error($errstr); +}); + +function testProperty(callable $makeObj, $propReflector) { + + $reflector = new ReflectionClass(B::class); + + $getValue = function ($obj, $propReflector) { + $name = $propReflector->getName(); + return $obj->$name; + }; + + printf("\n## %s", $propReflector); + + printf("\nskipInitializerForProperty():\n"); + $obj = $makeObj(); + $skept = false; + try { + $propReflector->skipLazyInitialization($obj); + $skept = true; + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + if ($skept) { + try { + printf("getValue(): "); + var_dump($getValue($obj, $propReflector)); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$propReflector->isStatic()) { + $propReflector->setValue($obj, ''); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + } + + printf("\nsetRawValueWithoutLazyInitialization():\n"); + $obj = $makeObj(); + $skept = false; + try { + $propReflector->setRawValueWithoutLazyInitialization($obj, 'value'); + $skept = true; + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + if ($skept) { + try { + printf("getValue(): "); + var_dump($getValue($obj, $propReflector)); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + } +} + +function test(string $name, callable $makeObj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass(B::class); + + foreach ($reflector->getProperties() as $propReflector) { + testProperty($makeObj, $propReflector); + } + + testProperty($makeObj, new class { + function getName() { + return 'dynamicProp'; + } + function setValue($obj, $value) { + $obj->dynamicProp = $value; + } + function isStatic() { + return false; + } + // TODO: refactor this test + function skipLazyInitialization(object $object) { + throw new \ReflectionException(); + } + function setRawValueWithoutLazyInitialization(object $object) { + throw new \ReflectionException(); + } + function __toString() { + return "Property [ \$dynamicProp ]\n"; + } + }); +} + +$reflector = new ReflectionClass(B::class); + +$factory = function () use ($reflector) { + return $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); + }); +}; + +test('Ghost', $factory); + +$factory = function () use ($reflector) { + return $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); + }); +}; + +test('Virtual', $factory); + +?> +--EXPECT-- +# Ghost: + +## Property [ private $priv = 'privB' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$priv + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$priv + +## Property [ public $pubB = 'pubB' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubB" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ private readonly string $readonly ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$readonly + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$readonly + +## Property [ protected $prot = 'prot' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access protected property B::$prot + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access protected property B::$prot + +## Property [ public $pubA = 'pubA' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubA" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public static $static = 'static' ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on static property B::$static + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on static property B::$static + +## Property [ public $noDefault = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public string $noDefaultTyped ] + +skipInitializerForProperty(): +getValue(): Error: Typed property A::$noDefaultTyped must not be accessed before initialization + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $initialized = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $hooked = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $virtual ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on virtual property B::$virtual + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on virtual property B::$virtual + +## Property [ $dynamicProp ] + +skipInitializerForProperty(): +ReflectionException: + +setRawValueWithoutLazyInitialization(): +ReflectionException: +# Virtual: + +## Property [ private $priv = 'privB' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$priv + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$priv + +## Property [ public $pubB = 'pubB' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubB" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ private readonly string $readonly ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$readonly + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$readonly + +## Property [ protected $prot = 'prot' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access protected property B::$prot + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access protected property B::$prot + +## Property [ public $pubA = 'pubA' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubA" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public static $static = 'static' ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on static property B::$static + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on static property B::$static + +## Property [ public $noDefault = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public string $noDefaultTyped ] + +skipInitializerForProperty(): +getValue(): Error: Typed property A::$noDefaultTyped must not be accessed before initialization + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $initialized = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $hooked = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $virtual ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on virtual property B::$virtual + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on virtual property B::$virtual + +## Property [ $dynamicProp ] + +skipInitializerForProperty(): +ReflectionException: + +setRawValueWithoutLazyInitialization(): +ReflectionException: diff --git a/Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt b/Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt new file mode 100644 index 0000000000000..0b22d564baa76 --- /dev/null +++ b/Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt @@ -0,0 +1,45 @@ +--TEST-- +Lazy objects: ReflectionObject::__toString() does not trigger initialization +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + (new ReflectionObject($obj))->__toString(); + + printf("Initialized:\n"); + var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost +Initialized: +bool(false) +# Virtual +Initialized: +bool(false) diff --git a/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt b/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt new file mode 100644 index 0000000000000..0ac167724c7da --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: resetAsLazyProxy() can reset initialized proxies +--FILE-- +newLazyProxy(function ($proxy) { + return new A(1, $proxy); +}); + +print "Init\n"; + +$reflector->initializeLazyObject($proxy); + +var_dump($proxy); + +print "Reset\n"; + +$proxy = $reflector->resetAsLazyProxy($proxy, function () { + return new A(2); +}); + +?> +--EXPECTF-- +Init +lazy proxy object(A)#%d (1) { + ["instance"]=> + object(A)#%d (2) { + ["a"]=> + int(1) + ["proxy"]=> + *RECURSION* + } +} +Reset +string(13) "A::__destruct" +object(A)#%d (2) { + ["a"]=> + int(1) + ["proxy"]=> + object(A)#%d (0) { + } +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt b/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt new file mode 100644 index 0000000000000..0aa542474a9fd --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt @@ -0,0 +1,103 @@ +--TEST-- +Lazy objects: resetAsLazy() ignores additional props +--FILE-- +d = 1; + } + } +} + +$reflector = new ReflectionClass(A::class); + +printf("# B\n"); + +$obj = new B(); +$obj->a = 1; +$obj->b = 2; +$reflector->resetAsLazyGhost($obj, function () {}); +var_dump($obj->b); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +printf("# C\n"); + +$obj = new C(); +$obj->a = 1; +$obj->c = 2; +$reflector->resetAsLazyGhost($obj, function () {}); +var_dump($obj->c); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +printf("# D\n"); + +$obj = new D(); +$obj->a = 1; +$reflector->resetAsLazyGhost($obj, function ($obj) { + $obj->__construct(true); +}); +var_dump($obj->d ?? 'undef'); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# B +int(2) +lazy ghost object(B)#%d (1) { + ["b"]=> + int(2) +} +NULL +object(B)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(2) +} +# C +int(2) +lazy ghost object(C)#%d (1) { + ["c"]=> + int(2) +} +NULL +object(C)#%d (2) { + ["a"]=> + NULL + ["c"]=> + int(2) +} +# D +string(5) "undef" +lazy ghost object(D)#%d (0) { + ["d"]=> + uninitialized(int) +} +NULL +object(D)#%d (2) { + ["a"]=> + NULL + ["d"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/reset_readonly_001.phpt b/Zend/tests/lazy_objects/reset_readonly_001.phpt new file mode 100644 index 0000000000000..f673d00bb7665 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_readonly_001.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: resetAsLazy preserves readonly semantics +--FILE-- +a = $value; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if ($setB) { + $this->b = $value; + } + try { + $this->c = $value; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + } +} + +final class C extends B { +} + + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass($obj::class); + + $reflector->resetAsLazyGhost($obj, function ($obj) { + $obj->__construct(2, setB: true); + }); + + $reflector->initializeLazyObject($obj); + + var_dump($obj); +} + +$obj = new B(1); +test('B', $obj); + +$obj = new C(1); +test('C', $obj); + +--EXPECTF-- +# B +object(B)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} +# C +Error: Cannot modify readonly property B::$a +object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/rfc_example_001.phpt b/Zend/tests/lazy_objects/rfc_example_001.phpt new file mode 100644 index 0000000000000..187aa61540cb1 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_001.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: RFC example 001 +--FILE-- +foo; + } +} + +$initializer = static function (MyClass $ghost): void { + $ghost->__construct(123); +}; + +$reflector = new ReflectionClass(MyClass::class); +$object = $reflector->newLazyGhost($initializer); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +--EXPECTF-- +lazy ghost object(MyClass)#%d (0) { + ["foo":"MyClass":private]=> + uninitialized(int) +} +int(123) +object(MyClass)#%d (1) { + ["foo":"MyClass":private]=> + int(123) +} diff --git a/Zend/tests/lazy_objects/rfc_example_002.phpt b/Zend/tests/lazy_objects/rfc_example_002.phpt new file mode 100644 index 0000000000000..e86a25df88718 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_002.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: RFC example 002 +--FILE-- +foo; + } +} + +$reflector = new ReflectionClass(MyClass::class); + +$initializer = static function (MyClass $proxy): MyClass { + return new MyClass(123); +}; + +$object = $reflector->newLazyProxy($initializer); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +--EXPECTF-- +lazy proxy object(MyClass)#%d (0) { + ["foo":"MyClass":private]=> + uninitialized(int) +} +int(123) +lazy proxy object(MyClass)#%d (1) { + ["instance"]=> + object(MyClass)#%d (1) { + ["foo":"MyClass":private]=> + int(123) + } +} diff --git a/Zend/tests/lazy_objects/rfc_example_003.phpt b/Zend/tests/lazy_objects/rfc_example_003.phpt new file mode 100644 index 0000000000000..0463b745d4eed --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_003.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: RFC example 003 +--FILE-- +resetAsLazyGhost($this, $this->initialize(...), ReflectionClass::SKIP_DESTRUCTOR); + } + + public function initialize() + { + $this->foo = 123; + } + + public function getFoo() + { + return $this->foo; + } + + public function __destruct() + { + var_dump(__METHOD__); + } +} + +$object = new MyLazyClass(); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyLazyClass)#%d (0) { + ["foo":"MyLazyClass":private]=> + uninitialized(int) +} +int(123) +object(MyLazyClass)#%d (1) { + ["foo":"MyLazyClass":private]=> + int(123) +} +==DONE== +string(23) "MyLazyClass::__destruct" diff --git a/Zend/tests/lazy_objects/rfc_example_004.phpt b/Zend/tests/lazy_objects/rfc_example_004.phpt new file mode 100644 index 0000000000000..f2459d9aa6383 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_004.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: RFC example 004 +--FILE-- + 'Title', + 'content' => 'Content', + ]; +} + +$reflector = new ReflectionClass(BlogPost::class); +// Callable that retrieves the title and content from the database. +$initializer = function ($blogPost) { + var_dump("initialization"); + $data = loadFromDB(); + $blogPost->title = $data['title']; + $blogPost->content = $data['content']; +}; +$post = $reflector->newLazyGhost($initializer); + +// Without this line, the following call to ReflectionProperty::setValue() would trigger initialization. +$reflector->getProperty('id')->skipLazyInitialization($post); +$reflector->getProperty('id')->setValue($post, 123); + +// Alternatively, one can use this directly: +$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123); + +var_dump($post); +var_dump($post->id); +var_dump($post->title); +var_dump($post->content); +var_dump($post); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(BlogPost)#%d (1) { + ["id"]=> + int(123) + ["title"]=> + uninitialized(string) + ["content"]=> + uninitialized(string) +} +int(123) +string(14) "initialization" +string(5) "Title" +string(7) "Content" +object(BlogPost)#%d (3) { + ["id"]=> + int(123) + ["title"]=> + string(5) "Title" + ["content"]=> + string(7) "Content" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_005.phpt b/Zend/tests/lazy_objects/rfc_example_005.phpt new file mode 100644 index 0000000000000..f8548f36b700d --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_005.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: RFC example 005 +--FILE-- + 'Title', + 'content' => 'Content', + ]; +} + +$reflector = new ReflectionClass(BlogPost::class); +// Callable that retrieves the title and content from the database. +$initializer = function ($blogPost) { + var_dump("initialization"); + $data = loadFromDB(); + return new BlogPost($blogPost->id, $data['title'], $data['content']); +}; +$post = $reflector->newLazyProxy($initializer); + +// Without this line, the following call to ReflectionProperty::setValue() would trigger initialization. +$reflector->getProperty('id')->skipLazyInitialization($post); +$reflector->getProperty('id')->setValue($post, 123); + +// Alternatively, one can use this directly: +$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123); + +var_dump($post); +var_dump($post->id); +var_dump($post->title); +var_dump($post->content); +var_dump($post); + +?> +==DONE== +--EXPECTF-- +lazy proxy object(BlogPost)#%d (1) { + ["id"]=> + int(123) + ["title"]=> + uninitialized(string) + ["content"]=> + uninitialized(string) +} +int(123) +string(14) "initialization" +string(5) "Title" +string(7) "Content" +lazy proxy object(BlogPost)#%d (1) { + ["instance"]=> + object(BlogPost)#%d (3) { + ["id"]=> + int(123) + ["title"]=> + string(5) "Title" + ["content"]=> + string(7) "Content" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_006.phpt b/Zend/tests/lazy_objects/rfc_example_006.phpt new file mode 100644 index 0000000000000..c467567186495 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_006.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: RFC example 006 +--FILE-- +newLazyGhost(function ($object2) { + $object2->propB = 'value'; + throw new \Exception('initializer exception'); +}); +$reflector->getProperty('propA')->setRawValueWithoutLazyInitialization($object2, 'object-2'); + +$object1 = $reflector->newLazyGhost(function ($object1) use ($object2) { + $object1->propB = 'updated'; + $object1->propB = $object2->propB; +}); +$reflector->getProperty('propA')->setRawValueWithoutLazyInitialization($object1, 'object-1'); + +// Both objects are uninitalized at this point + +var_dump($object1); +var_dump($object2); + +try { + var_dump($object1->propB); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +// The state of both objects is unchanged + +var_dump($object1); +var_dump($object2); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-1" +} +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-2" +} +initializer exception +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-1" +} +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-2" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_007.phpt b/Zend/tests/lazy_objects/rfc_example_007.phpt new file mode 100644 index 0000000000000..5310345428556 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_007.phpt @@ -0,0 +1,31 @@ +--TEST-- +Lazy objects: RFC example 007 +--FILE-- +resetAsLazyGhost($object, function () {}); +var_dump($id === spl_object_id($object)); +var_dump($ref->get() === $object); + +$reflector->initializeLazyObject($object); +var_dump($id === spl_object_id($object)); +var_dump($ref->get() === $object); + +?> +==DONE== +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_008.phpt b/Zend/tests/lazy_objects/rfc_example_008.phpt new file mode 100644 index 0000000000000..7cbbcb21c5811 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_008.phpt @@ -0,0 +1,25 @@ +--TEST-- +Lazy objects: RFC example 008 +--FILE-- +newLazyGhost(function () { + throw new \Exception('initialization'); +}); + +$reflector->getProperty('id')->skipLazyInitialization($object); + +$object->id = 1; +var_dump($object->id); + +?> +==DONE== +--EXPECT-- +int(1) +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_009.phpt b/Zend/tests/lazy_objects/rfc_example_009.phpt new file mode 100644 index 0000000000000..ccf7f53e6b260 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_009.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: RFC example 009 +--FILE-- +connect(); + } + public function __destruct() { + var_dump(__METHOD__); + $this->close(); + } + public function connect() { + } + public function close() { + } +} + +$connection = new Connection(); + +$reflector = new ReflectionClass(Connection::class); + +print "Reset non-lazy\n"; +// Calls destructor +$reflector->resetAsLazyGhost($connection, function () { + var_dump("initialization"); +}); + +print "Release non-initialized\n"; +$connection = null; // Does not call destructor (object is not initialized) + +?> +==DONE== +--EXPECT-- +Reset non-lazy +string(22) "Connection::__destruct" +Release non-initialized +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_010.phpt b/Zend/tests/lazy_objects/rfc_example_010.phpt new file mode 100644 index 0000000000000..3c578a883ea90 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_010.phpt @@ -0,0 +1,25 @@ +--TEST-- +Lazy objects: RFC example 010 +--FILE-- +newLazyGhost(function () {}); + +$reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'value'); + +var_dump($obj); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyClass)#%d (1) { + ["a"]=> + string(5) "value" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_011.phpt b/Zend/tests/lazy_objects/rfc_example_011.phpt new file mode 100644 index 0000000000000..2dc50b1a33ff3 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_011.phpt @@ -0,0 +1,81 @@ +--TEST-- +Lazy objects: RFC example 011 +--FILE-- +name; + } + + public function getEmail() + { + return $this->email; + } +} + +// ORM code + +class EntityManager +{ + public function getReference(string $class, int $id) + { + // The ReflectionClass and ReflectionProperty instances are cached in practice + $reflector = new ReflectionClass($class); + + $entity = $reflector->newLazyGhost(function ($entity) use ($class, $id, $reflector) { + $data = $this->loadFromDatabase($class, $id); + $reflector->getProperty('name')->setValue($entity, $data['name']); + $reflector->getProperty('email')->setValue($entity, $data['email']); + }); + + // id is already known and can be accessed without triggering initialization + $reflector->getProperty('id')->setRawValueWithoutLazyInitialization($entity, $id); + + return $entity; + } + + public function loadFromDatabase($id) + { + return [ + 'name' => 'Example', + 'email' => 'example@example.com', + ]; + } +} + +$em = new EntityManager(); +$blogPost = $em->getReference(BlogPost::class, 123); +var_dump($blogPost); +var_dump($blogPost->getName()); +var_dump($blogPost); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(BlogPost)#%d (1) { + ["id":"BlogPost":private]=> + int(123) + ["name":"BlogPost":private]=> + uninitialized(string) + ["email":"BlogPost":private]=> + uninitialized(string) +} +string(7) "Example" +object(BlogPost)#%d (3) { + ["id":"BlogPost":private]=> + int(123) + ["name":"BlogPost":private]=> + string(7) "Example" + ["email":"BlogPost":private]=> + string(19) "example@example.com" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc_example_012.phpt b/Zend/tests/lazy_objects/rfc_example_012.phpt new file mode 100644 index 0000000000000..14b07d3bd65e4 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc_example_012.phpt @@ -0,0 +1,80 @@ +--TEST-- +Lazy objects: RFC example 012 +--FILE-- +hostname, $this->credentials); + } +} + +class Client +{ + public function __construct( + private string $hostname, + private string $credentials, + ) {} + + public function doSomething() + { + printf("doSomething() (hostname: %s)\n", $this->hostname); + } +} + +// Symfony code + +class Container +{ + public function getClientFactoryService(): ClientFactory + { + return new ClientFactory('127.0.0.1', 'secret'); + } + + public function getClientService(): Client + { + $reflector = new ReflectionClass(Client::class); + + $client = $reflector->newLazyProxy(function () { + $clientFactory = $this->getClientFactoryService(); + return $clientFactory->createClient(); + }); + + return $client; + } +} + +$container = new Container(); +$service = $container->getClientService(); +var_dump($service); +$service->doSomething(); +var_dump($service); + +?> +==DONE== +--EXPECTF-- +lazy proxy object(Client)#%d (0) { + ["hostname":"Client":private]=> + uninitialized(string) + ["credentials":"Client":private]=> + uninitialized(string) +} +doSomething() (hostname: 127.0.0.1) +lazy proxy object(Client)#%d (1) { + ["instance"]=> + object(Client)#%d (2) { + ["hostname":"Client":private]=> + string(9) "127.0.0.1" + ["credentials":"Client":private]=> + string(6) "secret" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/serialize_001.phpt b/Zend/tests/lazy_objects/serialize_001.phpt new file mode 100644 index 0000000000000..2203f83760bcc --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_001.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: serialize initializes object by default +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump(serialize($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_002.phpt b/Zend/tests/lazy_objects/serialize_002.phpt new file mode 100644 index 0000000000000..9b664f92dbf8f --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_002.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: serialize initializes object by default (properties hashtable) +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + // Builds properties hashtable + get_object_vars($obj); + + var_dump(serialize($obj)); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_003.phpt b/Zend/tests/lazy_objects/serialize_003.phpt new file mode 100644 index 0000000000000..71da496fb5aba --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_003.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: serialize does not initializes object if flag is set +--FILE-- +setRawValueWithoutLazyInitialization($obj, 1); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} +# Virtual: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_004.phpt b/Zend/tests/lazy_objects/serialize_004.phpt new file mode 100644 index 0000000000000..70d3fe7dfc8b5 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_004.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: serialize does not initializes object if flag is set (properties hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 1); + + // Builds properties hashtable + get_mangled_object_vars($obj); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} +# Virtual: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_005.phpt b/Zend/tests/lazy_objects/serialize_005.phpt new file mode 100644 index 0000000000000..e9817b6a3a771 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_005.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: serialize does not force initialization of object if the __serialize method is used +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/serialize_006.phpt b/Zend/tests/lazy_objects/serialize_006.phpt new file mode 100644 index 0000000000000..4c965c0fe934e --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_006.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: __serialize may initialize object +--FILE-- + $this->a]; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new c(); + $c->a = 1; + return $c; +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_007.phpt b/Zend/tests/lazy_objects/serialize_007.phpt new file mode 100644 index 0000000000000..d817aaf5279be --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_007.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: serialize initializes object by default if the __sleep method is used +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_008.phpt b/Zend/tests/lazy_objects/serialize_008.phpt new file mode 100644 index 0000000000000..4ef54498e5b5b --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_008.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: serialize does not initializes object with __sleep method if flag is set +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/serialize_009.phpt b/Zend/tests/lazy_objects/serialize_009.phpt new file mode 100644 index 0000000000000..af1876afbddf3 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_009.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: __sleep may initialize object +--FILE-- +a); + return ['a']; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +int(1) +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Virtual: +string(11) "initializer" +int(1) +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_010.phpt b/Zend/tests/lazy_objects/serialize_010.phpt new file mode 100644 index 0000000000000..6cc46513a0f6b --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_010.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: serialize during hook initializes object by default +--FILE-- +a = $value; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj->a); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Virtual: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/set_raw_value_001.phpt b/Zend/tests/lazy_objects/set_raw_value_001.phpt new file mode 100644 index 0000000000000..807476d70729a --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_001.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() sets value +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/set_raw_value_002.phpt b/Zend/tests/lazy_objects/set_raw_value_002.phpt new file mode 100644 index 0000000000000..7bd6261519ec8 --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_002.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() skips hooks +--FILE-- +a = $value; } + get { return $this->a; } + } + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/set_raw_value_003.phpt b/Zend/tests/lazy_objects/set_raw_value_003.phpt new file mode 100644 index 0000000000000..a3f0002c9cd6f --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_003.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may realize object if last lazy prop +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(true) +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + string(4) "test" +} +# Proxy +bool(true) +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/set_raw_value_004.phpt b/Zend/tests/lazy_objects/set_raw_value_004.phpt new file mode 100644 index 0000000000000..10a335f8fe5f0 --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_004.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() does not call __set() +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/set_raw_value_005.phpt b/Zend/tests/lazy_objects/set_raw_value_005.phpt new file mode 100644 index 0000000000000..1c8eac82880c0 --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_005.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may trigger initialization via side effects (__toString()) +--FILE-- +a = 'a'; + $this->b = 'b'; + } + public string $a; + public string $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + + $value = new class($obj) { + function __construct(public object $obj) {} + function __toString() { + return $this->obj->b; + } + }; + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $value); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + string(1) "b" + ["b"]=> + string(1) "b" +} +# Proxy +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(1) "b" + } +} diff --git a/Zend/tests/lazy_objects/set_raw_value_006.phpt b/Zend/tests/lazy_objects/set_raw_value_006.phpt new file mode 100644 index 0000000000000..96bc8054ed49b --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_006.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may trigger initialization via side effects (__destruct()) +--FILE-- +a = 'a'; + $this->b = 'b'; + } + public $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + + $value = new class($obj) { + function __construct(public object $obj) {} + function __destruct() { + $this->obj->b = ''; + } + }; + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $value); + $value = null; + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(0) "" +} +# Proxy +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(0) "" + } +} diff --git a/Zend/tests/lazy_objects/set_raw_value_007.phpt b/Zend/tests/lazy_objects/set_raw_value_007.phpt new file mode 100644 index 0000000000000..caa5211f371a5 --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_007.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() is allowed on initialized objects +--FILE-- +initializeLazyObject($obj); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + NULL +} +# Proxy +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/set_raw_value_008.phpt b/Zend/tests/lazy_objects/set_raw_value_008.phpt new file mode 100644 index 0000000000000..9151e58f3fc65 --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_008.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() can not be called on dynamic properties +--FILE-- +dyn = 1; + $propReflector = new ReflectionProperty($c, 'dyn'); + + try { + $propReflector->setRawValueWithoutLazyInitialization($obj, 'test'); + } catch (\ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +ReflectionException: Can not use setRawValueWithoutLazyInitialization on dynamic property C::$dyn +# Proxy +ReflectionException: Can not use setRawValueWithoutLazyInitialization on dynamic property C::$dyn diff --git a/Zend/tests/lazy_objects/set_raw_value_009.phpt b/Zend/tests/lazy_objects/set_raw_value_009.phpt new file mode 100644 index 0000000000000..1e4a7ade935ad --- /dev/null +++ b/Zend/tests/lazy_objects/set_raw_value_009.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() preserves readonly semantics +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 1); + try { + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 2); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Error: Cannot modify readonly property C::$a +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +Error: Cannot modify readonly property C::$a +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skip_initialization_001.phpt b/Zend/tests/lazy_objects/skip_initialization_001.phpt new file mode 100644 index 0000000000000..15859a79e74a4 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_001.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: skipLazyInitialization() marks property as non-lazy and sets default value if any +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump($obj->b); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +NULL +int(1) +bool(false) +lazy ghost object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) +} +# Proxy +NULL +int(1) +bool(false) +lazy proxy object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skip_initialization_002.phpt b/Zend/tests/lazy_objects/skip_initialization_002.phpt new file mode 100644 index 0000000000000..779e931773b06 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_002.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: skipLazyInitialization() skips hooks +--FILE-- +a = $value; } + get { return $this->a; } + } + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(1) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +int(1) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skip_initialization_003.phpt b/Zend/tests/lazy_objects/skip_initialization_003.phpt new file mode 100644 index 0000000000000..084a3993876f4 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_003.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: skipLazyInitialization() may realize object if last lazy prop +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} diff --git a/Zend/tests/lazy_objects/skip_initialization_004.phpt b/Zend/tests/lazy_objects/skip_initialization_004.phpt new file mode 100644 index 0000000000000..761a2923e69a2 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_004.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: skipLazyInitialization() does not call __set() +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(1) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +int(1) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skip_initialization_005.phpt b/Zend/tests/lazy_objects/skip_initialization_005.phpt new file mode 100644 index 0000000000000..2244020fb6100 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_005.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: skipLazyInitialization() has no effect on non-lazy properties +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + + $obj->a = 2; + + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(2) +} +# Proxy +int(2) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/skip_initialization_006.phpt b/Zend/tests/lazy_objects/skip_initialization_006.phpt new file mode 100644 index 0000000000000..bf8ff2094ca15 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_006.phpt @@ -0,0 +1,61 @@ +--TEST-- +Lazy objects: skipLazyInitialization() has no effect on initialized objects +--FILE-- +a = 2; + } + public $a = 1; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->initializeLazyObject($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(true) +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL +} +# Proxy +int(1) +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skip_initialization_007.phpt b/Zend/tests/lazy_objects/skip_initialization_007.phpt new file mode 100644 index 0000000000000..dcb94f90b82ac --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_007.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: skipLazyInitialization() preserves readonly semantics +--FILE-- +a = 1; + } + public readonly int $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + try { + var_dump($obj->a); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + + $reflector->initializeLazyObject($obj); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Error: Typed property C::$a must not be accessed before initialization +bool(false) +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +Error: Typed property C::$a must not be accessed before initialization +bool(false) +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skip_initialization_008.phpt b/Zend/tests/lazy_objects/skip_initialization_008.phpt new file mode 100644 index 0000000000000..cdb1b66543d65 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_008.phpt @@ -0,0 +1,76 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() preserves readonly semantics +--FILE-- +a = 1; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + } + public readonly int $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 2); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + + $reflector->initializeLazyObject($obj); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(2) +} +Error: Cannot modify readonly property C::$a +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL +} +# Proxy +int(2) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(2) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skip_initialization_009.phpt b/Zend/tests/lazy_objects/skip_initialization_009.phpt new file mode 100644 index 0000000000000..d6eb417a15760 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_009.phpt @@ -0,0 +1,67 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() leaves property as lazy if exception prevents update +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Prop is still lazy: This triggers initialization + $obj->a = 1; + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +TypeError: Cannot assign stdClass to property C::$a of type int +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +TypeError: Cannot assign stdClass to property C::$a of type int +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skip_initialization_010.phpt b/Zend/tests/lazy_objects/skip_initialization_010.phpt new file mode 100644 index 0000000000000..74e12cb3629f8 --- /dev/null +++ b/Zend/tests/lazy_objects/skip_initialization_010.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: skipLazyInitialization() can not be used on dynamic properties +--FILE-- +dyn = 1; + $propReflector = new ReflectionProperty($c, 'dyn'); + + try { + $propReflector->skipLazyInitialization($obj); + } catch (\ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +ReflectionException: Can not use skipLazyInitialization on dynamic property C::$dyn +# Proxy +ReflectionException: Can not use skipLazyInitialization on dynamic property C::$dyn diff --git a/Zend/tests/lazy_objects/unclean_shutdown.phpt b/Zend/tests/lazy_objects/unclean_shutdown.phpt new file mode 100644 index 0000000000000..a5effe34642f9 --- /dev/null +++ b/Zend/tests/lazy_objects/unclean_shutdown.phpt @@ -0,0 +1,17 @@ +--TEST-- +Lazy objects: unclean shutdown +--FILE-- +newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + trigger_error('Fatal', E_USER_ERROR); +}); + +var_dump($obj->a); +--EXPECTF-- +Fatal error: Fatal in %s on line %d diff --git a/Zend/tests/lazy_objects/unset_001.phpt b/Zend/tests/lazy_objects/unset_001.phpt new file mode 100644 index 0000000000000..c7f12cafd01d4 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_001.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: unset of undefined property initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_003.phpt b/Zend/tests/lazy_objects/unset_003.phpt new file mode 100644 index 0000000000000..2d08d94485d54 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_003.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of magic property may not initialize object +--FILE-- +b = 2; + } + + public function __unset($name) { + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_004.phpt b/Zend/tests/lazy_objects/unset_004.phpt new file mode 100644 index 0000000000000..be63629f532a2 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_004.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: unset of magic property may initialize object +--FILE-- +b = 2; + } + + public function __unset($name) { + var_dump($this->b); + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_005.phpt b/Zend/tests/lazy_objects/unset_005.phpt new file mode 100644 index 0000000000000..11560dfed5032 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_005.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: circular unset of magic property may initialize object +--FILE-- +b = 2; + } + + public function __unset($name) { + unset($this->a); + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_006.phpt b/Zend/tests/lazy_objects/unset_006.phpt new file mode 100644 index 0000000000000..8f03b11026b55 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_006.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: unset of undefined dynamic property initializes object +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_007.phpt b/Zend/tests/lazy_objects/unset_007.phpt new file mode 100644 index 0000000000000..b7ca5adbfdfd4 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_007.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of undefined dynamic property initializes object (2) +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + // no var_dump($obj), so that properties ht is not initialized + var_dump('before unset'); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +string(12) "before unset" +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Virtual: +string(12) "before unset" +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_008.phpt b/Zend/tests/lazy_objects/unset_008.phpt new file mode 100644 index 0000000000000..f8d110a963047 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_008.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of defined property does not initialize object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + (new ReflectionProperty($obj, 'a'))->setRawValueWithoutLazyInitialization($obj, 1); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (1) { + ["a"]=> + int(1) +} +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Virtual: +object(C)#%d (1) { + ["a"]=> + int(1) +} +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_009.phpt b/Zend/tests/lazy_objects/unset_009.phpt new file mode 100644 index 0000000000000..3de9ca792ce1f --- /dev/null +++ b/Zend/tests/lazy_objects/unset_009.phpt @@ -0,0 +1,78 @@ +--TEST-- +Lazy objects: unset of undefined skipped property initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + unset($obj->a); + unset($obj->b); + unset($obj->c); + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +# Virtual: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_010.phpt b/Zend/tests/lazy_objects/unset_010.phpt new file mode 100644 index 0000000000000..d22f3dcb83e92 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_010.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: cannot unset hooked property +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + try { + unset($obj->a); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +Error: Cannot unset hooked property C::$a +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +Error: Cannot unset hooked property C::$a +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/use_case_001.phpt b/Zend/tests/lazy_objects/use_case_001.phpt new file mode 100644 index 0000000000000..0bce225b1effe --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_001.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: Lazy service initialization in dependency injection container +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + $obj->__construct(); + }); + return $obj; + } + + public function getApplicationService(): Application { + return new Application($this->getEntityManagerService()); + } +} + +$container = new Container(); + +printf("Service can be fetched without initializing dependencies\n"); +$application = $container->getApplicationService(); +--EXPECTF-- +Service can be fetched without initializing dependencies +string(24) "Application::__construct" diff --git a/Zend/tests/lazy_objects/use_case_001b.phpt b/Zend/tests/lazy_objects/use_case_001b.phpt new file mode 100644 index 0000000000000..e32527bca1d78 --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_001b.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: Lazy service initialization in dependency injection container via factory +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + return new EntityManager(); + }); + return $obj; + } + + public function getApplicationService(): Application { + return new Application($this->getEntityManagerService()); + } +} + +$container = new Container(); + +printf("Service can be fetched without initializing dependencies\n"); +$application = $container->getApplicationService(); +--EXPECTF-- +Service can be fetched without initializing dependencies +string(24) "Application::__construct" diff --git a/Zend/tests/lazy_objects/use_case_002.phpt b/Zend/tests/lazy_objects/use_case_002.phpt new file mode 100644 index 0000000000000..0bbead439c1f7 --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_002.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: Lazy entity loading +--FILE-- +id; + } + + public function getName(): string { + return $this->name; + } +} + +class EntityManager { + public function lazyLoad(string $fqcn, int $id): object { + $entity = (new ReflectionClass($fqcn))->newInstanceWithoutConstructor(); + (new ReflectionClass($entity))->resetAsLazyGhost($entity, function ($obj) { + var_dump('initializer'); + $prop = new ReflectionProperty($obj, 'name'); + $prop->setValue($obj, 'John Doe'); + }); + + (new ReflectionProperty($entity, 'id'))->setRawValueWithoutLazyInitialization($entity, $id); + + return $entity; + } +} + +$em = new EntityManager(); +$user = $em->lazyLoad(User::class, 123); + +printf("Fetching identifier does not trigger initializer\n"); +var_dump($user->getId()); + +printf("Fetching anything else triggers initializer\n"); +var_dump($user->getName()); +--EXPECTF-- +Fetching identifier does not trigger initializer +int(123) +Fetching anything else triggers initializer +string(11) "initializer" +string(8) "John Doe" diff --git a/Zend/tests/lazy_objects/write_001.phpt b/Zend/tests/lazy_objects/write_001.phpt new file mode 100644 index 0000000000000..d5c4cb8fe01b6 --- /dev/null +++ b/Zend/tests/lazy_objects/write_001.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: property write initializes object +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_002.phpt b/Zend/tests/lazy_objects/write_002.phpt new file mode 100644 index 0000000000000..34f76f087d892 --- /dev/null +++ b/Zend/tests/lazy_objects/write_002.phpt @@ -0,0 +1,74 @@ +--TEST-- +Lazy objects: property write to custom property initializes object +--FILE-- +a = 1; + $this->b = 2; + } +} +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->custom = 3; + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["custom"]=> + int(3) +} +# Virtual: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["custom"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_003.phpt b/Zend/tests/lazy_objects/write_003.phpt new file mode 100644 index 0000000000000..288b8125820f6 --- /dev/null +++ b/Zend/tests/lazy_objects/write_003.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: property write to magic property initializes object +--FILE-- +a = 1; + } + + public function __set($name, $value) { + $this->a = $value; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->magic = 3; + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Virtual: +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_004.phpt b/Zend/tests/lazy_objects/write_004.phpt new file mode 100644 index 0000000000000..6ea60ad2d04e2 --- /dev/null +++ b/Zend/tests/lazy_objects/write_004.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: circular property write to magic property initializes object +--FILE-- +a = 1; + } + + public function __set($name, $value) { + $this->a = $value; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 3; + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Virtual: +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_005.phpt b/Zend/tests/lazy_objects/write_005.phpt new file mode 100644 index 0000000000000..6aafc032d55fc --- /dev/null +++ b/Zend/tests/lazy_objects/write_005.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: property write with initializer exception +--FILE-- +a = 1; + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + throw new \Exception('init exception'); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + throw new \Exception('init exception'); +}); + +test('Ghost', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +init exception +lazy ghost object(C)#%d (0) { +} +# Ghost: +lazy proxy object(C)#%d (0) { +} +init exception +lazy proxy object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/write_006.phpt b/Zend/tests/lazy_objects/write_006.phpt new file mode 100644 index 0000000000000..70b1b0c33b712 --- /dev/null +++ b/Zend/tests/lazy_objects/write_006.phpt @@ -0,0 +1,81 @@ +--TEST-- +Lazy objects: write to skipped property does not initialize object +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + $obj->a = 2; + $obj->b = 2; + $obj->c = 2; + var_dump($obj); +} + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Virtual', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} +# Virtual: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 377bc23c46bd2..9b797880684f1 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -885,7 +885,7 @@ ZEND_FUNCTION(get_mangled_object_vars) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); - properties = obj->handlers->get_properties(obj); + properties = zend_get_properties_no_init(obj); if (!properties) { ZVAL_EMPTY_ARRAY(return_value); return; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f1f5bfc84516f..21e17fe8c666b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -171,6 +171,7 @@ void init_executor(void) /* {{{ */ zend_stack_init(&EG(user_exception_handlers), sizeof(zval)); zend_objects_store_init(&EG(objects_store), 1024); + zend_lazy_objects_init(&EG(lazy_objects_store)); EG(full_tables_cleanup) = 0; ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false); @@ -492,6 +493,7 @@ void shutdown_executor(void) /* {{{ */ zend_stack_destroy(&EG(user_error_handlers_error_reporting)); zend_stack_destroy(&EG(user_error_handlers)); zend_stack_destroy(&EG(user_exception_handlers)); + zend_lazy_objects_destroy(&EG(lazy_objects_store)); zend_objects_store_destroy(&EG(objects_store)); if (EG(in_autoload)) { zend_hash_destroy(EG(in_autoload)); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 3aa967b8dd6bb..539793c8325a6 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -42,6 +42,7 @@ #include "zend_call_stack.h" #include "zend_max_execution_timer.h" #include "zend_strtod.h" +#include "zend_lazy_objects.h" /* Define ZTS if you want a thread-safe Zend */ /*#undef ZTS*/ @@ -246,6 +247,7 @@ struct _zend_executor_globals { zend_ini_entry *error_reporting_ini_entry; zend_objects_store objects_store; + zend_lazy_objects_store lazy_objects_store; zend_object *exception, *prev_exception; const zend_op *opline_before_exception; zend_op exception_op[3]; diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c new file mode 100644 index 0000000000000..3e2740a08ed07 --- /dev/null +++ b/Zend/zend_lazy_objects.c @@ -0,0 +1,668 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +/* Lazy objects are standard zend_object whose initialization is defered until + * one of their properties backing store is accessed for the first time. + * + * This is implemented by using the same fallback mechanism as __get and __set + * magic methods that is triggered when an undefined property is accessed. + * + * Execution of methods or virtual property hooks do not trigger initialization. + * + * A lazy object can be created via the Reflection API. The user specifies an + * initializer function that is called when initialization is required. + * + * There are two kinds of lazy objects: + * + * - Ghosts: These are initialized in-place by the initializer function + * - Proxy: The initializer returns a new instance. After initialization, + * interaction with the proxy object are proxied to the instance. + * + * Internal objects are not supported. + */ + +#include "zend_API.h" +#include "zend_compile.h" +#include "zend_execute.h" +#include "zend_hash.h" +#include "zend_object_handlers.h" +#include "zend_objects_API.h" +#include "zend_operators.h" +#include "zend_types.h" +#include "zend_variables.h" +#include "zend_lazy_objects.h" + +/** + * Information about each lazy object is stored outside of zend_objects, in + * EG(lazy_objects_store). For ghost objects, we can release this after the + * object is initialized. + */ +typedef struct _zend_lazy_object_info { + union { + struct { + zend_fcall_info_cache fcc; + zval zv; /* ReflectionClass::getLazyInitializer() */ + } initializer; + zend_object *instance; /* For initialized lazy proxy objects */ + } u; + zend_lazy_object_flags_t flags; + int lazy_properties_count; +} zend_lazy_object_info; + +/* zend_hash dtor_func_t for zend_lazy_objects_store.infos */ +static void zend_lazy_object_info_dtor_func(zval *pElement) +{ + zend_lazy_object_info *info = (zend_lazy_object_info*) Z_PTR_P(pElement); + + if (info->flags & ZEND_LAZY_OBJECT_INITIALIZED) { + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_STRATEGY_PROXY); + zend_object_release(info->u.instance); + } else { + zval_ptr_dtor(&info->u.initializer.zv); + zend_fcc_dtor(&info->u.initializer.fcc); + } + + efree(info); +} + +void zend_lazy_objects_init(zend_lazy_objects_store *store) +{ + zend_hash_init(&store->infos, 8, NULL, zend_lazy_object_info_dtor_func, false); +} + +void zend_lazy_objects_destroy(zend_lazy_objects_store *store) +{ + ZEND_ASSERT(zend_hash_num_elements(&store->infos) == 0 || CG(unclean_shutdown)); + zend_hash_destroy(&store->infos); +} + +void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) +{ + ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY)); + + zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); + ZEND_ASSERT(zv); +} + +zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) +{ + ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY)); + + zend_lazy_object_info *info = zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(info); + + return info; +} + +zval* zend_lazy_object_get_initializer_zv(zend_object *obj) +{ + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(!(info->flags & ZEND_LAZY_OBJECT_INITIALIZED)); + + return &info->u.initializer.zv; +} + +zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj) +{ + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(!(info->flags & ZEND_LAZY_OBJECT_INITIALIZED)); + + return &info->u.initializer.fcc; +} + +zend_object* zend_lazy_object_get_instance(zend_object *obj) +{ + ZEND_ASSERT(zend_lazy_object_initialized(obj)); + + if (zend_object_is_lazy_proxy(obj)) { + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_INITIALIZED); + + return info->u.instance; + } + + return obj; +} + +zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj) +{ + return zend_lazy_object_get_info(obj)->flags; +} + +void zend_lazy_object_del_info(zend_object *obj) +{ + zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(res == SUCCESS); +} + +bool zend_lazy_object_decr_lazy_props(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(info->lazy_properties_count > 0); + + info->lazy_properties_count--; + + return info->lazy_properties_count == 0; +} + +/** + * Making objects lazy + */ + +/* Make object 'obj' lazy. If 'obj' is NULL, create a lazy instance of + * class 'class_type' */ +ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, + zend_class_entry *ce, zval *initializer_zv, + zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags) +{ + ZEND_ASSERT(!(flags & ~(ZEND_LAZY_OBJECT_USER_FLAGS|ZEND_LAZY_OBJECT_STRATEGY_FLAGS))); + ZEND_ASSERT((flags & ZEND_LAZY_OBJECT_STRATEGY_FLAGS) == ZEND_LAZY_OBJECT_STRATEGY_GHOST + || (flags & ZEND_LAZY_OBJECT_STRATEGY_FLAGS) == ZEND_LAZY_OBJECT_STRATEGY_PROXY); + + ZEND_ASSERT(!obj || (!zend_object_is_lazy(obj) || zend_lazy_object_initialized(obj))); + ZEND_ASSERT(!obj || instanceof_function(obj->ce, ce)); + + /* Internal classes are not supported */ + if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) { + zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s is internal", ZSTR_VAL(ce->name)); + return NULL; + } + + for (zend_class_entry *parent = ce->parent; parent; parent = parent->parent) { + if (UNEXPECTED(parent->type == ZEND_INTERNAL_CLASS && parent != zend_standard_class_def)) { + zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s inherits internal class %s", + ZSTR_VAL(ce->name), ZSTR_VAL(parent->name)); + return NULL; + } + } + + int lazy_properties_count = 0; + + if (!obj) { + zval zobj; + if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) { + /* Slow path: use object_init_ex() */ + if (object_init_ex(&zobj, ce) == FAILURE) { + ZEND_ASSERT(EG(exception)); + return NULL; + } + obj = Z_OBJ(zobj); + } else { + obj = zend_objects_new(ce); + } + + for (int i = 0; i < obj->ce->default_properties_count; i++) { + zval *p = &obj->properties_table[i]; + ZVAL_UNDEF(p); + if (EXPECTED(obj->ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + lazy_properties_count++; + } else { + Z_PROP_FLAG_P(p) = 0; + } + } + } else { + if (zend_object_is_lazy(obj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(obj) && zend_lazy_object_initialized(obj)); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + zend_lazy_object_del_info(obj); + } else if (!(flags & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) + && !(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { + if (obj->handlers->dtor_obj != zend_objects_destroy_object + || obj->ce->destructor) { + GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); + GC_ADDREF(obj); + obj->handlers->dtor_obj(obj); + GC_DELREF(obj); + if (EG(exception)) { + return NULL; + } + } + } + + GC_DEL_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); + + /* unset() dynamic properties */ + zend_object_dtor_dynamic_properties(obj); + obj->properties = NULL; + + /* unset() declared properties */ + for (int i = 0; i < ce->default_properties_count; i++) { + zend_property_info *prop_info = obj->ce->properties_info_table[i]; + if (EXPECTED(prop_info)) { + zval *p = &obj->properties_table[i]; + if (Z_TYPE_P(p) != IS_UNDEF) { + if ((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(p) & IS_PROP_REINITABLE) + && (obj->ce->ce_flags & ZEND_ACC_FINAL)) { + continue; + } + zend_object_dtor_property(obj, p); + ZVAL_UNDEF(p); + } + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + lazy_properties_count++; + } + } + } + + /* Objects become non-lazy if all properties are made non-lazy before + * initialization is triggerd. If the object has no properties to begin + * with, this happens immediately. */ + if (UNEXPECTED(!lazy_properties_count)) { + return obj; + } + + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY; + + if (flags & ZEND_LAZY_OBJECT_STRATEGY_PROXY) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_PROXY; + } else { + ZEND_ASSERT(flags & ZEND_LAZY_OBJECT_STRATEGY_GHOST); + } + + zend_lazy_object_info *info = emalloc(sizeof(*info)); + zend_fcc_dup(&info->u.initializer.fcc, initializer_fcc); + ZVAL_COPY(&info->u.initializer.zv, initializer_zv); + info->flags = flags; + info->lazy_properties_count = lazy_properties_count; + zend_lazy_object_set_info(obj, info); + + return obj; +} + +/** + * Initialization of lazy objects + */ + +/* Mark object as initialized. Lazy properties are initialized to their default + * value and the initializer is not called. */ +ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_class_entry *ce = obj->ce; + + if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + ZEND_ASSERT(EG(exception)); + return NULL; + } + } + + zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce); + zval *properties_table = obj->properties_table; + + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + + for (int i = 0; i < ce->default_properties_count; i++) { + if (Z_PROP_FLAG_P(&properties_table[i]) & IS_PROP_LAZY) { + ZVAL_COPY_PROP(&properties_table[i], &default_properties_table[i]); + } + } + + zend_lazy_object_del_info(obj); + + return obj; +} + +/* Revert initializer effects */ +static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_table_snapshot, HashTable *properties_snapshot) +{ + zend_class_entry *ce = obj->ce; + + if (ce->default_properties_count) { + ZEND_ASSERT(properties_table_snapshot); + zval *properties_table = obj->properties_table; + + for (int i = 0; i < ce->default_properties_count; i++) { + zval *p = &properties_table[i]; + zend_object_dtor_property(obj, p); + ZVAL_COPY_PROP(p, &properties_table_snapshot[i]); + Z_TRY_DELREF_P(p); + + zend_property_info *prop_info = ce->properties_info_table[i]; + if (Z_ISREF_P(p) && prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(p), prop_info); + } + } + + efree(properties_table_snapshot); + } + if (properties_snapshot) { + if (obj->properties != properties_snapshot) { + ZEND_ASSERT((GC_FLAGS(properties_snapshot) & IS_ARRAY_IMMUTABLE) || GC_REFCOUNT(properties_snapshot) >= 1); + zend_release_properties(obj->properties); + obj->properties = properties_snapshot; + } else { + ZEND_ASSERT((GC_FLAGS(properties_snapshot) & IS_ARRAY_IMMUTABLE) || GC_REFCOUNT(properties_snapshot) > 1); + zend_release_properties(properties_snapshot); + } + } else if (obj->properties) { + zend_release_properties(obj->properties); + obj->properties = NULL; + } + + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY; +} + +static bool zend_lazy_object_compatible(zend_object *real_object, zend_object *lazy_object) +{ + if (EXPECTED(real_object->ce == lazy_object->ce)) { + return true; + } + + if (!instanceof_function(lazy_object->ce, real_object->ce)) { + return false; + } + + /* zend_hash_num_elements(ce.properties_info) reports the actual number of + * properties. ce.default_properties_count is off by the number of property + * overrides. */ + if (zend_hash_num_elements(&lazy_object->ce->properties_info) != zend_hash_num_elements(&real_object->ce->properties_info)) { + return false; + } + + return lazy_object->ce->destructor == real_object->ce->destructor + && lazy_object->ce->clone == real_object->ce->clone; +} + +/* Initialize a lazy proxy object */ +static zend_object *zend_lazy_object_init_proxy(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy_proxy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + /* prevent reentrant initialization */ + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + + /* Call factory */ + zval retval; + int argc = 1; + zval zobj; + HashTable *named_params = NULL; + zend_fcall_info_cache *initializer = &info->u.initializer.fcc; + + ZVAL_OBJ(&zobj, obj); + + zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params); + + if (UNEXPECTED(EG(exception))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + return NULL; + } + + if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT || !zend_lazy_object_compatible(Z_OBJ(retval), obj))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + zend_type_error("The real instance class %s is not compatible with the proxy class %s. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.", + zend_zval_value_name(&retval), + ZSTR_VAL(obj->ce->name)); + zval_ptr_dtor(&retval); + return NULL; + } + + if (UNEXPECTED(Z_OBJ(retval) == obj || zend_object_is_lazy(Z_OBJ(retval)))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); + zval_ptr_dtor(&retval); + return NULL; + } + + if (info->flags & ZEND_LAZY_OBJECT_CLONE) { + /* For uninitialized lazy proxies, cloning of the real instance is + * postponed until initialization */ + + zend_object *clone = Z_OBJ_HT(retval)->clone_obj(Z_OBJ(retval)); + if (EG(exception)) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + zval_ptr_dtor(&retval); + OBJ_RELEASE(clone); + return NULL; + } + + ZEND_ASSERT(zend_lazy_object_compatible(clone, obj)); + + if (zend_object_is_lazy(clone)) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); + zval_ptr_dtor(&retval); + return NULL; + } + + zval_ptr_dtor(&retval); + ZVAL_OBJ(&retval, clone); + } + + zend_fcc_dtor(&info->u.initializer.fcc); + zval_ptr_dtor(&info->u.initializer.zv); + info->u.instance = Z_OBJ(retval); + info->flags |= ZEND_LAZY_OBJECT_INITIALIZED; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_PROXY; + + /* unset() properties of the proxy. This ensures that all accesses are be + * delegated to the backing instance from now on. */ + // TODO: test that props are undef after initialization + zend_object_dtor_dynamic_properties(obj); + obj->properties = NULL; + + for (int i = 0; i < Z_OBJ(retval)->ce->default_properties_count; i++) { + if (EXPECTED(Z_OBJ(retval)->ce->properties_info_table[i])) { + zend_object_dtor_property(obj, &obj->properties_table[i]); + ZVAL_UNDEF(&obj->properties_table[i]); + Z_PROP_FLAG_P(&obj->properties_table[i]) = IS_PROP_UNINIT | IS_PROP_LAZY; + } + } + + return Z_OBJ(retval); +} + +/* Initialize a lazy object. */ +ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + + /* If obj is an initialized lazy proxy, return the real instance. This + * supports the following pattern: + * if (zend_lazy_object_must_init(obj)) { + * instance = zend_lazy_object_init(obj); + * } + */ + if (zend_lazy_object_initialized(obj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(obj)); + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_INITIALIZED); + return info->u.instance; + } + + zend_class_entry *ce = obj->ce; + + if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + ZEND_ASSERT(EG(exception)); + return NULL; + } + } + + if (zend_object_is_lazy_proxy(obj)) { + return zend_lazy_object_init_proxy(obj); + } + + zend_fcall_info_cache *initializer = zend_lazy_object_get_initializer_fcc(obj); + + /* Prevent reentrant initialization */ + OBJ_EXTRA_FLAGS(obj) &= ~IS_OBJ_LAZY; + + /* Snapshot dynamic properties */ + HashTable *properties_snapshot = obj->properties; + if (properties_snapshot) { + GC_TRY_ADDREF(properties_snapshot); + } + + zval *properties_table_snapshot = NULL; + + /* Snapshot declared properties and initialize lazy properties to their + * default value */ + if (ce->default_properties_count) { + zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce); + zval *properties_table = obj->properties_table; + properties_table_snapshot = emalloc(sizeof(*properties_table_snapshot) * ce->default_properties_count); + + for (int i = 0; i < ce->default_properties_count; i++) { + ZVAL_COPY_PROP(&properties_table_snapshot[i], &properties_table[i]); + if (Z_PROP_FLAG_P(&properties_table[i]) & IS_PROP_LAZY) { + ZVAL_COPY_PROP(&properties_table[i], &default_properties_table[i]); + } + } + } + + /* Call initializer */ + zval retval; + int argc = 1; + zval zobj; + HashTable *named_params = NULL; + + ZVAL_OBJ(&zobj, obj); + + zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params); + + if (EG(exception)) { + zend_lazy_object_revert_init(obj, properties_table_snapshot, properties_snapshot); + return NULL; + } + + if (Z_TYPE(retval) != IS_NULL) { + zend_lazy_object_revert_init(obj, properties_table_snapshot, properties_snapshot); + zval_ptr_dtor(&retval); + zend_type_error("Lazy object initializer must return NULL or no value"); + return NULL; + } + + if (properties_table_snapshot) { + for (int i = 0; i < obj->ce->default_properties_count; i++) { + zval *p = &properties_table_snapshot[i]; + /* Use zval_ptr_dtor directly here (not zend_object_dtor_property), + * as any reference type_source will have already been deleted in + * case the prop is not bound to this value anymore. */ + i_zval_ptr_dtor(p); + } + efree(properties_table_snapshot); + } + + if (properties_snapshot) { + zend_release_properties(properties_snapshot); + } + + zend_lazy_object_del_info(obj); + + return obj; +} + +/* Mark an object as non-lazy (after all properties were initialized) */ +void zend_lazy_object_realize(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_del_info(obj); + +#if ZEND_DEBUG + for (int i = 0; i < obj->ce->default_properties_count; i++) { + ZEND_ASSERT(!(Z_PROP_FLAG_P(&obj->properties_table[i]) & IS_PROP_LAZY)); + } +#endif + + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY | IS_OBJ_LAZY_PROXY); +} + +/* Initialize object and clone it. For proxies, we clone both the proxy and its + * real instance, and we don't call __clone() on the proxy. */ +zend_object *zend_lazy_object_clone(zend_object *old_obj) +{ + ZEND_ASSERT(zend_object_is_lazy(old_obj)); + + if (UNEXPECTED(!zend_lazy_object_initialized(old_obj) && !zend_lazy_object_init(old_obj))) { + ZEND_ASSERT(EG(exception)); + /* Clone handler must always return an object. It is discarded later due + * to the exception. */ + zval zv; + object_init_ex(&zv, old_obj->ce); + GC_ADD_FLAGS(Z_OBJ(zv), IS_OBJ_DESTRUCTOR_CALLED); + return Z_OBJ(zv); + } + + if (!zend_object_is_lazy_proxy(old_obj)) { + return zend_objects_clone_obj(old_obj); + } + + zend_lazy_object_info *info = zend_lazy_object_get_info(old_obj); + zend_class_entry *ce = old_obj->ce; + zend_object *new_proxy = zend_objects_new(ce); + + for (int i = 0; i < ce->default_properties_count; i++) { + zval *p = &new_proxy->properties_table[i]; + ZVAL_UNDEF(p); + if (EXPECTED(ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + } else { + Z_PROP_FLAG_P(p) = 0; + } + } + + OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj); + + zend_lazy_object_info *new_info = emalloc(sizeof(*info)); + *new_info = *info; + new_info->u.instance = zend_objects_clone_obj(info->u.instance); + + zend_lazy_object_set_info(new_proxy, new_info); + + return new_proxy; +} + +HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp) +{ + ZEND_ASSERT(zend_object_is_lazy(object)); + + if (zend_object_is_lazy_proxy(object)) { + if (zend_lazy_object_initialized(object)) { + HashTable *properties = zend_new_array(0); + zval instance; + ZVAL_OBJ(&instance, zend_lazy_object_get_instance(object)); + Z_ADDREF(instance); + zend_hash_str_add(properties, "instance", strlen("instance"), &instance); + *is_temp = 1; + return properties; + } + } + + *is_temp = 0; + return zend_get_properties_no_init(object); +} diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h new file mode 100644 index 0000000000000..ca1ad4a630a3d --- /dev/null +++ b/Zend/zend_lazy_objects.h @@ -0,0 +1,107 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_LAZY_OBJECT_H +#define ZEND_LAZY_OBJECT_H + +#include "Zend/zend_types.h" + +/* Lazy object is a lazy proxy object */ +#define ZEND_LAZY_OBJECT_STRATEGY_PROXY (1<<0) + +/* Lazy object is a lazy ghost object */ +#define ZEND_LAZY_OBJECT_STRATEGY_GHOST (1<<1) + +/* Lazy object is initialized (info.u is an instance) */ +#define ZEND_LAZY_OBJECT_INITIALIZED (1<<2) + +/* Serialization skips initialization */ +#define ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE (1<<3) + +/* Do not call destructor when making existing object lazy */ +#define ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR (1<<4) + +/* The object is a clone */ +#define ZEND_LAZY_OBJECT_CLONE (1<<5) + +#define ZEND_LAZY_OBJECT_USER_FLAGS ( \ + ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE | \ + ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR \ +) + +#define ZEND_LAZY_OBJECT_STRATEGY_FLAGS ( \ + ZEND_LAZY_OBJECT_STRATEGY_PROXY | \ + ZEND_LAZY_OBJECT_STRATEGY_GHOST \ +) + +typedef uint8_t zend_lazy_object_flags_t; + +typedef struct _zend_lazy_objects_store { + /* object handle -> *zend_lazy_object_info */ + HashTable infos; +} zend_lazy_objects_store; + +typedef struct _zend_fcall_info zend_fcall_info; +typedef struct _zend_fcall_info_cache zend_fcall_info_cache; + +ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, + zend_class_entry *class_type, zval *initializer_zv, + zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags); +ZEND_API zend_object *zend_lazy_object_init(zend_object *obj); +ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj); + +void zend_lazy_objects_init(zend_lazy_objects_store *store); +void zend_lazy_objects_destroy(zend_lazy_objects_store *store); +zval* zend_lazy_object_get_initializer_zv(zend_object *obj); +zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj); +zend_object *zend_lazy_object_get_instance(zend_object *obj); +zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); +void zend_lazy_object_del_info(zend_object *obj); +zend_object *zend_lazy_object_clone(zend_object *old_obj); +HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); +bool zend_lazy_object_decr_lazy_props(zend_object *obj); +void zend_lazy_object_realize(zend_object *obj); + +static zend_always_inline bool zend_object_is_lazy(zend_object *obj) +{ + return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY | IS_OBJ_LAZY_PROXY)); +} + +static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj) +{ + return (OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_PROXY); +} + +static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj) +{ + return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY); +} + +/* True if accessing a lazy prop on obj mandates a call to + * zend_lazy_object_init() */ +static zend_always_inline bool zend_lazy_object_must_init(zend_object *obj) +{ + return zend_object_is_lazy(obj); +} + +static inline bool zend_lazy_object_initialize_on_serialize(zend_object *obj) +{ + return !(zend_lazy_object_get_flags(obj) & ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); +} + +#endif /* ZEND_LAZY_OBJECT_H */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index fdac24ccb258b..cceede535cb8d 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -20,6 +20,7 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_lazy_objects.h" #include "zend_variables.h" #include "zend_API.h" #include "zend_objects.h" @@ -92,6 +93,7 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj) /* {{{ } /* }}} */ +/* Implements the fast path for array cast */ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* {{{ */ { zend_property_info *prop_info; @@ -100,6 +102,7 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* zval* prop; int i; + ZEND_ASSERT(!(zend_object_is_lazy_proxy(zobj) && zend_lazy_object_initialized(zobj))); ZEND_ASSERT(!zobj->properties); ht = zend_new_array(ce->default_properties_count); if (ce->default_properties_count) { @@ -130,13 +133,29 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* ZEND_API HashTable *zend_std_get_properties(zend_object *zobj) /* {{{ */ { - if (!zobj->properties) { - return rebuild_object_properties_internal(zobj); - } - return zobj->properties; + return zend_std_get_properties_ex(zobj); } /* }}} */ +/* Fetch properties HashTable without triggering lazy initialization */ +ZEND_API HashTable *zend_get_properties_no_init(zend_object *zobj) +{ + if (zobj->handlers->get_properties == zend_std_get_properties) { + if (UNEXPECTED(zend_object_is_lazy_proxy(zobj) + && zend_lazy_object_initialized(zobj))) { + zend_object *instance = zend_lazy_object_get_instance(zobj); + return zend_get_properties_no_init(instance); + } + + if (!zobj->properties) { + rebuild_object_properties_internal(zobj); + } + return zobj->properties; + } + + return zobj->handlers->get_properties(zobj); +} + ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /* {{{ */ { if (zobj->handlers->get_properties != zend_std_get_properties) { @@ -144,7 +163,37 @@ ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /* *n = 0; return zobj->handlers->get_properties(zobj); } else { - if (zobj->properties) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + if (zend_lazy_object_initialized(zobj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(zobj)); + zend_object *instance = zend_lazy_object_get_instance(zobj); + zend_get_gc_buffer_add_obj(gc_buffer, instance); + } else { + zend_fcall_info_cache* initializer = zend_lazy_object_get_initializer_fcc(zobj); + if (initializer) { + // TODO: also expose _get_initializer_zv() to the GC + if (initializer->object) { + zend_get_gc_buffer_add_obj(gc_buffer, initializer->object); + } + if (initializer->closure) { + zend_get_gc_buffer_add_obj(gc_buffer, initializer->closure); + } + } + } + if (zobj->properties) { + zend_get_gc_buffer_use(gc_buffer, table, n); + return zobj->properties; + } else { + zval *prop = zobj->properties_table; + zval *end = prop + zobj->ce->default_properties_count; + for ( ; prop < end; prop++) { + zend_get_gc_buffer_add_zval(gc_buffer, prop); + } + zend_get_gc_buffer_use(gc_buffer, table, n); + return NULL; + } + } else if (zobj->properties) { *table = NULL; *n = 0; return zobj->properties; @@ -164,6 +213,10 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) / HashTable *ht; if (!ce->__debugInfo) { + if (UNEXPECTED(zend_object_is_lazy(object))) { + return zend_lazy_object_debug_info(object, is_temp); + } + *is_temp = 0; return object->handlers->get_properties(object); } @@ -826,6 +879,8 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int goto exit; } + retval = &EG(uninitialized_zval); + /* magic isset */ if ((type == BP_VAR_IS) && zobj->ce->__isset) { zval tmp_result; @@ -894,6 +949,17 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int } uninit_error: + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (!prop_info || (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY)) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + retval = &EG(uninitialized_zval); + goto exit; + } + + return zend_std_read_property(zobj, name, type, cache_slot, rv); + } + } if (type != BP_VAR_IS) { if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); @@ -1005,6 +1071,11 @@ found:; goto exit; } if (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_UNINIT) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_LAZY) { + goto lazy_init; + } + } /* Writes to uninitialized typed properties bypass __set(). */ goto write_std_property; } @@ -1082,6 +1153,10 @@ found:; OBJ_RELEASE(zobj); variable_ptr = value; } else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + goto lazy_init; + } + goto write_std_property; } else { /* Trigger the correct error */ @@ -1092,6 +1167,9 @@ found:; } } else { ZEND_ASSERT(!IS_WRONG_PROPERTY_OFFSET(property_offset)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + goto lazy_init; + } write_std_property: if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { variable_ptr = OBJ_PROP(zobj, property_offset); @@ -1122,6 +1200,14 @@ found:; exit: return variable_ptr; + +lazy_init: + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(!zobj)) { + variable_ptr = &EG(error_zval); + goto exit; + } + return zend_std_write_property(zobj, name, value, cache_slot); } /* }}} */ @@ -1252,6 +1338,14 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam if (EXPECTED(!zobj->ce->__get) || UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET) || UNEXPECTED(prop_info && (Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT))) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return &EG(error_zval); + } + + return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot); + } if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); @@ -1302,13 +1396,21 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam return &EG(error_zval); } } + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return &EG(error_zval); + } + + return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot); + } if (UNEXPECTED(!zobj->properties)) { rebuild_object_properties_internal(zobj); } if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { zend_error(E_WARNING, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); } - retval = zend_hash_add(zobj->properties, name, &EG(uninitialized_zval)); + retval = zend_hash_add(zend_std_get_properties(zobj), name, &EG(uninitialized_zval)); } } else if (!IS_HOOKED_PROPERTY_OFFSET(property_offset) && zobj->ce->__get == NULL) { retval = &EG(error_zval); @@ -1368,6 +1470,14 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void return; } if (UNEXPECTED(Z_PROP_FLAG_P(slot) & IS_PROP_UNINIT)) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(slot) & IS_PROP_LAZY))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return; + } + return zend_std_unset_property(zobj, name, cache_slot); + } + /* Reset the IS_PROP_UNINIT flag, if it exists and bypass __unset(). */ Z_PROP_FLAG_P(slot) = 0; return; @@ -1401,6 +1511,7 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void (*guard) |= IN_UNSET; /* prevent circular unsetting */ zend_std_call_unsetter(zobj, name); (*guard) &= ~IN_UNSET; + return; } else if (UNEXPECTED(IS_WRONG_PROPERTY_OFFSET(property_offset))) { /* Trigger the correct error */ zend_wrong_offset(zobj->ce, name); @@ -1410,6 +1521,14 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void /* Nothing to do: The property already does not exist. */ } } + + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return; + } + return zend_std_unset_property(zobj, name, cache_slot); + } } /* }}} */ @@ -2062,8 +2181,7 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has } if (UNEXPECTED(Z_PROP_FLAG_P(value) & IS_PROP_UNINIT)) { /* Skip __isset() for uninitialized typed properties */ - result = false; - goto exit; + goto lazy_init; } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { if (EXPECTED(zobj->properties != NULL)) { @@ -2146,6 +2264,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has goto exit; } + if (!zobj->ce->__isset) { + goto lazy_init; + } + result = false; if ((has_set_exists != ZEND_PROPERTY_EXISTS) && zobj->ce->__isset) { uint32_t *guard = zend_get_property_guard(zobj, name); @@ -2177,6 +2299,22 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has exit: return result; + +lazy_init: + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (!value || (Z_PROP_FLAG_P(value) & IS_PROP_LAZY)) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + result = 0; + goto exit; + } + + return zend_std_has_property(zobj, name, has_set_exists, cache_slot); + } + } + + result = 0; + goto exit; } /* }}} */ @@ -2259,14 +2397,29 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp if (obj->ce->num_hooked_props) { return zend_hooked_object_build_properties(obj); } - ZEND_FALLTHROUGH; - case ZEND_PROP_PURPOSE_ARRAY_CAST: - case ZEND_PROP_PURPOSE_SERIALIZE: ht = obj->handlers->get_properties(obj); if (ht) { GC_TRY_ADDREF(ht); } return ht; + case ZEND_PROP_PURPOSE_ARRAY_CAST: + ht = zend_get_properties_no_init(obj); + if (ht) { + GC_TRY_ADDREF(ht); + } + return ht; + case ZEND_PROP_PURPOSE_SERIALIZE: { + if (zend_object_is_lazy(obj) + && !zend_lazy_object_initialize_on_serialize(obj)) { + ht = zend_get_properties_no_init(obj); + } else { + ht = obj->handlers->get_properties(obj); + } + if (ht) { + GC_TRY_ADDREF(ht); + } + return ht; + } default: ZEND_UNREACHABLE(); return NULL; diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 8ec2164413df5..7ac2051ea3870 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -24,6 +24,7 @@ #include "zend_types.h" #include "zend_property_hooks.h" +#include "zend_lazy_objects.h" struct _zend_property_info; @@ -251,6 +252,7 @@ ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zen ZEND_API zend_function *zend_std_get_constructor(zend_object *object); ZEND_API struct _zend_property_info *zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent); ZEND_API HashTable *zend_std_get_properties(zend_object *object); +ZEND_API HashTable *zend_get_properties_no_init(zend_object *zobj); ZEND_API HashTable *zend_std_get_gc(zend_object *object, zval **table, int *n); ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp); ZEND_API zend_result zend_std_cast_object_tostring(zend_object *object, zval *writeobj, int type); @@ -272,12 +274,19 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { + if (UNEXPECTED(zend_lazy_object_must_init(object))) { + zend_object *instance = zend_lazy_object_init(object); + if (EXPECTED(instance)) { + object = instance; + } + } if (!object->properties) { return rebuild_object_properties_internal(object); } return object->properties; } +/* Implements the fast path for array cast */ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj); /* Handler for objects that cannot be meaningfully compared. diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index af4d1f265897a..bdfc2a814aa35 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -25,12 +25,14 @@ #include "zend_interfaces.h" #include "zend_exceptions.h" #include "zend_weakrefs.h" +#include "zend_lazy_objects.h" static zend_always_inline void _zend_object_std_init(zend_object *object, zend_class_entry *ce) { GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT; object->ce = ce; + object->flags = 0; object->handlers = ce->default_object_handlers; object->properties = NULL; zend_objects_store_put(object); @@ -46,14 +48,8 @@ ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class _zend_object_std_init(object, ce); } -ZEND_API void zend_object_std_dtor(zend_object *object) +void zend_object_dtor_dynamic_properties(zend_object *object) { - zval *p, *end; - - if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { - zend_weakrefs_notify(object); - } - if (object->properties) { if (EXPECTED(!(GC_FLAGS(object->properties) & IS_ARRAY_IMMUTABLE))) { if (EXPECTED(GC_DELREF(object->properties) == 0) @@ -62,20 +58,41 @@ ZEND_API void zend_object_std_dtor(zend_object *object) } } } +} + +void zend_object_dtor_property(zend_object *object, zval *p) +{ + if (Z_REFCOUNTED_P(p)) { + if (UNEXPECTED(Z_ISREF_P(p)) && + (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { + zend_property_info *prop_info = zend_get_property_info_for_slot(object, p); + if (ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); + } + } + i_zval_ptr_dtor(p); + } +} + +ZEND_API void zend_object_std_dtor(zend_object *object) +{ + zval *p, *end; + + if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + zend_weakrefs_notify(object); + } + + if (UNEXPECTED(zend_object_is_lazy(object))) { + zend_lazy_object_del_info(object); + } + + zend_object_dtor_dynamic_properties(object); + p = object->properties_table; if (EXPECTED(object->ce->default_properties_count)) { end = p + object->ce->default_properties_count; do { - if (Z_REFCOUNTED_P(p)) { - if (UNEXPECTED(Z_ISREF_P(p)) && - (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { - zend_property_info *prop_info = zend_get_property_info_for_slot(object, p); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); - } - } - i_zval_ptr_dtor(p); - } + zend_object_dtor_property(object, p); p++; } while (p != end); } @@ -99,6 +116,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) zend_function *destructor = object->ce->destructor; if (destructor) { + if (UNEXPECTED(zend_object_is_lazy(object))) { + return; + } + zend_object *old_exception; const zend_op *old_opline_before_exception; @@ -286,18 +307,22 @@ ZEND_API zend_object *zend_objects_clone_obj(zend_object *old_object) { zend_object *new_object; - /* assume that create isn't overwritten, so when clone depends on the - * overwritten one then it must itself be overwritten */ - new_object = zend_objects_new(old_object->ce); - - /* zend_objects_clone_members() expect the properties to be initialized. */ - if (new_object->ce->default_properties_count) { - zval *p = new_object->properties_table; - zval *end = p + new_object->ce->default_properties_count; - do { - ZVAL_UNDEF(p); - p++; - } while (p != end); + if (UNEXPECTED(zend_object_is_lazy(old_object))) { + return zend_lazy_object_clone(old_object); + } else { + /* assume that create isn't overwritten, so when clone depends on the + * overwritten one then it must itself be overwritten */ + new_object = zend_objects_new(old_object->ce); + + /* zend_objects_clone_members() expect the properties to be initialized. */ + if (new_object->ce->default_properties_count) { + zval *p = new_object->properties_table; + zval *end = p + new_object->ce->default_properties_count; + do { + ZVAL_UNDEF(p); + p++; + } while (p != end); + } } zend_objects_clone_members(new_object, old_object); diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 91d388154dd13..41e3bcd9594b1 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -30,6 +30,10 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, ZEND_API void zend_object_std_dtor(zend_object *object); ZEND_API void zend_objects_destroy_object(zend_object *object); ZEND_API zend_object *zend_objects_clone_obj(zend_object *object); + +void zend_object_dtor_dynamic_properties(zend_object *object); +void zend_object_dtor_property(zend_object *object, zval *p); + END_EXTERN_C() #endif /* ZEND_OBJECTS_H */ diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 5331244731cac..a3446bdcc4a99 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -814,7 +814,8 @@ ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */ convert_scalar_to_array(op); } else if (Z_OBJ_P(op)->properties == NULL && Z_OBJ_HT_P(op)->get_properties_for == NULL - && Z_OBJ_HT_P(op)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(op)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(op)) && !zend_lazy_object_initialized(Z_OBJ_P(op)))) { /* Optimized version without rebuilding properties HashTable */ HashTable *ht = zend_std_build_object_properties_array(Z_OBJ_P(op)); OBJ_RELEASE(Z_OBJ_P(op)); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index d33f8a33bcbe6..d6aec3a35b4bd 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -556,6 +556,7 @@ typedef struct _HashTableIterator { struct _zend_object { zend_refcounted_h gc; uint32_t handle; // TODO: may be removed ??? + uint32_t flags; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; @@ -829,6 +830,13 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define OBJ_FLAGS(obj) GC_FLAGS(obj) +/* object extra flags (zend_object.flags) */ + +#define IS_OBJ_LAZY (1U<<31) /* Virtual proxy or uninitialized Ghost */ +#define IS_OBJ_LAZY_PROXY (1U<<30) /* Virtual proxy (may be initialized) */ + +#define OBJ_EXTRA_FLAGS(obj) ((obj)->flags) + /* Fast class cache */ #define ZSTR_HAS_CE_CACHE(s) (GC_FLAGS(s) & IS_STR_CLASS_NAME_MAP_PTR) #define ZSTR_GET_CE_CACHE(s) ZSTR_GET_CE_CACHE_EX(s, 1) @@ -1556,6 +1564,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { * macros for this purpose, so this workaround is easier to remove in the future. */ #define IS_PROP_UNINIT (1<<0) #define IS_PROP_REINITABLE (1<<1) /* It has impact only on readonly properties */ +#define IS_PROP_LAZY (1<<2) #define Z_PROP_FLAG_P(z) Z_EXTRA_P(z) #define ZVAL_COPY_VALUE_PROP(z, v) \ do { *(z) = *(v); } while (0) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 55fdb7d46582b..772bc27869121 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6431,7 +6431,8 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) } } else if (Z_OBJ_P(expr)->properties == NULL && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 16455b6e0cd58..edcab7848cc10 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5174,7 +5174,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H } } else if (Z_OBJ_P(expr)->properties == NULL && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -20047,7 +20048,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC } } else if (Z_OBJ_P(expr)->properties == NULL && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -22700,7 +22702,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC } } else if (Z_OBJ_P(expr)->properties == NULL && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -40745,7 +40748,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO } } else if (Z_OBJ_P(expr)->properties == NULL && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties + && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { diff --git a/configure.ac b/configure.ac index 2693ba09f4af9..6a30788a2afce 100644 --- a/configure.ac +++ b/configure.ac @@ -1743,6 +1743,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ zend_iterators.c zend_language_parser.c zend_language_scanner.c + zend_lazy_objects.c zend_list.c zend_llist.c zend_max_execution_timer.c diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index d53427523f4bc..f5fe23f955398 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -246,6 +246,7 @@ static zend_always_inline void zend_ffi_object_init(zend_object *object, zend_cl { GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT | (IS_OBJ_DESTRUCTOR_CALLED << GC_FLAGS_SHIFT); + object->flags = 0; object->ce = ce; object->handlers = ce->default_object_handlers; object->properties = NULL; diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 1e344cde436ff..6d28ab033336d 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -28,6 +28,7 @@ #include #include "zend_enum.h" #include "zend_property_hooks.h" +#include "zend_lazy_objects.h" static const char digits[] = "0123456789abcdef"; @@ -127,6 +128,14 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, && Z_OBJ_P(val)->ce->num_hooked_props == 0) { /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(val); + + if (zend_lazy_object_must_init(Z_OBJ_P(val))) { + obj = zend_lazy_object_init(Z_OBJ_P(val)); + if (!obj) { + return FAILURE; + } + } + zend_class_entry *ce = obj->ce; zend_property_info *prop_info; zval *prop; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1215fa8b1ad48..9354bf626877e 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -19,7 +19,11 @@ */ #include "zend_compile.h" +#include "zend_execute.h" +#include "zend_lazy_objects.h" +#include "zend_object_handlers.h" #include "zend_type_info.h" +#include "zend_types.h" #ifdef HAVE_CONFIG_H #include #endif @@ -474,7 +478,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char smart_str_append_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(Z_OBJ_P(obj)); + HashTable *properties = zend_get_properties_no_init(Z_OBJ_P(obj)); zend_string *prop_name; smart_str prop_str = {0}; @@ -5187,6 +5191,195 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) } /* }}} */ +void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, + int strategy, bool is_reset) +{ + reflection_object *intern; + zend_object *obj; + zend_class_entry *ce; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zend_long flags = 0; + + ZEND_ASSERT(strategy == ZEND_LAZY_OBJECT_STRATEGY_GHOST + || strategy == ZEND_LAZY_OBJECT_STRATEGY_PROXY); + + GET_REFLECTION_OBJECT_PTR(ce); + + if (is_reset) { + ZEND_PARSE_PARAMETERS_START(2, 3) + // TODO: check that obj->ce matches ce + Z_PARAM_OBJ_OF_CLASS(obj, ce) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_OPTIONAL + // TODO: check named param + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); + } else { + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); + obj = NULL; + } + + if (flags & ~ZEND_LAZY_OBJECT_USER_FLAGS) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Invalid flags"); + RETURN_THROWS(); + } + + if (is_reset) { + if (zend_object_is_lazy(obj) && !zend_lazy_object_initialized(obj)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Object is already lazy"); + RETURN_THROWS(); + } + } else { + obj = NULL; + } + + if (!fcc.function_handler) { + /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal + * with it ourselves. It is important that it is not refetched on every call, + * because calls may occur from different scopes. */ + zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); + } + + obj = zend_object_make_lazy(obj, ce, &fci.function_name, &fcc, + strategy | flags); + + if (!obj) { + RETURN_THROWS(); + } + + if (!is_reset) { + RETURN_OBJ(obj); + } +} + +/* {{{ Instantiates a lazy instance, using the ghost strategy */ +PHP_METHOD(ReflectionClass, newLazyGhost) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_GHOST, /*is_make_lazy */ false); +} +/* }}} */ + +/* {{{ Instantiates a lazy instance, using the proxy strategy */ +PHP_METHOD(ReflectionClass, newLazyProxy) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /*is_make_lazy */ false); +} +/* }}} */ + +/* {{{ Reset an object and make it lazy, using the ghost strategy */ +PHP_METHOD(ReflectionClass, resetAsLazyGhost) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_GHOST, /* is_reset */ true); +} +/* }}} */ + +/* {{{ Reset an object and make it lazy, using the proxy strategy */ +PHP_METHOD(ReflectionClass, resetAsLazyProxy) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /*is_reset */ true); +} +/* }}} */ + +/* {{{ Returns whether object lazy and uninitialized */ +ZEND_METHOD(ReflectionClass, isUninitializedLazyObject) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL(zend_object_is_lazy(object) && !zend_lazy_object_initialized(object)); +} +/* }}} */ + +/* {{{ Trigger object initialization */ +ZEND_METHOD(ReflectionClass, initializeLazyObject) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + zend_lazy_object_init(object); + } + + if (zend_lazy_object_initialized(object)) { + RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); + } else { + ZEND_ASSERT(EG(exception)); + } +} +/* }}} */ + +/* {{{ Mark object as initialized without calling the initializer */ +ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + zend_lazy_object_mark_as_initialized(object); + } + + if (zend_lazy_object_initialized(object)) { + RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); + } else { + ZEND_ASSERT(EG(exception)); + } +} +/* }}} */ + +/* {{{ Get lazy object initializer */ +ZEND_METHOD(ReflectionClass, getLazyInitializer) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (!zend_object_is_lazy(object) + || zend_lazy_object_initialized(object)) { + return; + } + + RETURN_ZVAL(zend_lazy_object_get_initializer_zv(object), 1, 0); +} +/* }}} */ + /* {{{ Returns an array of interfaces this class implements */ ZEND_METHOD(ReflectionClass, getInterfaces) { @@ -5916,6 +6109,148 @@ ZEND_METHOD(ReflectionProperty, setRawValue) } } +/* {{{ Set property value withtout triggering initializer while skipping hooks if any */ +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +{ + reflection_object *intern; + property_reference *ref; + zend_object *object; + zval *value; + + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ref->prop) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use setRawValueWithoutLazyInitialization on dynamic property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + if (ref->prop->flags & ZEND_ACC_STATIC) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use setRawValueWithoutLazyInitialization on static property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + if (ref->prop->flags & ZEND_ACC_VIRTUAL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use setRawValueWithoutLazyInitialization on virtual property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + ZEND_PARSE_PARAMETERS_START(2, 2) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + Z_PARAM_ZVAL(value) + } ZEND_PARSE_PARAMETERS_END(); + + if (object->handlers->write_property != zend_std_write_property) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use setRawValueWithoutLazyInitialization on internal class %s", + ZSTR_VAL(intern->ce->name)); + RETURN_THROWS(); + } + + ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); + + zval *var_ptr = OBJ_PROP(object, ref->prop->offset); + bool prop_was_lazy = Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY; + + /* Do not trigger initialization */ + Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_LAZY; + + if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); + } else { + zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); + zend_call_known_instance_method_with_1_params(func, object, NULL, value); + } + + /* Mark property as lazy again if an exception prevented update */ + if (EG(exception) && Z_TYPE_P(var_ptr) == IS_UNDEF + && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + Z_PROP_FLAG_P(var_ptr) |= IS_PROP_LAZY; + } + + /* Object becomes non-lazy if this was the last lazy prop */ + if (prop_was_lazy && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY) + && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + if (zend_lazy_object_decr_lazy_props(object)) { + zend_lazy_object_realize(object); + } + } +} + +/* {{{ Mark property as non-lazy, and initialize to default value */ +ZEND_METHOD(ReflectionProperty, skipLazyInitialization) +{ + reflection_object *intern; + property_reference *ref; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ref->prop) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use skipLazyInitialization on dynamic property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + if (ref->prop->flags & ZEND_ACC_STATIC) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use skipLazyInitialization on static property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + if (ref->prop->flags & ZEND_ACC_VIRTUAL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use skipLazyInitialization on virtual property %s::$%s", + ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); + RETURN_THROWS(); + } + + ZEND_PARSE_PARAMETERS_START(1, 1) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + } ZEND_PARSE_PARAMETERS_END(); + + if (object->handlers->write_property != zend_std_write_property) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use skipLazyInitialization on internal class %s", + ZSTR_VAL(intern->ce->name)); + RETURN_THROWS(); + } + + ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); + + bool prop_was_lazy = (Z_PROP_FLAG_P(OBJ_PROP(object, ref->prop->offset)) & IS_PROP_LAZY); + + zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; + zval *dst = OBJ_PROP(object, ref->prop->offset); + + if (!(Z_PROP_FLAG_P(dst) & IS_PROP_LAZY)) { + /* skipLazyInitialization has no effect on non-lazy properties */ + return; + } + + ZEND_ASSERT(Z_TYPE_P(dst) == IS_UNDEF && "Lazy property should be UNDEF"); + + ZVAL_COPY_OR_DUP_PROP(dst, src); + Z_PROP_FLAG_P(dst) &= ~(IS_PROP_LAZY | IS_PROP_REINITABLE); + + /* Object becomes non-lazy if this was the last lazy prop */ + if (prop_was_lazy && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + if (zend_lazy_object_decr_lazy_props(object)) { + zend_lazy_object_realize(object); + } + } +} + /* {{{ Returns true if property was initialized */ ZEND_METHOD(ReflectionProperty, isInitialized) { diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index 6420b04520aa6..d676597fd0bed 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -47,6 +47,7 @@ extern PHPAPI zend_class_entry *reflection_enum_ptr; extern PHPAPI zend_class_entry *reflection_enum_unit_case_ptr; extern PHPAPI zend_class_entry *reflection_enum_backed_case_ptr; extern PHPAPI zend_class_entry *reflection_fiber_ptr; +extern PHPAPI zend_class_entry *reflection_lazy_object_ptr; PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object); diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 2bb9a9a5efa01..366c13f3a1a1d 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -250,6 +250,12 @@ class ReflectionClass implements Reflector /** @cvalue ZEND_ACC_READONLY_CLASS */ public const int IS_READONLY = UNKNOWN; + /** @cvalue ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE */ + public const int SKIP_INITIALIZATION_ON_SERIALIZE = UNKNOWN; + + /** @cvalue ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR */ + public const int SKIP_DESTRUCTOR = UNKNOWN; + public string $name; private function __clone(): void {} @@ -370,6 +376,22 @@ public function newInstanceWithoutConstructor(): object {} /** @tentative-return-type */ public function newInstanceArgs(array $args = []): ?object {} + public function newLazyGhost(callable $initializer, int $options = 0): object {} + + public function newLazyProxy(callable $factory, int $options = 0): object {} + + public function resetAsLazyGhost(object $object, callable $factory, int $options = 0): void {} + + public function resetAsLazyProxy(object $object, callable $factory, int $options = 0): void {} + + public function initializeLazyObject(object $object): object {} + + public function isUninitializedLazyObject(object $object): bool {} + + public function markLazyObjectAsInitialized(object $object): object {} + + public function getLazyInitializer(object $object): ?callable {} + /** @tentative-return-type */ public function getParentClass(): ReflectionClass|false {} @@ -472,6 +494,10 @@ public function getRawValue(object $object): mixed {} public function setRawValue(object $object, mixed $value): void {} + public function setRawValueWithoutLazyInitialization(object $object, mixed $value): void {} + + public function skipLazyInitialization(object $object): void {} + /** @tentative-return-type */ public function isInitialized(?object $object = null): bool {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 19812c409c053..5d95b25582988 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 28fde6ed0e247201ee25d608d27a4c5b0bb8f2f7 */ + * Stub hash: 09e21577c53d8b53e30aa30e3208d3807ecd8852 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -287,6 +287,38 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_newLazyGhost, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, initializer, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_newLazyProxy, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, factory, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_resetAsLazyGhost, 0, 2, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, factory, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionClass_resetAsLazyProxy arginfo_class_ReflectionClass_resetAsLazyGhost + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_initializeLazyObject, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_isUninitializedLazyObject, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionClass_markLazyObjectAsInitialized arginfo_class_ReflectionClass_initializeLazyObject + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_getLazyInitializer, 0, 1, IS_CALLABLE, 1) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_ReflectionClass_getParentClass, 0, 0, ReflectionClass, MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -361,6 +393,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_setRawV ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionProperty_setRawValueWithoutLazyInitialization arginfo_class_ReflectionProperty_setRawValue + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_skipLazyInitialization, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_isInitialized, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, object, IS_OBJECT, 1, "null") ZEND_END_ARG_INFO() @@ -763,6 +801,14 @@ ZEND_METHOD(ReflectionClass, isInstance); ZEND_METHOD(ReflectionClass, newInstance); ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor); ZEND_METHOD(ReflectionClass, newInstanceArgs); +ZEND_METHOD(ReflectionClass, newLazyGhost); +ZEND_METHOD(ReflectionClass, newLazyProxy); +ZEND_METHOD(ReflectionClass, resetAsLazyGhost); +ZEND_METHOD(ReflectionClass, resetAsLazyProxy); +ZEND_METHOD(ReflectionClass, initializeLazyObject); +ZEND_METHOD(ReflectionClass, isUninitializedLazyObject); +ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized); +ZEND_METHOD(ReflectionClass, getLazyInitializer); ZEND_METHOD(ReflectionClass, getParentClass); ZEND_METHOD(ReflectionClass, isSubclassOf); ZEND_METHOD(ReflectionClass, getStaticProperties); @@ -785,6 +831,8 @@ ZEND_METHOD(ReflectionProperty, getValue); ZEND_METHOD(ReflectionProperty, setValue); ZEND_METHOD(ReflectionProperty, getRawValue); ZEND_METHOD(ReflectionProperty, setRawValue); +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization); +ZEND_METHOD(ReflectionProperty, skipLazyInitialization); ZEND_METHOD(ReflectionProperty, isInitialized); ZEND_METHOD(ReflectionProperty, isPublic); ZEND_METHOD(ReflectionProperty, isPrivate); @@ -1044,6 +1092,14 @@ static const zend_function_entry class_ReflectionClass_methods[] = { ZEND_ME(ReflectionClass, newInstance, arginfo_class_ReflectionClass_newInstance, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, newInstanceWithoutConstructor, arginfo_class_ReflectionClass_newInstanceWithoutConstructor, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, newInstanceArgs, arginfo_class_ReflectionClass_newInstanceArgs, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, newLazyGhost, arginfo_class_ReflectionClass_newLazyGhost, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, newLazyProxy, arginfo_class_ReflectionClass_newLazyProxy, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, resetAsLazyGhost, arginfo_class_ReflectionClass_resetAsLazyGhost, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, resetAsLazyProxy, arginfo_class_ReflectionClass_resetAsLazyProxy, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, initializeLazyObject, arginfo_class_ReflectionClass_initializeLazyObject, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isUninitializedLazyObject, arginfo_class_ReflectionClass_isUninitializedLazyObject, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, markLazyObjectAsInitialized, arginfo_class_ReflectionClass_markLazyObjectAsInitialized, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getLazyInitializer, arginfo_class_ReflectionClass_getLazyInitializer, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getParentClass, arginfo_class_ReflectionClass_getParentClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, isSubclassOf, arginfo_class_ReflectionClass_isSubclassOf, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getStaticProperties, arginfo_class_ReflectionClass_getStaticProperties, ZEND_ACC_PUBLIC) @@ -1080,6 +1136,8 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, setValue, arginfo_class_ReflectionProperty_setValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getRawValue, arginfo_class_ReflectionProperty_getRawValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, setRawValue, arginfo_class_ReflectionProperty_setRawValue, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, setRawValueWithoutLazyInitialization, arginfo_class_ReflectionProperty_setRawValueWithoutLazyInitialization, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, skipLazyInitialization, arginfo_class_ReflectionProperty_skipLazyInitialization, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isInitialized, arginfo_class_ReflectionProperty_isInitialized, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isPublic, arginfo_class_ReflectionProperty_isPublic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isPrivate, arginfo_class_ReflectionProperty_isPrivate, ZEND_ACC_PUBLIC) @@ -1443,6 +1501,18 @@ static zend_class_entry *register_class_ReflectionClass(zend_class_entry *class_ zend_declare_typed_class_constant(class_entry, const_IS_READONLY_name, &const_IS_READONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_IS_READONLY_name); + zval const_SKIP_INITIALIZATION_ON_SERIALIZE_value; + ZVAL_LONG(&const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); + zend_string *const_SKIP_INITIALIZATION_ON_SERIALIZE_name = zend_string_init_interned("SKIP_INITIALIZATION_ON_SERIALIZE", sizeof("SKIP_INITIALIZATION_ON_SERIALIZE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_SKIP_INITIALIZATION_ON_SERIALIZE_name, &const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_SKIP_INITIALIZATION_ON_SERIALIZE_name); + + zval const_SKIP_DESTRUCTOR_value; + ZVAL_LONG(&const_SKIP_DESTRUCTOR_value, ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR); + zend_string *const_SKIP_DESTRUCTOR_name = zend_string_init_interned("SKIP_DESTRUCTOR", sizeof("SKIP_DESTRUCTOR") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_SKIP_DESTRUCTOR_name, &const_SKIP_DESTRUCTOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_SKIP_DESTRUCTOR_name); + zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index 15059211ef01d..9b5c7db436b09 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -11,11 +11,13 @@ echo $rc; --EXPECT-- Class [ class ReflectionClass implements Stringable, Reflector ] { - - Constants [4] { + - Constants [6] { Constant [ public int IS_IMPLICIT_ABSTRACT ] { 16 } Constant [ public int IS_EXPLICIT_ABSTRACT ] { 64 } Constant [ public int IS_FINAL ] { 32 } Constant [ public int IS_READONLY ] { 65536 } + Constant [ public int SKIP_INITIALIZATION_ON_SERIALIZE ] { 8 } + Constant [ public int SKIP_DESTRUCTOR ] { 16 } } - Static properties [0] { @@ -28,7 +30,7 @@ Class [ class ReflectionClass implements Stringable, Refle Property [ public string $name ] } - - Methods [56] { + - Methods [64] { Method [ private method __clone ] { - Parameters [0] { @@ -330,6 +332,76 @@ Class [ class ReflectionClass implements Stringable, Refle - Tentative return [ ?object ] } + Method [ public method newLazyGhost ] { + + - Parameters [2] { + Parameter #0 [ callable $initializer ] + Parameter #1 [ int $options = 0 ] + } + - Return [ object ] + } + + Method [ public method newLazyProxy ] { + + - Parameters [2] { + Parameter #0 [ callable $factory ] + Parameter #1 [ int $options = 0 ] + } + - Return [ object ] + } + + Method [ public method resetAsLazyGhost ] { + + - Parameters [3] { + Parameter #0 [ object $object ] + Parameter #1 [ callable $factory ] + Parameter #2 [ int $options = 0 ] + } + - Return [ void ] + } + + Method [ public method resetAsLazyProxy ] { + + - Parameters [3] { + Parameter #0 [ object $object ] + Parameter #1 [ callable $factory ] + Parameter #2 [ int $options = 0 ] + } + - Return [ void ] + } + + Method [ public method initializeLazyObject ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ object ] + } + + Method [ public method isUninitializedLazyObject ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ bool ] + } + + Method [ public method markLazyObjectAsInitialized ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ object ] + } + + Method [ public method getLazyInitializer ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ ?callable ] + } + Method [ public method getParentClass ] { - Parameters [0] { diff --git a/ext/standard/var.c b/ext/standard/var.c index 7e51a23e3c029..479412de4aea2 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -23,11 +23,13 @@ #include "php.h" #include "php_string.h" #include "php_var.h" +#include "zend_lazy_objects.h" #include "zend_smart_str.h" #include "basic_functions.h" #include "php_incomplete_class.h" #include "zend_enum.h" #include "zend_exceptions.h" +#include "zend_types.h" /* }}} */ struct php_serialize_data { @@ -163,7 +165,19 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("%sobject(%s)#%d (%d) {\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); + + const char *prefix; + if (zend_object_is_lazy(Z_OBJ_P(struc))) { + if (zend_object_is_lazy_proxy(Z_OBJ_P(struc))) { + prefix = "lazy proxy "; + } else { + prefix = "lazy ghost "; + } + } else { + prefix = ""; + } + + php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); zend_string_release_ex(class_name, 0); if (myht) { @@ -360,7 +374,19 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("object(%s)#%d (%d) refcount(%u){\n", ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc)); + + const char *prefix; + if (zend_object_is_lazy(Z_OBJ_P(struc))) { + if (zend_object_is_lazy_proxy(Z_OBJ_P(struc))) { + prefix = "lazy proxy "; + } else { + prefix = "lazy ghost "; + } + } else { + prefix = ""; + } + + php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc)); zend_string_release_ex(class_name, 0); if (myht) { ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) { @@ -1209,6 +1235,16 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties) { /* Optimized version without rebulding properties HashTable */ zend_object *obj = Z_OBJ_P(struc); + + if (zend_lazy_object_must_init(Z_OBJ_P(struc)) + && zend_lazy_object_initialize_on_serialize(Z_OBJ_P(struc))) { + obj = zend_lazy_object_init(Z_OBJ_P(struc)); + if (!obj) { + smart_str_appendl(buf, "N;", 2); + return; + } + } + zend_class_entry *ce = obj->ce; zend_property_info *prop_info; zval *prop; From c5901fc81fd119364de8c4aa08fd34bbb882e823 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 25 Jul 2024 19:07:10 +0200 Subject: [PATCH 226/280] Test cleanup --- Zend/tests/lazy_objects/016.phpt | 45 --------------- Zend/tests/lazy_objects/018.phpt | 57 ------------------- ...002.phpt => clone_calls___clone_once.phpt} | 0 ...es_object_with_independent_state_001.phpt} | 2 +- ...es_object_with_independent_state_002.phpt} | 2 +- ...es_object_with_independent_state_003.phpt} | 2 +- ...{clone_004.phpt => clone_initialized.phpt} | 0 ....phpt => clone_initializer_exception.phpt} | 0 ...{clone_001.phpt => clone_initializes.phpt} | 0 ...phpt => clone_preverves_object_class.phpt} | 7 ++- .../{017.phpt => dtor_called_if_init.phpt} | 20 ++----- .../dtor_not_called_if_not_init.phpt | 43 ++++++++++++++ Zend/tests/lazy_objects/feedback_006.phpt | 29 ---------- ...8.phpt => fetch_coalesce_initializes.phpt} | 8 +-- ...ch_coalesce_non_existing_initializes.phpt} | 8 +-- ...t => fetch_declared_prop_initializes.phpt} | 8 +-- ...pt => fetch_dynamic_prop_initializes.phpt} | 8 +-- ...hpt => fetch_hook_may_not_initialize.phpt} | 10 ++-- ...=> fetch_hook_virtual_may_initialize.phpt} | 10 ++-- ...etch_hook_virtual_may_not_initialize.phpt} | 10 ++-- ...t => fetch_magic_prop_may_initialize.phpt} | 10 ++-- ... fetch_magic_prop_may_not_initialize.phpt} | 10 ++-- ..._magic_prop_recursive_may_initialize.phpt} | 10 ++-- ...h_011.phpt => fetch_op_dynamic_error.phpt} | 8 +-- ...=> fetch_op_dynamic_prop_initializes.phpt} | 8 +-- .../{fetch_012.phpt => fetch_op_error.phpt} | 8 +-- ...tch_003.phpt => fetch_op_initializes.phpt} | 8 +-- ..._op_skipped_prop_does_not_initialize.phpt} | 8 +-- ...ch_010.phpt => fetch_ref_initializes.phpt} | 8 +-- ...ref_skipped_prop_does_not_initialize.phpt} | 8 +-- ...tch_skipped_prop_does_not_initialize.phpt} | 8 +-- ...al_classes_can_be_initialized_lazily.phpt} | 8 +-- .../{feedback_002.phpt => gc_006.phpt} | 2 +- ...ast_const_001.phpt => init_ast_const.phpt} | 0 ...t_002.phpt => init_ast_const_failure.phpt} | 0 ...=> init_exception_leaves_object_lazy.phpt} | 14 +++-- ...xception_reverts_initializer_changes.phpt} | 16 +++--- ...everts_initializer_changes_dyn_props.phpt} | 16 +++--- ...initializer_changes_dyn_props_and_ht.phpt} | 16 +++--- ...n_reverts_initializer_changes_nested.phpt} | 2 +- ..._initializer_changes_overridden_prop.phpt} | 13 +++-- ...reverts_initializer_changes_props_ht.phpt} | 16 +++--- ...rts_initializer_changes_props_ht_ref.phpt} | 16 +++--- .../{024.phpt => init_fatal.phpt} | 3 +- ...hpt => init_handles_ref_source_types.phpt} | 16 +++--- ...t_handles_ref_source_types_exception.phpt} | 15 ++--- ....phpt => init_may_leave_props_uninit.phpt} | 7 ++- ..._004.phpt => init_preserves_identity.phpt} | 2 +- ...3.phpt => init_preserves_proxy_class.phpt} | 2 +- ...hpt => init_sets_prop_default_values.phpt} | 7 ++- ...{012.phpt => init_trigger_array_cast.phpt} | 8 +-- ...phpt => init_trigger_debug_zval_dump.phpt} | 0 .../{006.phpt => init_trigger_foreach.phpt} | 8 +-- ...init_trigger_get_mangled_object_vars.phpt} | 8 +-- ...phpt => init_trigger_get_object_vars.phpt} | 8 +-- ...010.phpt => init_trigger_json_encode.phpt} | 8 +-- ...t_trigger_reflection_object_toString.phpt} | 8 +-- .../{009.phpt => init_trigger_serialize.phpt} | 8 +-- .../{007.phpt => init_trigger_var_dump.phpt} | 1 - ...init_trigger_var_dump_debug_info_001.phpt} | 12 ++-- ...init_trigger_var_dump_debug_info_002.phpt} | 11 ++-- ...{008.phpt => init_trigger_var_export.phpt} | 8 +-- ...ize_001.phpt => initializeLazyObject.phpt} | 10 ++-- ...5.phpt => initializeLazyObject_error.phpt} | 10 ++-- ...azyObject_noop_on_initialized_object.phpt} | 16 +++--- ...itializer_must_return_the_right_type.phpt} | 12 ++-- .../isUninitializedLazyObject.phpt | 49 ++++++++++++++++ .../lazy_objects/is_initialized_001.phpt | 26 --------- .../is_uninitialized_lazy_object.phpt | 31 ---------- ....phpt => isset_hooked_may_initialize.phpt} | 10 ++-- ...t => isset_hooked_may_not_initialize.phpt} | 10 ++-- ...{isset_001.phpt => isset_initializes.phpt} | 8 +-- ....phpt => markLazyObjectAsInitialized.phpt} | 10 ++-- .../lazy_objects/new_instance_lazy_001.phpt | 20 ------- .../lazy_objects/new_instance_lazy_002.phpt | 21 ------- .../lazy_objects/new_instance_lazy_003.phpt | 22 ------- .../lazy_objects/new_instance_lazy_004.phpt | 18 ------ .../lazy_objects/new_instance_lazy_005.phpt | 21 ------- .../{realize_001.phpt => realize.phpt} | 11 ++-- ...realize_003.phpt => realize_no_props.phpt} | 0 ...004.phpt => realize_proxy_overridden.phpt} | 11 ++-- ...{realize_002.phpt => realize_skipped.phpt} | 11 ++-- ...t => reset_as_lazy_already_exception.phpt} | 19 ++++--- ...pt => reset_as_lazy_calls_destructor.phpt} | 8 ++- ...s_lazy_deletes_reference_source_type.phpt} | 8 ++- ...> reset_as_lazy_destructor_exception.phpt} | 8 ++- ...t => reset_as_lazy_initialized_proxy.phpt} | 2 +- ..._as_lazy_may_call_nested_destructors.phpt} | 2 +- ...=> reset_as_lazy_may_skip_destructor.phpt} | 8 ++- ...y_001.phpt => reset_as_lazy_readonly.phpt} | 2 +- ....phpt => reset_as_lazy_real_instance.phpt} | 2 +- ...> reset_as_lazy_resets_dynamic_props.phpt} | 8 ++- .../{ => rfc}/rfc_example_001.phpt | 0 .../{ => rfc}/rfc_example_002.phpt | 0 .../{ => rfc}/rfc_example_003.phpt | 0 .../{ => rfc}/rfc_example_004.phpt | 0 .../{ => rfc}/rfc_example_005.phpt | 0 .../{ => rfc}/rfc_example_006.phpt | 0 .../{ => rfc}/rfc_example_007.phpt | 0 .../{ => rfc}/rfc_example_008.phpt | 0 .../{ => rfc}/rfc_example_009.phpt | 0 .../{ => rfc}/rfc_example_010.phpt | 0 .../{ => rfc}/rfc_example_011.phpt | 0 .../{ => rfc}/rfc_example_012.phpt | 0 ...serialize___serialize_may_initialize.phpt} | 10 ++-- ...alize___serialize_may_not_initialize.phpt} | 10 ++-- ...hpt => serialize___sleep_initializes.phpt} | 8 +-- ....phpt => serialize___sleep_skip_flag.phpt} | 8 +-- ...ize___sleep_skip_flag_may_initialize.phpt} | 10 ++-- ...serialize_010.phpt => serialize_hook.phpt} | 8 +-- ...ze_001.phpt => serialize_initializes.phpt} | 8 +-- ...alize_002.phpt => serialize_props_ht.phpt} | 8 +-- ...lize_003.phpt => serialize_skip_flag.phpt} | 8 +-- ...phpt => serialize_skip_flag_props_ht.phpt} | 8 +-- ...setRawValueWithoutLazyInitialization.phpt} | 0 ...eWithoutLazyInitialization_exception.phpt} | 0 ...ithoutLazyInitialization_initialized.phpt} | 0 ...utLazyInitialization_no_dynamic_prop.phpt} | 0 ...ueWithoutLazyInitialization_readonly.phpt} | 0 ...tLazyInitialization_readonly_variant.phpt} | 0 ...lueWithoutLazyInitialization_realize.phpt} | 0 ...yInitialization_side_effect_destruct.phpt} | 0 ...yInitialization_side_effect_toString.phpt} | 0 ...ithoutLazyInitialization_skips___set.phpt} | 0 ...WithoutLazyInitialization_skips_hook.phpt} | 0 ...y_001.phpt => skipLazyInitialization.phpt} | 2 +- ...pt => skipLazyInitialization_default.phpt} | 0 ...azyInitialization_initialized_object.phpt} | 0 ...ipLazyInitialization_no_dynamic_prop.phpt} | 0 ...t => skipLazyInitialization_readonly.phpt} | 0 ...pt => skipLazyInitialization_realize.phpt} | 0 ...> skipLazyInitialization_skips___set.phpt} | 0 ...> skipLazyInitialization_skips_hooks.phpt} | 0 ...zyInitialization_skips_non_lazy_prop.phpt} | 0 ....phpt => support_no_internal_classes.phpt} | 8 +-- ...t => support_no_internal_sub_classes.phpt} | 8 +-- .../{004.phpt => support_readonly_class.phpt} | 8 +-- .../{003.phpt => support_readonly_prop.phpt} | 8 +-- Zend/tests/lazy_objects/support_stdClass.phpt | 30 ++++++++++ .../support_stdClass_sub_classes.phpt | 33 +++++++++++ Zend/tests/lazy_objects/unclean_shutdown.phpt | 5 +- ....phpt => unset_defined_no_initialize.phpt} | 8 +-- .../{unset_010.phpt => unset_hook.phpt} | 8 +-- ... unset_magic_circular_may_initialize.phpt} | 8 +-- ...4.phpt => unset_magic_may_initialize.phpt} | 10 ++-- ...pt => unset_magic_may_not_initialize.phpt} | 10 ++-- ....phpt => unset_skipped_no_initialize.phpt} | 10 ++-- ... unset_undefined_dynamic_initializes.phpt} | 8 +-- ...ined_dynamic_initializes_no_props_ht.phpt} | 8 +-- ....phpt => unset_undefined_initializes.phpt} | 8 +-- Zend/tests/lazy_objects/use_case_001.phpt | 4 +- Zend/tests/lazy_objects/use_case_001b.phpt | 4 +- Zend/tests/lazy_objects/use_case_002.phpt | 8 +-- ...02.phpt => write_dynamic_initializes.phpt} | 10 ++-- ....phpt => write_initializer_exception.phpt} | 8 +-- ...{write_001.phpt => write_initializes.phpt} | 8 +-- ... write_magic_circular_may_initialize.phpt} | 8 +-- ...3.phpt => write_magic_may_initialize.phpt} | 10 ++-- ....phpt => write_skipped_no_initialize.phpt} | 10 ++-- 159 files changed, 623 insertions(+), 729 deletions(-) delete mode 100644 Zend/tests/lazy_objects/016.phpt delete mode 100644 Zend/tests/lazy_objects/018.phpt rename Zend/tests/lazy_objects/{clone_002.phpt => clone_calls___clone_once.phpt} (100%) rename Zend/tests/lazy_objects/{clone_007.phpt => clone_creates_object_with_independent_state_001.phpt} (92%) rename Zend/tests/lazy_objects/{clone_008.phpt => clone_creates_object_with_independent_state_002.phpt} (94%) rename Zend/tests/lazy_objects/{clone_009.phpt => clone_creates_object_with_independent_state_003.phpt} (92%) rename Zend/tests/lazy_objects/{clone_004.phpt => clone_initialized.phpt} (100%) rename Zend/tests/lazy_objects/{clone_003.phpt => clone_initializer_exception.phpt} (100%) rename Zend/tests/lazy_objects/{clone_001.phpt => clone_initializes.phpt} (100%) rename Zend/tests/lazy_objects/{feedback_007.phpt => clone_preverves_object_class.phpt} (76%) rename Zend/tests/lazy_objects/{017.phpt => dtor_called_if_init.phpt} (66%) create mode 100644 Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt delete mode 100644 Zend/tests/lazy_objects/feedback_006.phpt rename Zend/tests/lazy_objects/{fetch_008.phpt => fetch_coalesce_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{fetch_009.phpt => fetch_coalesce_non_existing_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{fetch_001.phpt => fetch_declared_prop_initializes.phpt} (77%) rename Zend/tests/lazy_objects/{fetch_002.phpt => fetch_dynamic_prop_initializes.phpt} (77%) rename Zend/tests/lazy_objects/{fetch_016.phpt => fetch_hook_may_not_initialize.phpt} (75%) rename Zend/tests/lazy_objects/{fetch_017.phpt => fetch_hook_virtual_may_initialize.phpt} (79%) rename Zend/tests/lazy_objects/{fetch_018.phpt => fetch_hook_virtual_may_not_initialize.phpt} (69%) rename Zend/tests/lazy_objects/{fetch_006.phpt => fetch_magic_prop_may_initialize.phpt} (72%) rename Zend/tests/lazy_objects/{fetch_005.phpt => fetch_magic_prop_may_not_initialize.phpt} (70%) rename Zend/tests/lazy_objects/{fetch_007.phpt => fetch_magic_prop_recursive_may_initialize.phpt} (74%) rename Zend/tests/lazy_objects/{fetch_011.phpt => fetch_op_dynamic_error.phpt} (76%) rename Zend/tests/lazy_objects/{fetch_004.phpt => fetch_op_dynamic_prop_initializes.phpt} (77%) rename Zend/tests/lazy_objects/{fetch_012.phpt => fetch_op_error.phpt} (75%) rename Zend/tests/lazy_objects/{fetch_003.phpt => fetch_op_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{fetch_014.phpt => fetch_op_skipped_prop_does_not_initialize.phpt} (83%) rename Zend/tests/lazy_objects/{fetch_010.phpt => fetch_ref_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{fetch_015.phpt => fetch_ref_skipped_prop_does_not_initialize.phpt} (83%) rename Zend/tests/lazy_objects/{fetch_013.phpt => fetch_skipped_prop_does_not_initialize.phpt} (83%) rename Zend/tests/lazy_objects/{013.phpt => final_classes_can_be_initialized_lazily.phpt} (75%) rename Zend/tests/lazy_objects/{feedback_002.phpt => gc_006.phpt} (95%) rename Zend/tests/lazy_objects/{object_with_ast_const_001.phpt => init_ast_const.phpt} (100%) rename Zend/tests/lazy_objects/{object_with_ast_const_002.phpt => init_ast_const_failure.phpt} (100%) rename Zend/tests/lazy_objects/{init_exception_001.phpt => init_exception_leaves_object_lazy.phpt} (62%) rename Zend/tests/lazy_objects/{init_exception_002.phpt => init_exception_reverts_initializer_changes.phpt} (66%) rename Zend/tests/lazy_objects/{init_exception_005.phpt => init_exception_reverts_initializer_changes_dyn_props.phpt} (68%) rename Zend/tests/lazy_objects/{init_exception_006.phpt => init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt} (70%) rename Zend/tests/lazy_objects/{feedback_005.phpt => init_exception_reverts_initializer_changes_nested.phpt} (91%) rename Zend/tests/lazy_objects/{init_exception_012.phpt => init_exception_reverts_initializer_changes_overridden_prop.phpt} (68%) rename Zend/tests/lazy_objects/{init_exception_003.phpt => init_exception_reverts_initializer_changes_props_ht.phpt} (69%) rename Zend/tests/lazy_objects/{init_exception_009.phpt => init_exception_reverts_initializer_changes_props_ht_ref.phpt} (73%) rename Zend/tests/lazy_objects/{024.phpt => init_fatal.phpt} (85%) rename Zend/tests/lazy_objects/{init_exception_010.phpt => init_handles_ref_source_types.phpt} (76%) rename Zend/tests/lazy_objects/{init_exception_011.phpt => init_handles_ref_source_types_exception.phpt} (81%) rename Zend/tests/lazy_objects/{ghost_002.phpt => init_may_leave_props_uninit.phpt} (74%) rename Zend/tests/lazy_objects/{feedback_004.phpt => init_preserves_identity.phpt} (90%) rename Zend/tests/lazy_objects/{feedback_003.phpt => init_preserves_proxy_class.phpt} (84%) rename Zend/tests/lazy_objects/{ghost_001.phpt => init_sets_prop_default_values.phpt} (72%) rename Zend/tests/lazy_objects/{012.phpt => init_trigger_array_cast.phpt} (71%) rename Zend/tests/lazy_objects/{027.phpt => init_trigger_debug_zval_dump.phpt} (100%) rename Zend/tests/lazy_objects/{006.phpt => init_trigger_foreach.phpt} (69%) rename Zend/tests/lazy_objects/{019.phpt => init_trigger_get_mangled_object_vars.phpt} (73%) rename Zend/tests/lazy_objects/{011.phpt => init_trigger_get_object_vars.phpt} (73%) rename Zend/tests/lazy_objects/{010.phpt => init_trigger_json_encode.phpt} (67%) rename Zend/tests/lazy_objects/{reflection_to_string_does_not_init.phpt => init_trigger_reflection_object_toString.phpt} (70%) rename Zend/tests/lazy_objects/{009.phpt => init_trigger_serialize.phpt} (68%) rename Zend/tests/lazy_objects/{007.phpt => init_trigger_var_dump.phpt} (95%) rename Zend/tests/lazy_objects/{025.phpt => init_trigger_var_dump_debug_info_001.phpt} (68%) rename Zend/tests/lazy_objects/{026.phpt => init_trigger_var_dump_debug_info_002.phpt} (70%) rename Zend/tests/lazy_objects/{008.phpt => init_trigger_var_export.phpt} (68%) rename Zend/tests/lazy_objects/{initialize_001.phpt => initializeLazyObject.phpt} (72%) rename Zend/tests/lazy_objects/{initialize_005.phpt => initializeLazyObject_error.phpt} (72%) rename Zend/tests/lazy_objects/{initialize_002.phpt => initializeLazyObject_noop_on_initialized_object.phpt} (67%) rename Zend/tests/lazy_objects/{005.phpt => initializer_must_return_the_right_type.phpt} (90%) create mode 100644 Zend/tests/lazy_objects/isUninitializedLazyObject.phpt delete mode 100644 Zend/tests/lazy_objects/is_initialized_001.phpt delete mode 100644 Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt rename Zend/tests/lazy_objects/{isset_002.phpt => isset_hooked_may_initialize.phpt} (75%) rename Zend/tests/lazy_objects/{isset_003.phpt => isset_hooked_may_not_initialize.phpt} (71%) rename Zend/tests/lazy_objects/{isset_001.phpt => isset_initializes.phpt} (78%) rename Zend/tests/lazy_objects/{mark_as_initialized_001.phpt => markLazyObjectAsInitialized.phpt} (76%) delete mode 100644 Zend/tests/lazy_objects/new_instance_lazy_001.phpt delete mode 100644 Zend/tests/lazy_objects/new_instance_lazy_002.phpt delete mode 100644 Zend/tests/lazy_objects/new_instance_lazy_003.phpt delete mode 100644 Zend/tests/lazy_objects/new_instance_lazy_004.phpt delete mode 100644 Zend/tests/lazy_objects/new_instance_lazy_005.phpt rename Zend/tests/lazy_objects/{realize_001.phpt => realize.phpt} (86%) rename Zend/tests/lazy_objects/{realize_003.phpt => realize_no_props.phpt} (100%) rename Zend/tests/lazy_objects/{props_of_proxy_must_not_be_lazy_004.phpt => realize_proxy_overridden.phpt} (85%) rename Zend/tests/lazy_objects/{realize_002.phpt => realize_skipped.phpt} (86%) rename Zend/tests/lazy_objects/{make_lazy_already_exception.phpt => reset_as_lazy_already_exception.phpt} (56%) rename Zend/tests/lazy_objects/{make_lazy_destructor_001.phpt => reset_as_lazy_calls_destructor.phpt} (78%) rename Zend/tests/lazy_objects/{021.phpt => reset_as_lazy_deletes_reference_source_type.phpt} (85%) rename Zend/tests/lazy_objects/{make_lazy_destructor_003.phpt => reset_as_lazy_destructor_exception.phpt} (81%) rename Zend/tests/lazy_objects/{feedback_008.phpt => reset_as_lazy_initialized_proxy.phpt} (93%) rename Zend/tests/lazy_objects/{feedback_001.phpt => reset_as_lazy_may_call_nested_destructors.phpt} (90%) rename Zend/tests/lazy_objects/{make_lazy_destructor_002.phpt => reset_as_lazy_may_skip_destructor.phpt} (76%) rename Zend/tests/lazy_objects/{reset_readonly_001.phpt => reset_as_lazy_readonly.phpt} (95%) rename Zend/tests/lazy_objects/{feedback_009.phpt => reset_as_lazy_real_instance.phpt} (88%) rename Zend/tests/lazy_objects/{020.phpt => reset_as_lazy_resets_dynamic_props.phpt} (84%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_001.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_002.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_003.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_004.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_005.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_006.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_007.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_008.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_009.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_010.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_011.phpt (100%) rename Zend/tests/lazy_objects/{ => rfc}/rfc_example_012.phpt (100%) rename Zend/tests/lazy_objects/{serialize_006.phpt => serialize___serialize_may_initialize.phpt} (69%) rename Zend/tests/lazy_objects/{serialize_005.phpt => serialize___serialize_may_not_initialize.phpt} (62%) rename Zend/tests/lazy_objects/{serialize_007.phpt => serialize___sleep_initializes.phpt} (74%) rename Zend/tests/lazy_objects/{serialize_008.phpt => serialize___sleep_skip_flag.phpt} (74%) rename Zend/tests/lazy_objects/{serialize_009.phpt => serialize___sleep_skip_flag_may_initialize.phpt} (72%) rename Zend/tests/lazy_objects/{serialize_010.phpt => serialize_hook.phpt} (73%) rename Zend/tests/lazy_objects/{serialize_001.phpt => serialize_initializes.phpt} (70%) rename Zend/tests/lazy_objects/{serialize_002.phpt => serialize_props_ht.phpt} (72%) rename Zend/tests/lazy_objects/{serialize_003.phpt => serialize_skip_flag.phpt} (75%) rename Zend/tests/lazy_objects/{serialize_004.phpt => serialize_skip_flag_props_ht.phpt} (77%) rename Zend/tests/lazy_objects/{set_raw_value_001.phpt => setRawValueWithoutLazyInitialization.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_009.phpt => setRawValueWithoutLazyInitialization_exception.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_007.phpt => setRawValueWithoutLazyInitialization_initialized.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_008.phpt => setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_009.phpt => setRawValueWithoutLazyInitialization_readonly.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_008.phpt => setRawValueWithoutLazyInitialization_readonly_variant.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_003.phpt => setRawValueWithoutLazyInitialization_realize.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_006.phpt => setRawValueWithoutLazyInitialization_side_effect_destruct.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_005.phpt => setRawValueWithoutLazyInitialization_side_effect_toString.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_004.phpt => setRawValueWithoutLazyInitialization_skips___set.phpt} (100%) rename Zend/tests/lazy_objects/{set_raw_value_002.phpt => setRawValueWithoutLazyInitialization_skips_hook.phpt} (100%) rename Zend/tests/lazy_objects/{reflection_lazy_object_skip_property_001.phpt => skipLazyInitialization.phpt} (98%) rename Zend/tests/lazy_objects/{skip_initialization_001.phpt => skipLazyInitialization_default.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_006.phpt => skipLazyInitialization_initialized_object.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_010.phpt => skipLazyInitialization_no_dynamic_prop.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_007.phpt => skipLazyInitialization_readonly.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_003.phpt => skipLazyInitialization_realize.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_004.phpt => skipLazyInitialization_skips___set.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_002.phpt => skipLazyInitialization_skips_hooks.phpt} (100%) rename Zend/tests/lazy_objects/{skip_initialization_005.phpt => skipLazyInitialization_skips_non_lazy_prop.phpt} (100%) rename Zend/tests/lazy_objects/{014.phpt => support_no_internal_classes.phpt} (66%) rename Zend/tests/lazy_objects/{015.phpt => support_no_internal_sub_classes.phpt} (70%) rename Zend/tests/lazy_objects/{004.phpt => support_readonly_class.phpt} (74%) rename Zend/tests/lazy_objects/{003.phpt => support_readonly_prop.phpt} (74%) create mode 100644 Zend/tests/lazy_objects/support_stdClass.phpt create mode 100644 Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt rename Zend/tests/lazy_objects/{unset_008.phpt => unset_defined_no_initialize.phpt} (75%) rename Zend/tests/lazy_objects/{unset_010.phpt => unset_hook.phpt} (79%) rename Zend/tests/lazy_objects/{unset_005.phpt => unset_magic_circular_may_initialize.phpt} (77%) rename Zend/tests/lazy_objects/{unset_004.phpt => unset_magic_may_initialize.phpt} (73%) rename Zend/tests/lazy_objects/{unset_003.phpt => unset_magic_may_not_initialize.phpt} (69%) rename Zend/tests/lazy_objects/{unset_009.phpt => unset_skipped_no_initialize.phpt} (78%) rename Zend/tests/lazy_objects/{unset_006.phpt => unset_undefined_dynamic_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{unset_007.phpt => unset_undefined_dynamic_initializes_no_props_ht.phpt} (77%) rename Zend/tests/lazy_objects/{unset_001.phpt => unset_undefined_initializes.phpt} (77%) rename Zend/tests/lazy_objects/{write_002.phpt => write_dynamic_initializes.phpt} (74%) rename Zend/tests/lazy_objects/{write_005.phpt => write_initializer_exception.phpt} (69%) rename Zend/tests/lazy_objects/{write_001.phpt => write_initializes.phpt} (76%) rename Zend/tests/lazy_objects/{write_004.phpt => write_magic_circular_may_initialize.phpt} (76%) rename Zend/tests/lazy_objects/{write_003.phpt => write_magic_may_initialize.phpt} (76%) rename Zend/tests/lazy_objects/{write_006.phpt => write_skipped_no_initialize.phpt} (77%) diff --git a/Zend/tests/lazy_objects/016.phpt b/Zend/tests/lazy_objects/016.phpt deleted file mode 100644 index 5efd48bdebff1..0000000000000 --- a/Zend/tests/lazy_objects/016.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -Lazy objects: destructor of lazy objets is not called if not initialized ---FILE-- -newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { - var_dump("initializer"); -}); -print "After makeLazy\n"; - -// Does not call destructor -$obj = null; - -print "# Virtual:\n"; - -print "In makeLazy\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { - var_dump("initializer"); -}); -print "After makeLazy\n"; - -// Does not call destructor -$obj = null; - ---EXPECT-- -# Ghost: -In makeLazy -string(13) "C::__destruct" -After makeLazy -# Virtual: -In makeLazy -string(13) "C::__destruct" -After makeLazy diff --git a/Zend/tests/lazy_objects/018.phpt b/Zend/tests/lazy_objects/018.phpt deleted file mode 100644 index 2ee1b6e2db630..0000000000000 --- a/Zend/tests/lazy_objects/018.phpt +++ /dev/null @@ -1,57 +0,0 @@ ---TEST-- -Lazy objects: exception during initializer leaves object uninitialized ---FILE-- -a); - } catch (Exception $e) { - printf("%s\n", $e->getMessage()); - } - var_dump((new ReflectionClass($obj))->isUninitializedLazyObject($obj)); - try { - var_dump($obj->a); - } catch (Exception $e) { - printf("%s\n", $e->getMessage()); - } - var_dump((new ReflectionClass($obj))->isUninitializedLazyObject($obj)); -} - -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { - var_dump("initializer"); - throw new \Exception('initializer exception'); -}); - -test('Ghost', $obj); - -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { - var_dump("initializer"); - throw new \Exception('initializer exception'); -}); - -test('Virtual', $obj); - ---EXPECT-- -# Ghost: -string(11) "initializer" -initializer exception -bool(true) -string(11) "initializer" -initializer exception -bool(true) -# Virtual: -string(11) "initializer" -initializer exception -bool(true) -string(11) "initializer" -initializer exception -bool(true) diff --git a/Zend/tests/lazy_objects/clone_002.phpt b/Zend/tests/lazy_objects/clone_calls___clone_once.phpt similarity index 100% rename from Zend/tests/lazy_objects/clone_002.phpt rename to Zend/tests/lazy_objects/clone_calls___clone_once.phpt diff --git a/Zend/tests/lazy_objects/clone_007.phpt b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt similarity index 92% rename from Zend/tests/lazy_objects/clone_007.phpt rename to Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt index 9a350e6f01cd8..10aab3da023b3 100644 --- a/Zend/tests/lazy_objects/clone_007.phpt +++ b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: clone semantics +Lazy objects: clone is independant of the original object --FILE-- ==DONE== --EXPECT-- +string(1) "B" +string(1) "B" ==DONE== diff --git a/Zend/tests/lazy_objects/017.phpt b/Zend/tests/lazy_objects/dtor_called_if_init.phpt similarity index 66% rename from Zend/tests/lazy_objects/017.phpt rename to Zend/tests/lazy_objects/dtor_called_if_init.phpt index e5ebc8aa50ad5..4002a66a13c36 100644 --- a/Zend/tests/lazy_objects/017.phpt +++ b/Zend/tests/lazy_objects/dtor_called_if_init.phpt @@ -12,11 +12,12 @@ class C { } function ghost() { + $reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; print "In makeLazy\n"; - $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); - (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () { + $obj = $reflector->newLazyGhost(function () { var_dump("initializer"); }); print "After makeLazy\n"; @@ -25,11 +26,12 @@ function ghost() { } function virtual() { + $reflector = new ReflectionClass(C::class); + print "# Virtual:\n"; print "In makeLazy\n"; - $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); - (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () { + $obj = $reflector->newLazyProxy(function () { var_dump("initializer"); return new C(); }); @@ -44,11 +46,6 @@ virtual(); --EXPECTF-- # Ghost: In makeLazy -string(13) "C::__destruct" -object(C)#%d (1) { - ["a"]=> - int(1) -} After makeLazy string(11) "initializer" int(1) @@ -59,11 +56,6 @@ object(C)#%d (1) { } # Virtual: In makeLazy -string(13) "C::__destruct" -object(C)#%d (1) { - ["a"]=> - int(1) -} After makeLazy string(11) "initializer" int(1) diff --git a/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt new file mode 100644 index 0000000000000..17855588ec1fc --- /dev/null +++ b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: destructor of lazy objets is not called if not initialized +--FILE-- +newLazyGhost(function () { + var_dump("initializer"); +}); +print "After newLazyGhost\n"; + +// Does not call destructor +$obj = null; + +print "# Virtual:\n"; + +print "In newLazyProxy\n"; +$obj = $reflector->newLazyProxy(function () { + var_dump("initializer"); +}); +print "After newLazyGhost\n"; + +// Does not call destructor +$obj = null; + +--EXPECT-- +# Ghost: +In newLazyGhost +After newLazyGhost +# Virtual: +In newLazyProxy +After newLazyGhost diff --git a/Zend/tests/lazy_objects/feedback_006.phpt b/Zend/tests/lazy_objects/feedback_006.phpt deleted file mode 100644 index 64d1ae00938e3..0000000000000 --- a/Zend/tests/lazy_objects/feedback_006.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -Lazy objects: feedback 006 ---FILE-- -foo; - } -} - -$r = new ReflectionClass(B::class); -$obj = $r->newLazyProxy(function ($obj) { - return new A(); -}); - -try { - $obj->getFoo(); -} catch (\Throwable $e) { - printf("%s: %s\n", $e::class, $e->getMessage()); -} - -?> ---EXPECT-- -TypeError: The real instance class A is not compatible with the proxy class B. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. diff --git a/Zend/tests/lazy_objects/fetch_008.phpt b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/fetch_008.phpt rename to Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt index 1a87364e8ded5..832fc7f4f64bd 100644 --- a/Zend/tests/lazy_objects/fetch_008.phpt +++ b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt @@ -18,16 +18,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_009.phpt b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/fetch_009.phpt rename to Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt index d4316320c6e9d..5ed1e27133618 100644 --- a/Zend/tests/lazy_objects/fetch_009.phpt +++ b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt @@ -18,16 +18,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_001.phpt b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt similarity index 77% rename from Zend/tests/lazy_objects/fetch_001.phpt rename to Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt index d89cba11d4481..7b055c060ae3d 100644 --- a/Zend/tests/lazy_objects/fetch_001.phpt +++ b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt @@ -22,16 +22,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/fetch_002.phpt b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt similarity index 77% rename from Zend/tests/lazy_objects/fetch_002.phpt rename to Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt index fda287265948e..dc4d92d2965dd 100644 --- a/Zend/tests/lazy_objects/fetch_002.phpt +++ b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt @@ -19,16 +19,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_016.phpt b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt similarity index 75% rename from Zend/tests/lazy_objects/fetch_016.phpt rename to Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt index 5e27cb77a5abc..b87134fff0934 100644 --- a/Zend/tests/lazy_objects/fetch_016.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: hooked property fetch may initialize object +Lazy objects: hooked property fetch does not initialize object if hook does not observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/fetch_017.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt similarity index 79% rename from Zend/tests/lazy_objects/fetch_017.phpt rename to Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt index 88d40a59101ac..a81f52795966e 100644 --- a/Zend/tests/lazy_objects/fetch_017.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: virtual hooked property fetch may initialize object +Lazy objects: virtual hooked property fetch may initialize object if hook observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/fetch_018.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt similarity index 69% rename from Zend/tests/lazy_objects/fetch_018.phpt rename to Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt index c66d657dfcd0f..cd9a1d837c95e 100644 --- a/Zend/tests/lazy_objects/fetch_018.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: virtual hooked property fetch may not initialize object +Lazy objects: virtual hooked property fetch does not initialize object if hook does not observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/fetch_006.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt similarity index 72% rename from Zend/tests/lazy_objects/fetch_006.phpt rename to Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt index ecf5ab123b4bf..cff2e62d1bb47 100644 --- a/Zend/tests/lazy_objects/fetch_006.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: magic property fetch may initialize object +Lazy objects: magic property fetch initializes object if magic method observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_005.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt similarity index 70% rename from Zend/tests/lazy_objects/fetch_005.phpt rename to Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt index 11b8d463ced95..bc362abf02831 100644 --- a/Zend/tests/lazy_objects/fetch_005.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: magic property fetch may not initialize object +Lazy objects: magic property fetch does not not initialize object if magic method does not observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_007.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt similarity index 74% rename from Zend/tests/lazy_objects/fetch_007.phpt rename to Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt index abdb8212a11b2..c1c9dcb1cfe42 100644 --- a/Zend/tests/lazy_objects/fetch_007.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: recursive magic property fetch may initialize object +Lazy objects: recursive magic property fetch initializes object if magic method observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_011.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt similarity index 76% rename from Zend/tests/lazy_objects/fetch_011.phpt rename to Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt index 077a11a2f60ff..1efd76071224a 100644 --- a/Zend/tests/lazy_objects/fetch_011.phpt +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt @@ -24,16 +24,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { throw new Error("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { throw new Error("initializer"); }); diff --git a/Zend/tests/lazy_objects/fetch_004.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt similarity index 77% rename from Zend/tests/lazy_objects/fetch_004.phpt rename to Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt index 892850fed5f0f..e52e3c8cdf184 100644 --- a/Zend/tests/lazy_objects/fetch_004.phpt +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt @@ -19,16 +19,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_012.phpt b/Zend/tests/lazy_objects/fetch_op_error.phpt similarity index 75% rename from Zend/tests/lazy_objects/fetch_012.phpt rename to Zend/tests/lazy_objects/fetch_op_error.phpt index 8c3b591350f80..7e04d3593d527 100644 --- a/Zend/tests/lazy_objects/fetch_012.phpt +++ b/Zend/tests/lazy_objects/fetch_op_error.phpt @@ -25,15 +25,15 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { throw new Error("initializer"); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { throw new Error("initializer"); }); diff --git a/Zend/tests/lazy_objects/fetch_003.phpt b/Zend/tests/lazy_objects/fetch_op_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/fetch_003.phpt rename to Zend/tests/lazy_objects/fetch_op_initializes.phpt index d24af36221a0f..1731f7004fc75 100644 --- a/Zend/tests/lazy_objects/fetch_003.phpt +++ b/Zend/tests/lazy_objects/fetch_op_initializes.phpt @@ -19,16 +19,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_014.phpt b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt similarity index 83% rename from Zend/tests/lazy_objects/fetch_014.phpt rename to Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt index 0320a073039b6..f152366b12ca1 100644 --- a/Zend/tests/lazy_objects/fetch_014.phpt +++ b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt @@ -32,16 +32,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new c(); }); diff --git a/Zend/tests/lazy_objects/fetch_010.phpt b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/fetch_010.phpt rename to Zend/tests/lazy_objects/fetch_ref_initializes.phpt index 6fb013c3ff1b2..6c7c28cee5084 100644 --- a/Zend/tests/lazy_objects/fetch_010.phpt +++ b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt @@ -19,16 +19,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_015.phpt b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt similarity index 83% rename from Zend/tests/lazy_objects/fetch_015.phpt rename to Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt index c4c77a679329b..26a820cbb092a 100644 --- a/Zend/tests/lazy_objects/fetch_015.phpt +++ b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt @@ -27,16 +27,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/fetch_013.phpt b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt similarity index 83% rename from Zend/tests/lazy_objects/fetch_013.phpt rename to Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt index 96faaf3f19d10..f210e8b05aaa7 100644 --- a/Zend/tests/lazy_objects/fetch_013.phpt +++ b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt @@ -34,16 +34,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/013.phpt b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt similarity index 75% rename from Zend/tests/lazy_objects/013.phpt rename to Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt index 8e92692169bc1..42a5177f91125 100644 --- a/Zend/tests/lazy_objects/013.phpt +++ b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt @@ -11,10 +11,11 @@ final class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -25,8 +26,7 @@ var_dump($obj); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/feedback_002.phpt b/Zend/tests/lazy_objects/gc_006.phpt similarity index 95% rename from Zend/tests/lazy_objects/feedback_002.phpt rename to Zend/tests/lazy_objects/gc_006.phpt index 76138e8656a75..e1002ffea7108 100644 --- a/Zend/tests/lazy_objects/feedback_002.phpt +++ b/Zend/tests/lazy_objects/gc_006.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: feedback 002 +Lazy objects: GC 006 --FILE-- initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -30,8 +33,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/init_exception_002.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt similarity index 66% rename from Zend/tests/lazy_objects/init_exception_002.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt index e14a873b3f9cb..2bc098a8d19ee 100644 --- a/Zend/tests/lazy_objects/init_exception_002.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt @@ -10,22 +10,25 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - (new ReflectionProperty($obj, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); + (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); try { - (new ReflectionClass($obj))->initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } var_dump($obj); - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -35,8 +38,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/init_exception_005.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt similarity index 68% rename from Zend/tests/lazy_objects/init_exception_005.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt index db5b6dabefb6d..ba91c973a11d0 100644 --- a/Zend/tests/lazy_objects/init_exception_005.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt @@ -11,22 +11,25 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - (new ReflectionProperty($obj, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); + (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); try { - (new ReflectionClass($obj))->initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } var_dump($obj); - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -37,8 +40,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/init_exception_006.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt similarity index 70% rename from Zend/tests/lazy_objects/init_exception_006.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt index 28ff9331ceb20..7de4025dcee94 100644 --- a/Zend/tests/lazy_objects/init_exception_006.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt @@ -11,25 +11,28 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); // Builds properties hashtable var_dump(get_mangled_object_vars($obj)); - (new ReflectionProperty($obj, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); + (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); try { - (new ReflectionClass($obj))->initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } var_dump($obj); - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -40,8 +43,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/feedback_005.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt similarity index 91% rename from Zend/tests/lazy_objects/feedback_005.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt index 83454e70a7c96..535f93e65f63f 100644 --- a/Zend/tests/lazy_objects/feedback_005.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: feedback 005 +Lazy objects: Initializer effects are reverted after exception (nested) --FILE-- getProperty('b')->skipLazyInitialization($obj); $i = 5; $obj->b = &$i; @@ -25,11 +26,12 @@ function test(string $name, object $obj) { printf("%s\n", $e->getMessage()); } - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -38,8 +40,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/init_exception_003.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt similarity index 69% rename from Zend/tests/lazy_objects/init_exception_003.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt index 26eabc8bf4204..081a4d2737f48 100644 --- a/Zend/tests/lazy_objects/init_exception_003.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt @@ -10,25 +10,28 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - (new ReflectionProperty($obj, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); + (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); // Builds properties hashtable var_dump(get_mangled_object_vars($obj)); try { - (new ReflectionClass($obj))->initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } var_dump($obj); - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; @@ -38,8 +41,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 3; $obj->b = 4; diff --git a/Zend/tests/lazy_objects/init_exception_009.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt similarity index 73% rename from Zend/tests/lazy_objects/init_exception_009.phpt rename to Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt index ad6c4232214a6..f3d4285f55257 100644 --- a/Zend/tests/lazy_objects/init_exception_009.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt @@ -10,27 +10,30 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - (new ReflectionProperty($obj, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); + (new ReflectionProperty(C::class, 'c'))->setRawValueWithoutLazyInitialization($obj, 0); // Builds properties hashtable var_dump(get_mangled_object_vars($obj)); try { - (new ReflectionClass($obj))->initializeLazyObject($obj); + $reflector->initializeLazyObject($obj); } catch (Exception $e) { printf("%s\n", $e->getMessage()); } var_dump($obj); - printf("Is lazy: %d\n", (new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); var_dump($table); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { global $table; var_dump("initializer"); $obj->a = 3; @@ -42,8 +45,7 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { global $table; var_dump("initializer"); $obj->a = 3; diff --git a/Zend/tests/lazy_objects/024.phpt b/Zend/tests/lazy_objects/init_fatal.phpt similarity index 85% rename from Zend/tests/lazy_objects/024.phpt rename to Zend/tests/lazy_objects/init_fatal.phpt index 548088394a650..7f5e03c94b0fa 100644 --- a/Zend/tests/lazy_objects/024.phpt +++ b/Zend/tests/lazy_objects/init_fatal.phpt @@ -13,8 +13,7 @@ class C { } $reflector = new ReflectionClass(C::class); -$obj = $reflector->newInstanceWithoutConstructor(); -$reflector->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); diff --git a/Zend/tests/lazy_objects/init_exception_010.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt similarity index 76% rename from Zend/tests/lazy_objects/init_exception_010.phpt rename to Zend/tests/lazy_objects/init_handles_ref_source_types.phpt index 788d92ec6e6b5..1042131ec3165 100644 --- a/Zend/tests/lazy_objects/init_exception_010.phpt +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt @@ -15,12 +15,13 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - $r = new ReflectionClass($obj); - $r->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); $refA = &$obj->a; - $r->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); $refB = &$obj->b; var_dump($obj); @@ -41,19 +42,18 @@ function test(string $name, object $obj) { $refA = 1; $refB = 1; - } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -$r = (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(null); }); diff --git a/Zend/tests/lazy_objects/init_exception_011.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt similarity index 81% rename from Zend/tests/lazy_objects/init_exception_011.phpt rename to Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt index de6c5ff5fd61e..d2caad0ccd84e 100644 --- a/Zend/tests/lazy_objects/init_exception_011.phpt +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt @@ -14,12 +14,13 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - $r = new ReflectionClass($obj); - $r->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); $refA = &$obj->a; - $r->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); $refB = &$obj->b; var_dump($obj); @@ -56,16 +57,16 @@ function test(string $name, object $obj) { } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -$r = (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(null); }); diff --git a/Zend/tests/lazy_objects/ghost_002.phpt b/Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt similarity index 74% rename from Zend/tests/lazy_objects/ghost_002.phpt rename to Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt index 8c818c035a841..954433918b92b 100644 --- a/Zend/tests/lazy_objects/ghost_002.phpt +++ b/Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: properties may be left uninitialized by the initializer +Lazy objects: properties with no default values are left uninitialized --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); diff --git a/Zend/tests/lazy_objects/feedback_004.phpt b/Zend/tests/lazy_objects/init_preserves_identity.phpt similarity index 90% rename from Zend/tests/lazy_objects/feedback_004.phpt rename to Zend/tests/lazy_objects/init_preserves_identity.phpt index fb6d2e31fe0e0..7ef197d43112a 100644 --- a/Zend/tests/lazy_objects/feedback_004.phpt +++ b/Zend/tests/lazy_objects/init_preserves_identity.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: feedback 004 +Lazy objects: initialization of proxy does not change object id --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); var_dump($obj); $obj->__construct(); diff --git a/Zend/tests/lazy_objects/012.phpt b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt similarity index 71% rename from Zend/tests/lazy_objects/012.phpt rename to Zend/tests/lazy_objects/init_trigger_array_cast.phpt index ab8e5c5c3fcbe..e58e1cbbd775a 100644 --- a/Zend/tests/lazy_objects/012.phpt +++ b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -26,8 +27,7 @@ var_dump((array)$obj); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/027.phpt b/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt similarity index 100% rename from Zend/tests/lazy_objects/027.phpt rename to Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt diff --git a/Zend/tests/lazy_objects/006.phpt b/Zend/tests/lazy_objects/init_trigger_foreach.phpt similarity index 69% rename from Zend/tests/lazy_objects/006.phpt rename to Zend/tests/lazy_objects/init_trigger_foreach.phpt index 43211fa38e117..dd5c8b6291433 100644 --- a/Zend/tests/lazy_objects/006.phpt +++ b/Zend/tests/lazy_objects/init_trigger_foreach.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -25,8 +26,7 @@ foreach ($obj as $prop => $value) { print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/019.phpt b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt similarity index 73% rename from Zend/tests/lazy_objects/019.phpt rename to Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt index 819421f60afd4..ccac68990820c 100644 --- a/Zend/tests/lazy_objects/019.phpt +++ b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt @@ -20,16 +20,16 @@ function test(string $name, object $obj) { var_dump(get_mangled_object_vars($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/011.phpt b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt similarity index 73% rename from Zend/tests/lazy_objects/011.phpt rename to Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt index 3636a53d19831..19b2ad936299c 100644 --- a/Zend/tests/lazy_objects/011.phpt +++ b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -26,8 +27,7 @@ var_dump(get_object_vars($obj)); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/010.phpt b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt similarity index 67% rename from Zend/tests/lazy_objects/010.phpt rename to Zend/tests/lazy_objects/init_trigger_json_encode.phpt index ad996a5a21191..02b2331fcdb38 100644 --- a/Zend/tests/lazy_objects/010.phpt +++ b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -23,8 +24,7 @@ var_dump(json_encode($obj)); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt similarity index 70% rename from Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt rename to Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt index 0b22d564baa76..dbf16348d83b7 100644 --- a/Zend/tests/lazy_objects/reflection_to_string_does_not_init.phpt +++ b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt @@ -20,16 +20,16 @@ function test(string $name, object $obj) { var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/009.phpt b/Zend/tests/lazy_objects/init_trigger_serialize.phpt similarity index 68% rename from Zend/tests/lazy_objects/009.phpt rename to Zend/tests/lazy_objects/init_trigger_serialize.phpt index 7f1263a50af70..a14edded5ae16 100644 --- a/Zend/tests/lazy_objects/009.phpt +++ b/Zend/tests/lazy_objects/init_trigger_serialize.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -23,8 +24,7 @@ var_dump(serialize($obj)); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/007.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt similarity index 95% rename from Zend/tests/lazy_objects/007.phpt rename to Zend/tests/lazy_objects/init_trigger_var_dump.phpt index 6dfdf1457f4cf..30ece89208fa6 100644 --- a/Zend/tests/lazy_objects/007.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt @@ -26,7 +26,6 @@ var_dump($obj); print "# Virtual:\n"; -$reflector = new ReflectionClass(C::class); $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); diff --git a/Zend/tests/lazy_objects/025.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt similarity index 68% rename from Zend/tests/lazy_objects/025.phpt rename to Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt index 3f101dc5a2060..f752815f8e8b3 100644 --- a/Zend/tests/lazy_objects/025.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt @@ -15,23 +15,25 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s\n", $name); var_dump($obj); printf("Initialized:\n"); - var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + var_dump(!$reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/026.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt similarity index 70% rename from Zend/tests/lazy_objects/026.phpt rename to Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt index aea4a5003cf0c..7ec224e7b6b59 100644 --- a/Zend/tests/lazy_objects/026.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt @@ -15,23 +15,24 @@ class C { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); printf("# %s\n", $name); var_dump($obj); printf("Initialized:\n"); - var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + var_dump(!$reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/008.phpt b/Zend/tests/lazy_objects/init_trigger_var_export.phpt similarity index 68% rename from Zend/tests/lazy_objects/008.phpt rename to Zend/tests/lazy_objects/init_trigger_var_export.phpt index 56b1b30219b14..315235d5fb379 100644 --- a/Zend/tests/lazy_objects/008.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_export.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -24,8 +25,7 @@ print "\n"; print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/initialize_001.phpt b/Zend/tests/lazy_objects/initializeLazyObject.phpt similarity index 72% rename from Zend/tests/lazy_objects/initialize_001.phpt rename to Zend/tests/lazy_objects/initializeLazyObject.phpt index 5f1966974af3e..d1770c2c083a3 100644 --- a/Zend/tests/lazy_objects/initialize_001.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject.phpt @@ -10,7 +10,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); printf("Initialized:\n"); var_dump(!$reflector->isUninitializedLazyObject($obj)); @@ -21,16 +21,16 @@ function test(string $name, object $obj) { var_dump(!$reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new C(); $c->a = 1; diff --git a/Zend/tests/lazy_objects/initialize_005.phpt b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt similarity index 72% rename from Zend/tests/lazy_objects/initialize_005.phpt rename to Zend/tests/lazy_objects/initializeLazyObject_error.phpt index a2449aec79125..e81762a4dd748 100644 --- a/Zend/tests/lazy_objects/initialize_005.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt @@ -10,7 +10,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); var_dump(!$reflector->isUninitializedLazyObject($obj)); try { @@ -22,16 +22,16 @@ function test(string $name, object $obj) { var_dump(!$reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); throw new \Exception('initializer exception'); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); throw new \Exception('initializer exception'); }); diff --git a/Zend/tests/lazy_objects/initialize_002.phpt b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt similarity index 67% rename from Zend/tests/lazy_objects/initialize_002.phpt rename to Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt index 867b2d54b53d9..266e92cbc4b19 100644 --- a/Zend/tests/lazy_objects/initialize_002.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt @@ -10,7 +10,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); var_dump($obj->a); @@ -21,16 +21,16 @@ function test(string $name, object $obj) { var_dump(!$reflector->isUninitializedLazyObject($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new C(); $c->a = 1; @@ -39,12 +39,12 @@ $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); test('Virtual', $obj); ---EXPECT-- +--EXPECTF-- # Ghost: string(11) "initializer" int(1) bool(true) -object(C)#2 (1) { +object(C)#%d (1) { ["a"]=> int(1) } @@ -53,7 +53,7 @@ bool(true) string(11) "initializer" int(1) bool(true) -object(C)#4 (1) { +object(C)#%d (1) { ["a"]=> int(1) } diff --git a/Zend/tests/lazy_objects/005.phpt b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt similarity index 90% rename from Zend/tests/lazy_objects/005.phpt rename to Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt index 050b55871e2d1..54f5b79decf6e 100644 --- a/Zend/tests/lazy_objects/005.phpt +++ b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt @@ -24,9 +24,11 @@ class E extends B { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost initializer must return NULL or no value:\n"; -$obj = (new ReflectionClass(C::class))->newLazyGhost(function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); return new stdClass; @@ -50,8 +52,7 @@ $tests = [ ]; foreach ($tests as [$class, $instance]) { - $reflector = new ReflectionClass($class); - $obj = $reflector->newLazyProxy(function ($obj) use ($instance) { + $obj = (new ReflectionClass($class))->newLazyProxy(function ($obj) use ($instance) { var_dump("initializer"); $instance->b = 1; return $instance; @@ -73,8 +74,7 @@ $tests = [ ]; foreach ($tests as [$class, $instance]) { - $obj = (new ReflectionClass($class))->newInstanceWithoutConstructor(); - (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) use ($instance) { + $obj = (new ReflectionClass($class))->newLazyProxy(function ($obj) use ($instance) { var_dump("initializer"); return $instance; }); @@ -87,7 +87,7 @@ foreach ($tests as [$class, $instance]) { } } -$obj = (new ReflectionClass(C::class))->newLazyProxy(function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return $obj; }); diff --git a/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt b/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt new file mode 100644 index 0000000000000..82989b78409be --- /dev/null +++ b/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: ReflectionClass::isUninitializedLazyObject() +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj->a); + var_dump($reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj = new C(); + $obj->a = 1; + return $obj; +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +bool(true) +string(11) "initializer" +int(1) +bool(false) +# Proxy +bool(true) +string(11) "initializer" +int(1) +bool(false) diff --git a/Zend/tests/lazy_objects/is_initialized_001.phpt b/Zend/tests/lazy_objects/is_initialized_001.phpt deleted file mode 100644 index d121417a889db..0000000000000 --- a/Zend/tests/lazy_objects/is_initialized_001.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -Lazy objects: ReflectionClass::isInitialized ---FILE-- -newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { - var_dump("initializer"); - $obj->a = 1; -}); - -$reflector = new ReflectionClass($obj); -var_dump(!$reflector->isUninitializedLazyObject($obj)); - -var_dump($obj->a); - -var_dump(!$reflector->isUninitializedLazyObject($obj)); ---EXPECTF-- -bool(false) -string(11) "initializer" -int(1) -bool(true) diff --git a/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt b/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt deleted file mode 100644 index 62fd7c1c70542..0000000000000 --- a/Zend/tests/lazy_objects/is_uninitialized_lazy_object.phpt +++ /dev/null @@ -1,31 +0,0 @@ ---TEST-- -Lazy objects: isUninitializedLazyObject() ---FILE-- -a = 1; - } -} - -$reflector = new ReflectionClass(C::class); - -$obj = $reflector->newLazyGhost(function () {}); -var_dump($reflector->isUninitializedLazyObject($obj)); -$reflector->initializeLazyObject($obj); -var_dump($reflector->isUninitializedLazyObject($obj)); - -$obj = $reflector->newLazyProxy(function () { return new C(); }); -var_dump($reflector->isUninitializedLazyObject($obj)); -$reflector->initializeLazyObject($obj); -var_dump($reflector->isUninitializedLazyObject($obj)); - -?> ---EXPECT-- -bool(true) -bool(false) -bool(true) -bool(false) diff --git a/Zend/tests/lazy_objects/isset_002.phpt b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt similarity index 75% rename from Zend/tests/lazy_objects/isset_002.phpt rename to Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt index 39722791e5687..ef4deb1a952f9 100644 --- a/Zend/tests/lazy_objects/isset_002.phpt +++ b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: hooked property isset may initialize object +Lazy objects: hooked property isset initializes object if hook observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/isset_003.phpt b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt similarity index 71% rename from Zend/tests/lazy_objects/isset_003.phpt rename to Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt index 9ade21d693e1e..18d420064f72d 100644 --- a/Zend/tests/lazy_objects/isset_003.phpt +++ b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: hooked property isset may not initialize object +Lazy objects: hooked property isset may does not initialize object if hook does not observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/isset_001.phpt b/Zend/tests/lazy_objects/isset_initializes.phpt similarity index 78% rename from Zend/tests/lazy_objects/isset_001.phpt rename to Zend/tests/lazy_objects/isset_initializes.phpt index 3f9c918c9ebfc..d70ae76ccc84e 100644 --- a/Zend/tests/lazy_objects/isset_001.phpt +++ b/Zend/tests/lazy_objects/isset_initializes.phpt @@ -22,16 +22,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/mark_as_initialized_001.phpt b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt similarity index 76% rename from Zend/tests/lazy_objects/mark_as_initialized_001.phpt rename to Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt index b31852b49ff35..72f6476bc9afa 100644 --- a/Zend/tests/lazy_objects/mark_as_initialized_001.phpt +++ b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt @@ -10,7 +10,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); printf("Initialized:\n"); var_dump(!$reflector->isUninitializedLazyObject($obj)); @@ -23,16 +23,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new C(); $c->a = 1; diff --git a/Zend/tests/lazy_objects/new_instance_lazy_001.phpt b/Zend/tests/lazy_objects/new_instance_lazy_001.phpt deleted file mode 100644 index 32c2e1680c65c..0000000000000 --- a/Zend/tests/lazy_objects/new_instance_lazy_001.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -Lazy objects: newInstanceLazy can not instantiate internal classes ---FILE-- -newInstanceWithoutConstructor(); - -foreach (['resetAsLazyGhost', 'resetAsLazyProxy'] as $strategy) { - try { - $reflector->$strategy($obj, function ($obj) { - var_dump("initializer"); - }); - } catch (Error $e) { - printf("%s: %s\n", $e::class, $e->getMessage()); - } -} ---EXPECT-- -Error: Cannot make instance of internal class lazy: ReflectionClass is internal -Error: Cannot make instance of internal class lazy: ReflectionClass is internal diff --git a/Zend/tests/lazy_objects/new_instance_lazy_002.phpt b/Zend/tests/lazy_objects/new_instance_lazy_002.phpt deleted file mode 100644 index c8f3463c94edc..0000000000000 --- a/Zend/tests/lazy_objects/new_instance_lazy_002.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Lazy objects: newInstanceLazy can not instantiate sub-class of internal classes ---FILE-- -newInstanceWithoutConstructor(); - try { - $reflector->$strategy($obj, function ($obj) { - var_dump("initializer"); - }); - } catch (Error $e) { - printf("%s: %s\n", $e::class, $e->getMessage()); - } -} ---EXPECT-- -Error: Cannot make instance of internal class lazy: C inherits internal class ReflectionClass -Error: Cannot make instance of internal class lazy: C inherits internal class ReflectionClass diff --git a/Zend/tests/lazy_objects/new_instance_lazy_003.phpt b/Zend/tests/lazy_objects/new_instance_lazy_003.phpt deleted file mode 100644 index 00516a19b737f..0000000000000 --- a/Zend/tests/lazy_objects/new_instance_lazy_003.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Lazy objects: newInstanceLazy can instantiate sub-class of user classes ---FILE-- -newInstanceWithoutConstructor(); - $reflector->$strategy($obj, function ($obj) { - var_dump("initializer"); - }); - var_dump($obj); -} - ---EXPECTF-- -object(C)#%d (0) { -} -object(C)#%d (0) { -} diff --git a/Zend/tests/lazy_objects/new_instance_lazy_004.phpt b/Zend/tests/lazy_objects/new_instance_lazy_004.phpt deleted file mode 100644 index c4782b46b943d..0000000000000 --- a/Zend/tests/lazy_objects/new_instance_lazy_004.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Lazy objects: newInstanceLazy can instantiate stdClass ---FILE-- -newInstanceWithoutConstructor(); - $reflector->$strategy($obj, function ($obj) { - var_dump("initializer"); - }); - var_dump($obj); -} ---EXPECTF-- -object(stdClass)#%d (0) { -} -object(stdClass)#%d (0) { -} diff --git a/Zend/tests/lazy_objects/new_instance_lazy_005.phpt b/Zend/tests/lazy_objects/new_instance_lazy_005.phpt deleted file mode 100644 index fb028149c021b..0000000000000 --- a/Zend/tests/lazy_objects/new_instance_lazy_005.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Lazy objects: newInstanceLazy can instantiate sub-class of stdClass ---FILE-- -newInstanceWithoutConstructor(); - $reflector->$strategy($obj, function ($obj) { - var_dump("initializer"); - }); - var_dump($obj); -} - ---EXPECTF-- -object(C)#%d (0) { -} -object(C)#%d (0) { -} diff --git a/Zend/tests/lazy_objects/realize_001.phpt b/Zend/tests/lazy_objects/realize.phpt similarity index 86% rename from Zend/tests/lazy_objects/realize_001.phpt rename to Zend/tests/lazy_objects/realize.phpt index 69d78cdbe1f8f..f57303cb4b00a 100644 --- a/Zend/tests/lazy_objects/realize_001.phpt +++ b/Zend/tests/lazy_objects/realize.phpt @@ -23,9 +23,10 @@ class C extends B { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); var_dump(!$reflector->isUninitializedLazyObject($obj)); $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); @@ -52,16 +53,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/realize_003.phpt b/Zend/tests/lazy_objects/realize_no_props.phpt similarity index 100% rename from Zend/tests/lazy_objects/realize_003.phpt rename to Zend/tests/lazy_objects/realize_no_props.phpt diff --git a/Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt similarity index 85% rename from Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt rename to Zend/tests/lazy_objects/realize_proxy_overridden.phpt index 3858f3ff4216c..9da07059b1e10 100644 --- a/Zend/tests/lazy_objects/props_of_proxy_must_not_be_lazy_004.phpt +++ b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt @@ -22,9 +22,10 @@ class C extends B { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); var_dump(!$reflector->isUninitializedLazyObject($obj)); $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); @@ -47,16 +48,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/realize_002.phpt b/Zend/tests/lazy_objects/realize_skipped.phpt similarity index 86% rename from Zend/tests/lazy_objects/realize_002.phpt rename to Zend/tests/lazy_objects/realize_skipped.phpt index 6451b5e0127de..4d1c94a311cfe 100644 --- a/Zend/tests/lazy_objects/realize_002.phpt +++ b/Zend/tests/lazy_objects/realize_skipped.phpt @@ -23,9 +23,10 @@ class C extends B { } function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); var_dump(!$reflector->isUninitializedLazyObject($obj)); $reflector->getProperty('a')->skipLazyInitialization($obj); @@ -55,16 +56,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/make_lazy_already_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt similarity index 56% rename from Zend/tests/lazy_objects/make_lazy_already_exception.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt index 5dc8fb675d550..7f1f25486d2b4 100644 --- a/Zend/tests/lazy_objects/make_lazy_already_exception.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: makeLazy() on already lazy object is not allowed +Lazy objects: resetAsLazy*() on already lazy object is not allowed --FILE-- resetAsLazyGhost($obj, function () {}); +$reflector->resetAsLazyGhost($obj, function () {}); try { - $r->resetAsLazyGhost($obj, function ($obj) { + $reflector->resetAsLazyGhost($obj, function ($obj) { }); } catch (\Exception $e) { printf("%s: %s\n", $e::class, $e->getMessage()); @@ -23,23 +24,23 @@ try { printf("# Virtual:\n"); $obj = new C(); -$r->resetAsLazyProxy($obj, function () {}); +$reflector->resetAsLazyProxy($obj, function () {}); try { - $r->resetAsLazyProxy($obj, function ($obj) { + $reflector->resetAsLazyProxy($obj, function ($obj) { }); } catch (\Exception $e) { printf("%s: %s\n", $e::class, $e->getMessage()); } $obj = new C(); -$r->resetAsLazyProxy($obj, function () { +$reflector->resetAsLazyProxy($obj, function () { return new C(); }); -$r->initializeLazyObject($obj); +$reflector->initializeLazyObject($obj); try { - $r->resetAsLazyProxy($obj, function ($obj) { + $reflector->resetAsLazyProxy($obj, function ($obj) { }); } catch (\Exception $e) { printf("%s: %s\n", $e::class, $e->getMessage()); diff --git a/Zend/tests/lazy_objects/make_lazy_destructor_001.phpt b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt similarity index 78% rename from Zend/tests/lazy_objects/make_lazy_destructor_001.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt index e5400d7f51126..f7ed0178a6175 100644 --- a/Zend/tests/lazy_objects/make_lazy_destructor_001.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: makeLazy calls destructor of pre-existing object +Lazy objects: resetAsLazy*() calls destructor of pre-existing object --FILE-- resetAsLazyGhost($obj, function ($obj) { +$reflector->resetAsLazyGhost($obj, function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -32,7 +34,7 @@ print "# Virtual:\n"; $obj = new C(); print "In makeLazy\n"; -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$reflector->resetAsLazyProxy($obj, function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/021.phpt b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt similarity index 85% rename from Zend/tests/lazy_objects/021.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt index c4cc63c4a9743..2af1c07f23e3c 100644 --- a/Zend/tests/lazy_objects/021.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: reference source type is deleted by makeLazy() +Lazy objects: resetAsLazy deletes reference source type --FILE-- getMessage()); } -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector->resetAsLazyGhost($obj, function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -39,7 +41,7 @@ try { } catch (\Error $e) { printf("%s: %s\n", $e::class, $e->getMessage()); } -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$reflector->resetAsLazyProxy($obj, function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/make_lazy_destructor_003.phpt b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt similarity index 81% rename from Zend/tests/lazy_objects/make_lazy_destructor_003.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt index 4a0653ba327ec..0a6e2977f524c 100644 --- a/Zend/tests/lazy_objects/make_lazy_destructor_003.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: Destructor exception in makeLazy +Lazy objects: Destructor exception in resetAsLazy*() --FILE-- resetAsLazyGhost($obj, function ($obj) { + $reflector->resetAsLazyGhost($obj, function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -28,7 +30,7 @@ try { } // Object was not made lazy -var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +var_dump(!$reflector->isUninitializedLazyObject($obj)); print "# Virtual:\n"; diff --git a/Zend/tests/lazy_objects/feedback_008.phpt b/Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt similarity index 93% rename from Zend/tests/lazy_objects/feedback_008.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt index d309a2cd67d91..d277a4e247d6c 100644 --- a/Zend/tests/lazy_objects/feedback_008.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: feedback 008 +Lazy objects: resetAsLazy*() can reset initialized proxy --FILE-- resetAsLazyGhost($obj, function ($obj) { +$reflector->resetAsLazyGhost($obj, function ($obj) { var_dump("initializer"); $obj->__construct(); }, ReflectionClass::SKIP_DESTRUCTOR); @@ -32,7 +34,7 @@ print "# Virtual:\n"; $obj = new C(); print "In makeLazy\n"; -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$reflector->resetAsLazyProxy($obj, function ($obj) { var_dump("initializer"); return new C(); }, ReflectionClass::SKIP_DESTRUCTOR); diff --git a/Zend/tests/lazy_objects/reset_readonly_001.phpt b/Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt similarity index 95% rename from Zend/tests/lazy_objects/reset_readonly_001.phpt rename to Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt index f673d00bb7665..128e825e539a7 100644 --- a/Zend/tests/lazy_objects/reset_readonly_001.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: resetAsLazy preserves readonly semantics +Lazy objects: resetAsLazy*() preserves readonly semantics --FILE-- resetAsLazyGhost($obj, function ($obj) { +$reflector->resetAsLazyGhost($obj, function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -32,7 +34,7 @@ var_dump($obj); print "# Virtual:\n"; $obj = new C(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$reflector->resetAsLazyProxy($obj, function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/rfc_example_001.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_001.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_001.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_001.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_002.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_002.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_002.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_002.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_003.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_003.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_003.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_003.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_004.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_004.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_004.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_004.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_005.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_005.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_005.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_005.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_006.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_006.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_006.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_006.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_007.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_007.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_007.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_007.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_008.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_008.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_008.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_008.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_009.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_009.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_009.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_009.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_010.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_010.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_010.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_010.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_011.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_011.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_011.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_011.phpt diff --git a/Zend/tests/lazy_objects/rfc_example_012.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_012.phpt similarity index 100% rename from Zend/tests/lazy_objects/rfc_example_012.phpt rename to Zend/tests/lazy_objects/rfc/rfc_example_012.phpt diff --git a/Zend/tests/lazy_objects/serialize_006.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt similarity index 69% rename from Zend/tests/lazy_objects/serialize_006.phpt rename to Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt index 4c965c0fe934e..6d53449e1ec92 100644 --- a/Zend/tests/lazy_objects/serialize_006.phpt +++ b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: __serialize may initialize object +Lazy objects: serialize() initializes object if __serialize observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new c(); $c->a = 1; diff --git a/Zend/tests/lazy_objects/serialize_005.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt similarity index 62% rename from Zend/tests/lazy_objects/serialize_005.phpt rename to Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt index e9817b6a3a771..e3b5ceadb4e8f 100644 --- a/Zend/tests/lazy_objects/serialize_005.phpt +++ b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: serialize does not force initialization of object if the __serialize method is used +Lazy objects: serialize() does not initialize object if __serialize does observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/serialize_007.phpt b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt similarity index 74% rename from Zend/tests/lazy_objects/serialize_007.phpt rename to Zend/tests/lazy_objects/serialize___sleep_initializes.phpt index d817aaf5279be..4e183b3b1b148 100644 --- a/Zend/tests/lazy_objects/serialize_007.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt @@ -18,16 +18,16 @@ function test(string $name, object $obj) { var_dump($serialized, $unserialized); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new C(); $c->a = 1; diff --git a/Zend/tests/lazy_objects/serialize_008.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt similarity index 74% rename from Zend/tests/lazy_objects/serialize_008.phpt rename to Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt index 4ef54498e5b5b..1b7abd55fe4e1 100644 --- a/Zend/tests/lazy_objects/serialize_008.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt @@ -18,16 +18,16 @@ function test(string $name, object $obj) { var_dump($serialized, $unserialized); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->a = 1; }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); diff --git a/Zend/tests/lazy_objects/serialize_009.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt similarity index 72% rename from Zend/tests/lazy_objects/serialize_009.phpt rename to Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt index af1876afbddf3..51568f2fe0127 100644 --- a/Zend/tests/lazy_objects/serialize_009.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: __sleep may initialize object +Lazy objects: __sleep initializes object if it observes object state, even with SKIP_INITIALIZATION_ON_SERIALIZE --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->a = 1; }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $c = new C(); $c->a = 1; diff --git a/Zend/tests/lazy_objects/serialize_010.phpt b/Zend/tests/lazy_objects/serialize_hook.phpt similarity index 73% rename from Zend/tests/lazy_objects/serialize_010.phpt rename to Zend/tests/lazy_objects/serialize_hook.phpt index 6cc46513a0f6b..dd84899efe316 100644 --- a/Zend/tests/lazy_objects/serialize_010.phpt +++ b/Zend/tests/lazy_objects/serialize_hook.phpt @@ -20,16 +20,16 @@ function test(string $name, object $obj) { var_dump($obj->a); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/serialize_001.phpt b/Zend/tests/lazy_objects/serialize_initializes.phpt similarity index 70% rename from Zend/tests/lazy_objects/serialize_001.phpt rename to Zend/tests/lazy_objects/serialize_initializes.phpt index 2203f83760bcc..eea1361c34800 100644 --- a/Zend/tests/lazy_objects/serialize_001.phpt +++ b/Zend/tests/lazy_objects/serialize_initializes.phpt @@ -17,16 +17,16 @@ function test(string $name, object $obj) { var_dump(serialize($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/serialize_002.phpt b/Zend/tests/lazy_objects/serialize_props_ht.phpt similarity index 72% rename from Zend/tests/lazy_objects/serialize_002.phpt rename to Zend/tests/lazy_objects/serialize_props_ht.phpt index 9b664f92dbf8f..ebbdb407e20e7 100644 --- a/Zend/tests/lazy_objects/serialize_002.phpt +++ b/Zend/tests/lazy_objects/serialize_props_ht.phpt @@ -20,16 +20,16 @@ function test(string $name, object $obj) { var_dump(serialize($obj)); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/serialize_003.phpt b/Zend/tests/lazy_objects/serialize_skip_flag.phpt similarity index 75% rename from Zend/tests/lazy_objects/serialize_003.phpt rename to Zend/tests/lazy_objects/serialize_skip_flag.phpt index 71da496fb5aba..5ec4989d864b2 100644 --- a/Zend/tests/lazy_objects/serialize_003.phpt +++ b/Zend/tests/lazy_objects/serialize_skip_flag.phpt @@ -19,15 +19,15 @@ function test(string $name, object $obj) { var_dump($serialized, $unserialized); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); diff --git a/Zend/tests/lazy_objects/serialize_004.phpt b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt similarity index 77% rename from Zend/tests/lazy_objects/serialize_004.phpt rename to Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt index 70d3fe7dfc8b5..6292317cd3547 100644 --- a/Zend/tests/lazy_objects/serialize_004.phpt +++ b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt @@ -22,15 +22,15 @@ function test(string $name, object $obj) { var_dump($serialized, $unserialized); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); diff --git a/Zend/tests/lazy_objects/set_raw_value_001.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_001.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization.phpt diff --git a/Zend/tests/lazy_objects/skip_initialization_009.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception.phpt similarity index 100% rename from Zend/tests/lazy_objects/skip_initialization_009.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_007.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_007.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_008.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_008.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_009.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_009.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly.phpt diff --git a/Zend/tests/lazy_objects/skip_initialization_008.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly_variant.phpt similarity index 100% rename from Zend/tests/lazy_objects/skip_initialization_008.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly_variant.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_003.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_realize.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_003.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_realize.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_006.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_destruct.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_006.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_destruct.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_005.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_toString.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_005.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_toString.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_004.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips___set.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_004.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips___set.phpt diff --git a/Zend/tests/lazy_objects/set_raw_value_002.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips_hook.phpt similarity index 100% rename from Zend/tests/lazy_objects/set_raw_value_002.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips_hook.phpt diff --git a/Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt b/Zend/tests/lazy_objects/skipLazyInitialization.phpt similarity index 98% rename from Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt rename to Zend/tests/lazy_objects/skipLazyInitialization.phpt index ea4cfda907646..4f64dfb1eaa50 100644 --- a/Zend/tests/lazy_objects/reflection_lazy_object_skip_property_001.phpt +++ b/Zend/tests/lazy_objects/skipLazyInitialization.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: ReflectionClass::skipInitializerForProperty() prevent properties from triggering initializer +Lazy objects: ReflectionProperty::skipLazyInitialization() prevent properties from triggering initializer --FILE-- newInstanceWithoutConstructor(); try { - (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + $obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -17,9 +18,8 @@ try { print "# Virtual:\n"; -$obj = (new ReflectionClass(DateTime::class))->newInstanceWithoutConstructor(); try { - (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->__construct(); }); diff --git a/Zend/tests/lazy_objects/015.phpt b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt similarity index 70% rename from Zend/tests/lazy_objects/015.phpt rename to Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt index 727beb63ecb86..9629f63b20dc8 100644 --- a/Zend/tests/lazy_objects/015.phpt +++ b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt @@ -6,11 +6,12 @@ Lazy objects: sub-classes of internal classes can not be initialized lazily class C extends DateTime { } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); try { - (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + $obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -20,9 +21,8 @@ try { print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); try { - (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); $obj->__construct(); }); diff --git a/Zend/tests/lazy_objects/004.phpt b/Zend/tests/lazy_objects/support_readonly_class.phpt similarity index 74% rename from Zend/tests/lazy_objects/004.phpt rename to Zend/tests/lazy_objects/support_readonly_class.phpt index bc71f687f05d7..bb47b0b8af922 100644 --- a/Zend/tests/lazy_objects/004.phpt +++ b/Zend/tests/lazy_objects/support_readonly_class.phpt @@ -11,10 +11,11 @@ readonly class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -25,8 +26,7 @@ var_dump($obj); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/003.phpt b/Zend/tests/lazy_objects/support_readonly_prop.phpt similarity index 74% rename from Zend/tests/lazy_objects/003.phpt rename to Zend/tests/lazy_objects/support_readonly_prop.phpt index 589f5535a7324..05d674392da5a 100644 --- a/Zend/tests/lazy_objects/003.phpt +++ b/Zend/tests/lazy_objects/support_readonly_prop.phpt @@ -11,10 +11,11 @@ class C { } } +$reflector = new ReflectionClass(C::class); + print "# Ghost:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); @@ -25,8 +26,7 @@ var_dump($obj); print "# Virtual:\n"; -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/support_stdClass.phpt b/Zend/tests/lazy_objects/support_stdClass.phpt new file mode 100644 index 0000000000000..2bc61929cdc81 --- /dev/null +++ b/Zend/tests/lazy_objects/support_stdClass.phpt @@ -0,0 +1,30 @@ +--TEST-- +Lazy objects: stdClass can be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +--EXPECTF-- +# Ghost: +object(stdClass)#%d (0) { +} +# Virtual: +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt new file mode 100644 index 0000000000000..1730dc2fb28ac --- /dev/null +++ b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt @@ -0,0 +1,33 @@ +--TEST-- +Lazy objects: sub-classes of stdClass can be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +print "# Virtual:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (0) { +} +# Virtual: +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/unclean_shutdown.phpt b/Zend/tests/lazy_objects/unclean_shutdown.phpt index a5effe34642f9..d162ae2973678 100644 --- a/Zend/tests/lazy_objects/unclean_shutdown.phpt +++ b/Zend/tests/lazy_objects/unclean_shutdown.phpt @@ -7,8 +7,9 @@ class C { public $a; } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { trigger_error('Fatal', E_USER_ERROR); }); diff --git a/Zend/tests/lazy_objects/unset_008.phpt b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt similarity index 75% rename from Zend/tests/lazy_objects/unset_008.phpt rename to Zend/tests/lazy_objects/unset_defined_no_initialize.phpt index f8d110a963047..164f027c69556 100644 --- a/Zend/tests/lazy_objects/unset_008.phpt +++ b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt @@ -23,16 +23,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_010.phpt b/Zend/tests/lazy_objects/unset_hook.phpt similarity index 79% rename from Zend/tests/lazy_objects/unset_010.phpt rename to Zend/tests/lazy_objects/unset_hook.phpt index d22f3dcb83e92..2144af5d7c108 100644 --- a/Zend/tests/lazy_objects/unset_010.phpt +++ b/Zend/tests/lazy_objects/unset_hook.phpt @@ -29,16 +29,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_005.phpt b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt similarity index 77% rename from Zend/tests/lazy_objects/unset_005.phpt rename to Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt index 11560dfed5032..23b40753694a6 100644 --- a/Zend/tests/lazy_objects/unset_005.phpt +++ b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt @@ -24,16 +24,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_004.phpt b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt similarity index 73% rename from Zend/tests/lazy_objects/unset_004.phpt rename to Zend/tests/lazy_objects/unset_magic_may_initialize.phpt index be63629f532a2..66c2a6f35dba8 100644 --- a/Zend/tests/lazy_objects/unset_004.phpt +++ b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: unset of magic property may initialize object +Lazy objects: unset of magic property initializes object if method observes object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_003.phpt b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt similarity index 69% rename from Zend/tests/lazy_objects/unset_003.phpt rename to Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt index 2d08d94485d54..df25ae71f462e 100644 --- a/Zend/tests/lazy_objects/unset_003.phpt +++ b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: unset of magic property may not initialize object +Lazy objects: unset of magic property may not initialize object if method does not observe object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_009.phpt b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt similarity index 78% rename from Zend/tests/lazy_objects/unset_009.phpt rename to Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt index 3de9ca792ce1f..9c61e2406bab7 100644 --- a/Zend/tests/lazy_objects/unset_009.phpt +++ b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt @@ -18,7 +18,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); $reflector->getProperty('a')->skipLazyInitialization($obj); $reflector->getProperty('b')->skipLazyInitialization($obj); $reflector->getProperty('c')->skipLazyInitialization($obj); @@ -30,16 +30,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_006.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/unset_006.phpt rename to Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt index 8f03b11026b55..61362aa6c2e3f 100644 --- a/Zend/tests/lazy_objects/unset_006.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt @@ -21,16 +21,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_007.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt similarity index 77% rename from Zend/tests/lazy_objects/unset_007.phpt rename to Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt index b7ca5adbfdfd4..23944286f221f 100644 --- a/Zend/tests/lazy_objects/unset_007.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt @@ -22,16 +22,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/unset_001.phpt b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt similarity index 77% rename from Zend/tests/lazy_objects/unset_001.phpt rename to Zend/tests/lazy_objects/unset_undefined_initializes.phpt index c7f12cafd01d4..d582280b57b30 100644 --- a/Zend/tests/lazy_objects/unset_001.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt @@ -22,16 +22,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(1); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(1); }); diff --git a/Zend/tests/lazy_objects/use_case_001.phpt b/Zend/tests/lazy_objects/use_case_001.phpt index 0bce225b1effe..c2be34bfebc28 100644 --- a/Zend/tests/lazy_objects/use_case_001.phpt +++ b/Zend/tests/lazy_objects/use_case_001.phpt @@ -23,8 +23,8 @@ class Application { class Container { public function getEntityManagerService(): EntityManager { - $obj = (new ReflectionClass(EntityManager::class))->newInstanceWithoutConstructor(); - (new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + $reflector = new ReflectionClass(EntityManager::class); + $obj = $reflector->newLazyGhost(function ($obj) { $obj->__construct(); }); return $obj; diff --git a/Zend/tests/lazy_objects/use_case_001b.phpt b/Zend/tests/lazy_objects/use_case_001b.phpt index e32527bca1d78..f2491942d6e87 100644 --- a/Zend/tests/lazy_objects/use_case_001b.phpt +++ b/Zend/tests/lazy_objects/use_case_001b.phpt @@ -23,8 +23,8 @@ class Application { class Container { public function getEntityManagerService(): EntityManager { - $obj = (new ReflectionClass(EntityManager::class))->newInstanceWithoutConstructor(); - (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + $reflector = new ReflectionClass(EntityManager::class); + $obj = $reflector->newLazyProxy(function ($obj) { return new EntityManager(); }); return $obj; diff --git a/Zend/tests/lazy_objects/use_case_002.phpt b/Zend/tests/lazy_objects/use_case_002.phpt index 0bbead439c1f7..3a87acdfb8db3 100644 --- a/Zend/tests/lazy_objects/use_case_002.phpt +++ b/Zend/tests/lazy_objects/use_case_002.phpt @@ -23,14 +23,14 @@ class User { class EntityManager { public function lazyLoad(string $fqcn, int $id): object { - $entity = (new ReflectionClass($fqcn))->newInstanceWithoutConstructor(); - (new ReflectionClass($entity))->resetAsLazyGhost($entity, function ($obj) { + $reflector = new ReflectionClass($fqcn); + $entity = $reflector->newLazyGhost(function ($obj) { var_dump('initializer'); - $prop = new ReflectionProperty($obj, 'name'); + $prop = new ReflectionProperty($obj::class, 'name'); $prop->setValue($obj, 'John Doe'); }); - (new ReflectionProperty($entity, 'id'))->setRawValueWithoutLazyInitialization($entity, $id); + (new ReflectionProperty($fqcn, 'id'))->setRawValueWithoutLazyInitialization($entity, $id); return $entity; } diff --git a/Zend/tests/lazy_objects/write_002.phpt b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt similarity index 74% rename from Zend/tests/lazy_objects/write_002.phpt rename to Zend/tests/lazy_objects/write_dynamic_initializes.phpt index 34f76f087d892..b275d24a9aae5 100644 --- a/Zend/tests/lazy_objects/write_002.phpt +++ b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: property write to custom property initializes object +Lazy objects: property write to dynamic property initializes object --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/write_005.phpt b/Zend/tests/lazy_objects/write_initializer_exception.phpt similarity index 69% rename from Zend/tests/lazy_objects/write_005.phpt rename to Zend/tests/lazy_objects/write_initializer_exception.phpt index 6aafc032d55fc..2445da55d21d6 100644 --- a/Zend/tests/lazy_objects/write_005.phpt +++ b/Zend/tests/lazy_objects/write_initializer_exception.phpt @@ -19,15 +19,15 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { throw new \Exception('init exception'); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { throw new \Exception('init exception'); }); diff --git a/Zend/tests/lazy_objects/write_001.phpt b/Zend/tests/lazy_objects/write_initializes.phpt similarity index 76% rename from Zend/tests/lazy_objects/write_001.phpt rename to Zend/tests/lazy_objects/write_initializes.phpt index d5c4cb8fe01b6..bc32d8bfff0c9 100644 --- a/Zend/tests/lazy_objects/write_001.phpt +++ b/Zend/tests/lazy_objects/write_initializes.phpt @@ -21,16 +21,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/write_004.phpt b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt similarity index 76% rename from Zend/tests/lazy_objects/write_004.phpt rename to Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt index 6ea60ad2d04e2..8fdc882bbe5e1 100644 --- a/Zend/tests/lazy_objects/write_004.phpt +++ b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt @@ -24,16 +24,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/write_003.phpt b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt similarity index 76% rename from Zend/tests/lazy_objects/write_003.phpt rename to Zend/tests/lazy_objects/write_magic_may_initialize.phpt index 288b8125820f6..4804a72fce438 100644 --- a/Zend/tests/lazy_objects/write_003.phpt +++ b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Lazy objects: property write to magic property initializes object +Lazy objects: property write to magic property initializes object if method updates object state --FILE-- newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); diff --git a/Zend/tests/lazy_objects/write_006.phpt b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt similarity index 77% rename from Zend/tests/lazy_objects/write_006.phpt rename to Zend/tests/lazy_objects/write_skipped_no_initialize.phpt index 70b1b0c33b712..e2ee38e9ecb5b 100644 --- a/Zend/tests/lazy_objects/write_006.phpt +++ b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt @@ -16,7 +16,7 @@ class C { function test(string $name, object $obj) { printf("# %s:\n", $name); - $reflector = new ReflectionClass($obj); + $reflector = new ReflectionClass(C::class); $reflector->getProperty('a')->skipLazyInitialization($obj); $reflector->getProperty('b')->skipLazyInitialization($obj); $reflector->getProperty('c')->skipLazyInitialization($obj); @@ -28,16 +28,16 @@ function test(string $name, object $obj) { var_dump($obj); } -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { var_dump("initializer"); $obj->__construct(); }); test('Ghost', $obj); -$obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); -(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { +$obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); return new C(); }); From 36c70ee433f7659d29f1ff26e15bae91c9633264 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 25 Jul 2024 22:13:05 +0200 Subject: [PATCH 227/280] Test cleanup --- Zend/tests/lazy_objects/clone_calls___clone_once.phpt | 4 ++-- Zend/tests/lazy_objects/clone_initialized.phpt | 4 ++-- Zend/tests/lazy_objects/clone_initializer_exception.phpt | 4 ++-- Zend/tests/lazy_objects/clone_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/dtor_called_if_init.phpt | 8 ++++---- Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt | 4 ++-- Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt | 4 ++-- .../fetch_coalesce_non_existing_initializes.phpt | 4 ++-- .../lazy_objects/fetch_declared_prop_initializes.phpt | 4 ++-- .../lazy_objects/fetch_dynamic_prop_initializes.phpt | 4 ++-- .../tests/lazy_objects/fetch_hook_may_not_initialize.phpt | 4 ++-- .../lazy_objects/fetch_hook_virtual_may_initialize.phpt | 4 ++-- .../fetch_hook_virtual_may_not_initialize.phpt | 4 ++-- .../lazy_objects/fetch_magic_prop_may_initialize.phpt | 4 ++-- .../lazy_objects/fetch_magic_prop_may_not_initialize.phpt | 4 ++-- .../fetch_magic_prop_recursive_may_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt | 4 ++-- .../lazy_objects/fetch_op_dynamic_prop_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/fetch_op_error.phpt | 4 ++-- Zend/tests/lazy_objects/fetch_op_initializes.phpt | 4 ++-- .../fetch_op_skipped_prop_does_not_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/fetch_ref_initializes.phpt | 4 ++-- .../fetch_ref_skipped_prop_does_not_initialize.phpt | 4 ++-- .../fetch_skipped_prop_does_not_initialize.phpt | 4 ++-- .../final_classes_can_be_initialized_lazily.phpt | 4 ++-- Zend/tests/lazy_objects/gc_001.phpt | 8 ++++---- Zend/tests/lazy_objects/gc_002.phpt | 8 ++++---- Zend/tests/lazy_objects/gc_003.phpt | 8 ++++---- Zend/tests/lazy_objects/gc_004.phpt | 8 ++++---- Zend/tests/lazy_objects/gc_005.phpt | 8 ++++---- .../lazy_objects/init_exception_leaves_object_lazy.phpt | 4 ++-- .../init_exception_reverts_initializer_changes.phpt | 6 +++--- ...t_exception_reverts_initializer_changes_dyn_props.phpt | 6 +++--- ...tion_reverts_initializer_changes_dyn_props_and_ht.phpt | 6 +++--- ...ption_reverts_initializer_changes_overridden_prop.phpt | 4 ++-- ...it_exception_reverts_initializer_changes_props_ht.phpt | 6 +++--- ...xception_reverts_initializer_changes_props_ht_ref.phpt | 6 +++--- .../tests/lazy_objects/init_handles_ref_source_types.phpt | 6 +++--- .../init_handles_ref_source_types_exception.phpt | 6 +++--- Zend/tests/lazy_objects/init_trigger_array_cast.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_foreach.phpt | 4 ++-- .../init_trigger_get_mangled_object_vars.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_json_encode.phpt | 4 ++-- .../init_trigger_reflection_object_toString.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_serialize.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_var_dump.phpt | 4 ++-- .../init_trigger_var_dump_debug_info_001.phpt | 4 ++-- .../init_trigger_var_dump_debug_info_002.phpt | 4 ++-- Zend/tests/lazy_objects/init_trigger_var_export.phpt | 4 ++-- Zend/tests/lazy_objects/initializeLazyObject.phpt | 4 ++-- Zend/tests/lazy_objects/initializeLazyObject_error.phpt | 4 ++-- .../initializeLazyObject_noop_on_initialized_object.phpt | 4 ++-- .../initializer_must_return_the_right_type.phpt | 4 ++-- Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt | 4 ++-- .../lazy_objects/isset_hooked_may_not_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/isset_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt | 4 ++-- Zend/tests/lazy_objects/realize.phpt | 4 ++-- Zend/tests/lazy_objects/realize_no_props.phpt | 4 ++-- Zend/tests/lazy_objects/realize_proxy_overridden.phpt | 4 ++-- Zend/tests/lazy_objects/realize_skipped.phpt | 4 ++-- .../lazy_objects/reset_as_lazy_already_exception.phpt | 4 ++-- .../lazy_objects/reset_as_lazy_calls_destructor.phpt | 4 ++-- .../reset_as_lazy_deletes_reference_source_type.phpt | 4 ++-- .../lazy_objects/reset_as_lazy_destructor_exception.phpt | 4 ++-- .../lazy_objects/reset_as_lazy_may_skip_destructor.phpt | 4 ++-- .../lazy_objects/reset_as_lazy_resets_dynamic_props.phpt | 4 ++-- .../serialize___serialize_may_initialize.phpt | 4 ++-- .../serialize___serialize_may_not_initialize.phpt | 4 ++-- .../tests/lazy_objects/serialize___sleep_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt | 4 ++-- .../serialize___sleep_skip_flag_may_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/serialize_hook.phpt | 4 ++-- Zend/tests/lazy_objects/serialize_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/serialize_props_ht.phpt | 4 ++-- Zend/tests/lazy_objects/serialize_skip_flag.phpt | 4 ++-- Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt | 4 ++-- Zend/tests/lazy_objects/skipLazyInitialization.phpt | 4 ++-- Zend/tests/lazy_objects/support_no_internal_classes.phpt | 4 ++-- .../lazy_objects/support_no_internal_sub_classes.phpt | 4 ++-- Zend/tests/lazy_objects/support_readonly_class.phpt | 4 ++-- Zend/tests/lazy_objects/support_readonly_prop.phpt | 4 ++-- Zend/tests/lazy_objects/support_stdClass.phpt | 4 ++-- Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt | 4 ++-- Zend/tests/lazy_objects/unset_defined_no_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/unset_hook.phpt | 4 ++-- .../lazy_objects/unset_magic_circular_may_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/unset_magic_may_initialize.phpt | 4 ++-- .../lazy_objects/unset_magic_may_not_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt | 4 ++-- .../lazy_objects/unset_undefined_dynamic_initializes.phpt | 4 ++-- .../unset_undefined_dynamic_initializes_no_props_ht.phpt | 4 ++-- Zend/tests/lazy_objects/unset_undefined_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/write_dynamic_initializes.phpt | 4 ++-- Zend/tests/lazy_objects/write_initializes.phpt | 4 ++-- .../lazy_objects/write_magic_circular_may_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/write_magic_may_initialize.phpt | 4 ++-- Zend/tests/lazy_objects/write_skipped_no_initialize.phpt | 4 ++-- 100 files changed, 219 insertions(+), 219 deletions(-) diff --git a/Zend/tests/lazy_objects/clone_calls___clone_once.phpt b/Zend/tests/lazy_objects/clone_calls___clone_once.phpt index f2af4b241250e..c0f91e3e27a42 100644 --- a/Zend/tests/lazy_objects/clone_calls___clone_once.phpt +++ b/Zend/tests/lazy_objects/clone_calls___clone_once.phpt @@ -40,7 +40,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -56,7 +56,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" string(5) "clone" bool(false) diff --git a/Zend/tests/lazy_objects/clone_initialized.phpt b/Zend/tests/lazy_objects/clone_initialized.phpt index 30f802a7fd5f3..9540a0f960964 100644 --- a/Zend/tests/lazy_objects/clone_initialized.phpt +++ b/Zend/tests/lazy_objects/clone_initialized.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -53,7 +53,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" bool(false) lazy proxy object(C)#%d (1) { diff --git a/Zend/tests/lazy_objects/clone_initializer_exception.phpt b/Zend/tests/lazy_objects/clone_initializer_exception.phpt index 8334e6eadd84e..72069ca650d12 100644 --- a/Zend/tests/lazy_objects/clone_initializer_exception.phpt +++ b/Zend/tests/lazy_objects/clone_initializer_exception.phpt @@ -41,7 +41,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new \Exception('initializer'); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -49,7 +49,7 @@ Exception: initializer bool(true) lazy ghost object(C)#%d (0) { } -# Virtual: +# Proxy: Exception: initializer bool(true) lazy proxy object(C)#%d (0) { diff --git a/Zend/tests/lazy_objects/clone_initializes.phpt b/Zend/tests/lazy_objects/clone_initializes.phpt index c7ca01ba1168b..54be97fd768aa 100644 --- a/Zend/tests/lazy_objects/clone_initializes.phpt +++ b/Zend/tests/lazy_objects/clone_initializes.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -51,7 +51,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" bool(false) lazy proxy object(C)#%d (1) { diff --git a/Zend/tests/lazy_objects/dtor_called_if_init.phpt b/Zend/tests/lazy_objects/dtor_called_if_init.phpt index 4002a66a13c36..19a9c7b941b00 100644 --- a/Zend/tests/lazy_objects/dtor_called_if_init.phpt +++ b/Zend/tests/lazy_objects/dtor_called_if_init.phpt @@ -25,10 +25,10 @@ function ghost() { var_dump($obj->a); } -function virtual() { +function proxy() { $reflector = new ReflectionClass(C::class); - print "# Virtual:\n"; + print "# Proxy:\n"; print "In makeLazy\n"; $obj = $reflector->newLazyProxy(function () { @@ -41,7 +41,7 @@ function virtual() { } ghost(); -virtual(); +proxy(); --EXPECTF-- # Ghost: @@ -54,7 +54,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: In makeLazy After makeLazy string(11) "initializer" diff --git a/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt index 17855588ec1fc..f0ea2fdfc1ba2 100644 --- a/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt +++ b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt @@ -23,7 +23,7 @@ print "After newLazyGhost\n"; // Does not call destructor $obj = null; -print "# Virtual:\n"; +print "# Proxy:\n"; print "In newLazyProxy\n"; $obj = $reflector->newLazyProxy(function () { @@ -38,6 +38,6 @@ $obj = null; # Ghost: In newLazyGhost After newLazyGhost -# Virtual: +# Proxy: In newLazyProxy After newLazyGhost diff --git a/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt index 832fc7f4f64bd..f2a4123c1b2ac 100644 --- a/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt @@ -32,7 +32,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (0) { @@ -46,7 +46,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt index 5ed1e27133618..1ac947f93d65e 100644 --- a/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt @@ -32,7 +32,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (0) { @@ -46,7 +46,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt index 7b055c060ae3d..da3540bacc578 100644 --- a/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -53,7 +53,7 @@ object(C)#%d (2) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt index dc4d92d2965dd..a8171bcd6eb6c 100644 --- a/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt @@ -33,7 +33,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -48,7 +48,7 @@ object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt index b87134fff0934..b81635dfb9c84 100644 --- a/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt @@ -39,7 +39,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -56,7 +56,7 @@ object(C)#%d (2) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt index a81f52795966e..f66f9a34a680b 100644 --- a/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt @@ -40,7 +40,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -57,7 +57,7 @@ object(C)#%d (2) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt index cd9a1d837c95e..adf3c2845f21a 100644 --- a/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ lazy ghost object(C)#%d (0) { ["b"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt index cff2e62d1bb47..491b26dbbee82 100644 --- a/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (0) { @@ -49,7 +49,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt index bc362abf02831..3cd283705ab2b 100644 --- a/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -48,7 +48,7 @@ lazy ghost object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt index c1c9dcb1cfe42..db605826f64e5 100644 --- a/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (0) { @@ -51,7 +51,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt index 1efd76071224a..f6f4cddedc63e 100644 --- a/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Error("initializer"); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ lazy ghost object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt index e52e3c8cdf184..3f9af1aa5f1dd 100644 --- a/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt @@ -33,7 +33,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ object(C)#%d (2) { ["dynamic"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_op_error.phpt b/Zend/tests/lazy_objects/fetch_op_error.phpt index 7e04d3593d527..4ccfef4ac4d3a 100644 --- a/Zend/tests/lazy_objects/fetch_op_error.phpt +++ b/Zend/tests/lazy_objects/fetch_op_error.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Error("initializer"); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ lazy ghost object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_op_initializes.phpt b/Zend/tests/lazy_objects/fetch_op_initializes.phpt index 1731f7004fc75..d1a8605eb1d7f 100644 --- a/Zend/tests/lazy_objects/fetch_op_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_op_initializes.phpt @@ -33,7 +33,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -48,7 +48,7 @@ object(C)#%d (1) { ["a"]=> int(3) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt index f152366b12ca1..c1e662eaef1a3 100644 --- a/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt @@ -46,7 +46,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new c(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -69,7 +69,7 @@ object(C)#%d (2) { ["c"]=> uninitialized(int) } -# Virtual: +# Proxy: object(C)#%d (2) { ["a"]=> NULL diff --git a/Zend/tests/lazy_objects/fetch_ref_initializes.phpt b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt index 6c7c28cee5084..e1289558aaa77 100644 --- a/Zend/tests/lazy_objects/fetch_ref_initializes.phpt +++ b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt @@ -33,7 +33,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -48,7 +48,7 @@ object(C)#%d (1) { ["a"]=> &int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt index 26a820cbb092a..c64cd88781a31 100644 --- a/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt @@ -41,7 +41,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -63,7 +63,7 @@ object(C)#%d (2) { ["c"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt index f210e8b05aaa7..e93a65ee87cec 100644 --- a/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt +++ b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt @@ -48,7 +48,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -71,7 +71,7 @@ object(C)#%d (2) { ["c"]=> uninitialized(int) } -# Virtual: +# Proxy: object(C)#%d (2) { ["a"]=> NULL diff --git a/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt index 42a5177f91125..2434e69f57349 100644 --- a/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt +++ b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt @@ -24,7 +24,7 @@ var_dump($obj); var_dump($obj->a); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -48,7 +48,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/gc_001.phpt b/Zend/tests/lazy_objects/gc_001.phpt index db4ab41b8587e..7707423815a5b 100644 --- a/Zend/tests/lazy_objects/gc_001.phpt +++ b/Zend/tests/lazy_objects/gc_001.phpt @@ -26,8 +26,8 @@ function ghost() { gc_collect_cycles(); } -function virtual() { - printf("# Virtual:\n"); +function proxy() { + printf("# Proxy:\n"); $canary = new Canary(); $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); @@ -42,13 +42,13 @@ function virtual() { } ghost(); -virtual(); +proxy(); ?> ==DONE== --EXPECT-- # Ghost: string(10) "__destruct" -# Virtual: +# Proxy: string(10) "__destruct" ==DONE== diff --git a/Zend/tests/lazy_objects/gc_002.phpt b/Zend/tests/lazy_objects/gc_002.phpt index 004907c483adb..c794e4077c2bc 100644 --- a/Zend/tests/lazy_objects/gc_002.phpt +++ b/Zend/tests/lazy_objects/gc_002.phpt @@ -29,8 +29,8 @@ function ghost() { gc_collect_cycles(); } -function virtual() { - printf("# Virtual:\n"); +function proxy() { + printf("# Proxy:\n"); $canary = new Canary(); @@ -47,13 +47,13 @@ function virtual() { } ghost(); -virtual(); +proxy(); ?> ==DONE== --EXPECT-- # Ghost: string(10) "__destruct" -# Virtual: +# Proxy: string(10) "__destruct" ==DONE== diff --git a/Zend/tests/lazy_objects/gc_003.phpt b/Zend/tests/lazy_objects/gc_003.phpt index a17765a503d7a..ce58398e509e3 100644 --- a/Zend/tests/lazy_objects/gc_003.phpt +++ b/Zend/tests/lazy_objects/gc_003.phpt @@ -29,8 +29,8 @@ function ghost() { gc_collect_cycles(); } -function virtual() { - printf("# Virtual:\n"); +function proxy() { + printf("# Proxy:\n"); $canary = new Canary(); @@ -47,13 +47,13 @@ function virtual() { } ghost(); -virtual(); +proxy(); ?> ==DONE== --EXPECT-- # Ghost: string(10) "__destruct" -# Virtual: +# Proxy: string(10) "__destruct" ==DONE== diff --git a/Zend/tests/lazy_objects/gc_004.phpt b/Zend/tests/lazy_objects/gc_004.phpt index f0e64f39de698..ab0b5c2996770 100644 --- a/Zend/tests/lazy_objects/gc_004.phpt +++ b/Zend/tests/lazy_objects/gc_004.phpt @@ -31,8 +31,8 @@ function ghost() { gc_collect_cycles(); } -function virtual() { - printf("# Virtual:\n"); +function proxy() { + printf("# Proxy:\n"); $canary = new Canary(); @@ -51,7 +51,7 @@ function virtual() { } ghost(); -virtual(); +proxy(); ?> ==DONE== @@ -60,7 +60,7 @@ virtual(); object(C)#%d (0) { } string(10) "__destruct" -# Virtual: +# Proxy: object(C)#%d (0) { } string(10) "__destruct" diff --git a/Zend/tests/lazy_objects/gc_005.phpt b/Zend/tests/lazy_objects/gc_005.phpt index 70a20759248bf..934439adab951 100644 --- a/Zend/tests/lazy_objects/gc_005.phpt +++ b/Zend/tests/lazy_objects/gc_005.phpt @@ -34,8 +34,8 @@ function ghost() { gc_collect_cycles(); } -function virtual() { - printf("# Virtual:\n"); +function proxy() { + printf("# Proxy:\n"); $canary = new Canary(); @@ -56,13 +56,13 @@ function virtual() { } ghost(); -virtual(); +proxy(); ?> ==DONE== --EXPECT-- # Ghost: string(10) "__destruct" -# Virtual: +# Proxy: string(10) "__destruct" ==DONE== diff --git a/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt b/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt index a25517ea16004..86ecc2c9b8e2e 100644 --- a/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt +++ b/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt @@ -40,14 +40,14 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: string(11) "initializer" initializer exception Is lazy: 1 -# Virtual: +# Proxy: string(11) "initializer" initializer exception Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt index 2bc098a8d19ee..4edf9481ebc22 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt @@ -46,8 +46,8 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the virtual proxy are not reverted -test('Virtual', $obj); +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -60,7 +60,7 @@ lazy ghost object(C)#%d (1) { int(0) } Is lazy: 1 -# Virtual: +# Proxy: string(11) "initializer" initializer exception lazy proxy object(C)#%d (3) { diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt index ba91c973a11d0..ce94fc8b2ab79 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt @@ -49,8 +49,8 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the virtual proxy are not reverted -test('Virtual', $obj); +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -63,7 +63,7 @@ lazy ghost object(C)#%d (1) { int(0) } Is lazy: 1 -# Virtual: +# Proxy: string(11) "initializer" initializer exception lazy proxy object(C)#%d (4) { diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt index 7de4025dcee94..1bc3eb2cea8e1 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt @@ -52,8 +52,8 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the virtual proxy are not reverted -test('Virtual', $obj); +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -68,7 +68,7 @@ lazy ghost object(C)#%d (1) { int(0) } Is lazy: 1 -# Virtual: +# Proxy: array(0) { } string(11) "initializer" diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt index 8127f7f138942..656d267e137fa 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt @@ -47,14 +47,14 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: string(11) "initializer" initializer exception Is lazy: 1 -# Virtual: +# Proxy: string(11) "initializer" initializer exception Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt index 081a4d2737f48..c4f0bd98773fd 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt @@ -49,8 +49,8 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the virtual proxy are not reverted -test('Virtual', $obj); +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -67,7 +67,7 @@ lazy ghost object(C)#%d (1) { int(0) } Is lazy: 1 -# Virtual: +# Proxy: array(1) { ["c"]=> int(0) diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt index f3d4285f55257..094f5c9b80947 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt @@ -55,8 +55,8 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the virtual proxy are not reverted -test('Virtual', $obj); +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -76,7 +76,7 @@ Is lazy: 1 Warning: Undefined variable $table in %s on line %d NULL -# Virtual: +# Proxy: array(1) { ["c"]=> int(0) diff --git a/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt index 1042131ec3165..366751e02d7bb 100644 --- a/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt @@ -29,7 +29,7 @@ function test(string $name, object $obj) { var_dump($obj); try { - // $refA retained its reference source type (except for the virtual + // $refA retained its reference source type (except for the proxy // case: its the responsibility of the initializer to propagate // pre-initialized properties to the instance) $refA = 1; @@ -58,7 +58,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(null); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (2) { @@ -78,7 +78,7 @@ object(C)#%d (3) { NULL } TypeError: Cannot assign int to reference held by property C::$a of type ?C -# Virtual: +# Proxy: lazy proxy object(C)#%d (2) { ["a"]=> &NULL diff --git a/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt index d2caad0ccd84e..0613ca5f3f44d 100644 --- a/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt @@ -32,7 +32,7 @@ function test(string $name, object $obj) { var_dump($obj); try { - // $refA retained its reference source type (except for the virtual + // $refA retained its reference source type (except for the proxy // case: it is the responsibility of the initializer to propagate // pre-initialized properties to the instance) $refA = 1; @@ -71,7 +71,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(null); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: lazy ghost object(C)#%d (2) { @@ -90,7 +90,7 @@ lazy ghost object(C)#%d (2) { } TypeError: Cannot assign int to reference held by property C::$a of type ?C TypeError: Cannot assign int to reference held by property C::$b of type ?C -# Virtual: +# Proxy: lazy proxy object(C)#%d (2) { ["a"]=> &NULL diff --git a/Zend/tests/lazy_objects/init_trigger_array_cast.phpt b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt index e58e1cbbd775a..d48633f33dfad 100644 --- a/Zend/tests/lazy_objects/init_trigger_array_cast.phpt +++ b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt @@ -25,7 +25,7 @@ var_dump((array)$obj); $obj->a = 2; var_dump((array)$obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -47,7 +47,7 @@ array(1) { ["a"]=> int(2) } -# Virtual: +# Proxy: array(0) { } string(11) "initializer" diff --git a/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt b/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt index 0909942bcb284..b755484c15d93 100644 --- a/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt +++ b/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt @@ -24,7 +24,7 @@ debug_zval_dump($obj); $reflector->initializeLazyObject($obj); debug_zval_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -47,7 +47,7 @@ object(C)#%d (1) refcount(2){ ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) refcount(2){ ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/init_trigger_foreach.phpt b/Zend/tests/lazy_objects/init_trigger_foreach.phpt index dd5c8b6291433..b8bd780666bb8 100644 --- a/Zend/tests/lazy_objects/init_trigger_foreach.phpt +++ b/Zend/tests/lazy_objects/init_trigger_foreach.phpt @@ -24,7 +24,7 @@ foreach ($obj as $prop => $value) { var_dump($prop, $value); } -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -41,7 +41,7 @@ string(11) "initializer" string(14) "C::__construct" string(1) "a" int(1) -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(1) "a" diff --git a/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt index ccac68990820c..aff038fcda25f 100644 --- a/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt +++ b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt @@ -34,7 +34,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: array(0) { @@ -45,7 +45,7 @@ array(1) { ["a"]=> int(2) } -# Virtual: +# Proxy: array(0) { } string(11) "initializer" diff --git a/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt index 19b2ad936299c..ca14328377488 100644 --- a/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt +++ b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt @@ -25,7 +25,7 @@ var_dump(get_object_vars($obj)); $obj->a = 2; var_dump(get_object_vars($obj)); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -49,7 +49,7 @@ array(1) { ["a"]=> int(2) } -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" array(1) { diff --git a/Zend/tests/lazy_objects/init_trigger_json_encode.phpt b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt index 02b2331fcdb38..c7c7aed99f1ce 100644 --- a/Zend/tests/lazy_objects/init_trigger_json_encode.phpt +++ b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt @@ -22,7 +22,7 @@ $obj = $reflector->newLazyGhost(function ($obj) { var_dump(json_encode($obj)); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -36,7 +36,7 @@ var_dump(json_encode($obj)); string(11) "initializer" string(14) "C::__construct" string(7) "{"a":1}" -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(7) "{"a":1}" diff --git a/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt index dbf16348d83b7..7f0cc6e4ff543 100644 --- a/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt +++ b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt @@ -34,12 +34,12 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost Initialized: bool(false) -# Virtual +# Proxy Initialized: bool(false) diff --git a/Zend/tests/lazy_objects/init_trigger_serialize.phpt b/Zend/tests/lazy_objects/init_trigger_serialize.phpt index a14edded5ae16..5a5e2f78f66b7 100644 --- a/Zend/tests/lazy_objects/init_trigger_serialize.phpt +++ b/Zend/tests/lazy_objects/init_trigger_serialize.phpt @@ -22,7 +22,7 @@ $obj = $reflector->newLazyGhost(function ($obj) { var_dump(serialize($obj)); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -37,7 +37,7 @@ var_dump(serialize($obj)); string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt index 30ece89208fa6..17dbe62cae6eb 100644 --- a/Zend/tests/lazy_objects/init_trigger_var_dump.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt @@ -24,7 +24,7 @@ var_dump($obj); $reflector->initializeLazyObject($obj); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -47,7 +47,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt index f752815f8e8b3..0fbcaf826e305 100644 --- a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost @@ -48,7 +48,7 @@ lazy ghost object(C)#%d (1) { } Initialized: bool(false) -# Virtual +# Proxy lazy proxy object(C)#%d (1) { [0]=> string(5) "hello" diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt index 7ec224e7b6b59..54ebf1a80aaa3 100644 --- a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost @@ -49,7 +49,7 @@ object(C)#%d (1) { } Initialized: bool(true) -# Virtual +# Proxy string(11) "initializer" string(14) "C::__construct" lazy proxy object(C)#%d (1) { diff --git a/Zend/tests/lazy_objects/init_trigger_var_export.phpt b/Zend/tests/lazy_objects/init_trigger_var_export.phpt index 315235d5fb379..55d45063646dd 100644 --- a/Zend/tests/lazy_objects/init_trigger_var_export.phpt +++ b/Zend/tests/lazy_objects/init_trigger_var_export.phpt @@ -23,7 +23,7 @@ $obj = $reflector->newLazyGhost(function ($obj) { var_export($obj); print "\n"; -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -39,7 +39,7 @@ string(14) "C::__construct" \C::__set_state(array( 'a' => 1, )) -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" \C::__set_state(array( diff --git a/Zend/tests/lazy_objects/initializeLazyObject.phpt b/Zend/tests/lazy_objects/initializeLazyObject.phpt index d1770c2c083a3..b53858a76a207 100644 --- a/Zend/tests/lazy_objects/initializeLazyObject.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ object(C)#%d (1) { } Initialized: bool(true) -# Virtual: +# Proxy: Initialized: bool(false) string(11) "initializer" diff --git a/Zend/tests/lazy_objects/initializeLazyObject_error.phpt b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt index e81762a4dd748..541d6a8c491f1 100644 --- a/Zend/tests/lazy_objects/initializeLazyObject_error.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new \Exception('initializer exception'); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: @@ -44,7 +44,7 @@ bool(false) string(11) "initializer" initializer exception bool(false) -# Virtual: +# Proxy: bool(false) string(11) "initializer" initializer exception diff --git a/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt index 266e92cbc4b19..c424d2ecd396d 100644 --- a/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt +++ b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -49,7 +49,7 @@ object(C)#%d (1) { int(1) } bool(true) -# Virtual: +# Proxy: string(11) "initializer" int(1) bool(true) diff --git a/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt index 54f5b79decf6e..dd68a88406eeb 100644 --- a/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt +++ b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt @@ -42,7 +42,7 @@ try { } var_dump($obj); -print "# Virtual initializer must return an instance of a compatible class:\n"; +print "# Proxy initializer must return an instance of a compatible class:\n"; print "## Valid cases:\n"; $tests = [ @@ -111,7 +111,7 @@ lazy ghost object(C)#%d (0) { ["b"]=> uninitialized(int) } -# Virtual initializer must return an instance of a compatible class: +# Proxy initializer must return an instance of a compatible class: ## Valid cases: ## C vs C string(11) "initializer" diff --git a/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt index ef4deb1a952f9..3bdb63c3166b9 100644 --- a/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt +++ b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt @@ -39,7 +39,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -56,7 +56,7 @@ object(C)#%d (2) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt index 18d420064f72d..35f15be1007c3 100644 --- a/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt @@ -39,7 +39,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -52,7 +52,7 @@ lazy ghost object(C)#%d (0) { ["b"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/isset_initializes.phpt b/Zend/tests/lazy_objects/isset_initializes.phpt index d70ae76ccc84e..1478bb054fce2 100644 --- a/Zend/tests/lazy_objects/isset_initializes.phpt +++ b/Zend/tests/lazy_objects/isset_initializes.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -53,7 +53,7 @@ object(C)#%d (2) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt index 72f6476bc9afa..691cba7f34f4a 100644 --- a/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt +++ b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt @@ -39,7 +39,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -53,7 +53,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: Initialized: bool(false) markLazyObjectAsInitialized(true) returns $obj: diff --git a/Zend/tests/lazy_objects/realize.phpt b/Zend/tests/lazy_objects/realize.phpt index f57303cb4b00a..988b8114bde6f 100644 --- a/Zend/tests/lazy_objects/realize.phpt +++ b/Zend/tests/lazy_objects/realize.phpt @@ -67,7 +67,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -82,7 +82,7 @@ object(C)#%d (2) { ["a"]=> string(2) "a2" } -# Virtual: +# Proxy: bool(false) bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/realize_no_props.phpt b/Zend/tests/lazy_objects/realize_no_props.phpt index 5450eda1aeba1..0344c560c8a65 100644 --- a/Zend/tests/lazy_objects/realize_no_props.phpt +++ b/Zend/tests/lazy_objects/realize_no_props.phpt @@ -53,7 +53,7 @@ $obj3 = (new ReflectionClass(C::class))->newLazyGhost(function () { var_dump("initializer"); }); -test('Virtual', $obj, $obj2, $obj3); +test('Proxy', $obj, $obj2, $obj3); --EXPECTF-- # Ghost: @@ -66,7 +66,7 @@ object(D)#%d (0) { bool(false) object(C)#%d (0) { } -# Virtual: +# Proxy: bool(false) object(C)#%d (0) { } diff --git a/Zend/tests/lazy_objects/realize_proxy_overridden.phpt b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt index 9da07059b1e10..7443c7f0a66a3 100644 --- a/Zend/tests/lazy_objects/realize_proxy_overridden.phpt +++ b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt @@ -62,7 +62,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -77,7 +77,7 @@ object(C)#%d (2) { ["a"]=> string(2) "a2" } -# Virtual: +# Proxy: bool(false) bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/realize_skipped.phpt b/Zend/tests/lazy_objects/realize_skipped.phpt index 4d1c94a311cfe..711ccfa93c000 100644 --- a/Zend/tests/lazy_objects/realize_skipped.phpt +++ b/Zend/tests/lazy_objects/realize_skipped.phpt @@ -70,7 +70,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -86,7 +86,7 @@ object(C)#%d (0) { ["a"]=> uninitialized(string) } -# Virtual: +# Proxy: bool(false) bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt index 7f1f25486d2b4..708855d312609 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt @@ -21,7 +21,7 @@ try { printf("%s: %s\n", $e::class, $e->getMessage()); } -printf("# Virtual:\n"); +printf("# Proxy:\n"); $obj = new C(); $reflector->resetAsLazyProxy($obj, function () {}); @@ -51,6 +51,6 @@ try { --EXPECT-- # Ghost: ReflectionException: Object is already lazy -# Virtual: +# Proxy: ReflectionException: Object is already lazy ==DONE== diff --git a/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt index f7ed0178a6175..733da55a5cbc5 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt @@ -30,7 +30,7 @@ print "After makeLazy\n"; var_dump($obj->a); $obj = null; -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = new C(); print "In makeLazy\n"; @@ -52,7 +52,7 @@ After makeLazy string(11) "initializer" int(1) string(13) "C::__destruct" -# Virtual: +# Proxy: In makeLazy string(13) "C::__destruct" After makeLazy diff --git a/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt index 2af1c07f23e3c..583d5ccc881e5 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt @@ -32,7 +32,7 @@ var_dump($obj); var_dump($obj->a); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = new C(); $ref = &$obj->a; @@ -65,7 +65,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: TypeError: Cannot assign string to reference held by property C::$a of type int lazy proxy object(C)#%d (0) { ["a"]=> diff --git a/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt index 0a6e2977f524c..67a79ab6e8ac9 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt @@ -32,7 +32,7 @@ try { // Object was not made lazy var_dump(!$reflector->isUninitializedLazyObject($obj)); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = new C(); try { @@ -52,6 +52,6 @@ var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); # Ghost: Exception: C::__destruct bool(true) -# Virtual: +# Proxy: Exception: C::__destruct bool(true) diff --git a/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt b/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt index c7e8b0b8c2ccc..d0c22a0333ff2 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt @@ -30,7 +30,7 @@ print "After makeLazy\n"; var_dump($obj->a); $obj = null; -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = new C(); print "In makeLazy\n"; @@ -51,7 +51,7 @@ After makeLazy string(11) "initializer" int(1) string(13) "C::__destruct" -# Virtual: +# Proxy: In makeLazy After makeLazy string(11) "initializer" diff --git a/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt b/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt index c9a05910ae350..d99a30b3c1164 100644 --- a/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt +++ b/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt @@ -31,7 +31,7 @@ var_dump($obj); var_dump($obj->a); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = new C(); $reflector->resetAsLazyProxy($obj, function ($obj) { @@ -59,7 +59,7 @@ object(C)#%d (2) { object(Canary)#%d (0) { } } -# Virtual: +# Proxy: string(18) "Canary::__destruct" string(18) "Canary::__destruct" lazy proxy object(C)#%d (0) { diff --git a/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt index 6d53449e1ec92..632f6e9780880 100644 --- a/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt +++ b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt @@ -34,7 +34,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -44,7 +44,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" string(24) "O:1:"C":1:{s:1:"a";i:1;}" object(C)#%d (1) { diff --git a/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt index e3b5ceadb4e8f..404a35ee10442 100644 --- a/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt @@ -31,7 +31,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -40,7 +40,7 @@ object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: string(12) "O:1:"C":0:{}" object(C)#%d (0) { ["a"]=> diff --git a/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt index 4e183b3b1b148..ec7657afc6916 100644 --- a/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt @@ -34,7 +34,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -44,7 +44,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" string(24) "O:1:"C":1:{s:1:"a";i:1;}" object(C)#%d (1) { diff --git a/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt index 1b7abd55fe4e1..4641fb2a49ac3 100644 --- a/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt @@ -32,7 +32,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { $obj->a = 1; }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -41,7 +41,7 @@ object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: string(12) "O:1:"C":0:{}" object(C)#%d (0) { ["a"]=> diff --git a/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt index 51568f2fe0127..ed909a875de47 100644 --- a/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return $c; }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -46,7 +46,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: string(11) "initializer" int(1) string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_hook.phpt b/Zend/tests/lazy_objects/serialize_hook.phpt index dd84899efe316..f2094db2e9a0a 100644 --- a/Zend/tests/lazy_objects/serialize_hook.phpt +++ b/Zend/tests/lazy_objects/serialize_hook.phpt @@ -34,14 +34,14 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_initializes.phpt b/Zend/tests/lazy_objects/serialize_initializes.phpt index eea1361c34800..eacb6a985df39 100644 --- a/Zend/tests/lazy_objects/serialize_initializes.phpt +++ b/Zend/tests/lazy_objects/serialize_initializes.phpt @@ -31,14 +31,14 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_props_ht.phpt b/Zend/tests/lazy_objects/serialize_props_ht.phpt index ebbdb407e20e7..e8b8834b008de 100644 --- a/Zend/tests/lazy_objects/serialize_props_ht.phpt +++ b/Zend/tests/lazy_objects/serialize_props_ht.phpt @@ -34,14 +34,14 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECT-- # Ghost: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" -# Virtual: +# Proxy: string(11) "initializer" string(14) "C::__construct" string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_skip_flag.phpt b/Zend/tests/lazy_objects/serialize_skip_flag.phpt index 5ec4989d864b2..b7f75320fd51c 100644 --- a/Zend/tests/lazy_objects/serialize_skip_flag.phpt +++ b/Zend/tests/lazy_objects/serialize_skip_flag.phpt @@ -31,7 +31,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -42,7 +42,7 @@ object(C)#%d (1) { ["b"]=> int(1) } -# Virtual: +# Proxy: string(24) "O:1:"C":1:{s:1:"b";i:1;}" object(C)#%d (1) { ["a"]=> diff --git a/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt index 6292317cd3547..b54f7846eb86d 100644 --- a/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt +++ b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt @@ -34,7 +34,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -45,7 +45,7 @@ object(C)#%d (1) { ["b"]=> int(1) } -# Virtual: +# Proxy: string(24) "O:1:"C":1:{s:1:"b";i:1;}" object(C)#%d (1) { ["a"]=> diff --git a/Zend/tests/lazy_objects/skipLazyInitialization.phpt b/Zend/tests/lazy_objects/skipLazyInitialization.phpt index 4f64dfb1eaa50..faff902d0e418 100644 --- a/Zend/tests/lazy_objects/skipLazyInitialization.phpt +++ b/Zend/tests/lazy_objects/skipLazyInitialization.phpt @@ -149,7 +149,7 @@ $factory = function () use ($reflector) { }); }; -test('Virtual', $factory); +test('Proxy', $factory); ?> --EXPECT-- @@ -250,7 +250,7 @@ ReflectionException: setRawValueWithoutLazyInitialization(): ReflectionException: -# Virtual: +# Proxy: ## Property [ private $priv = 'privB' ] diff --git a/Zend/tests/lazy_objects/support_no_internal_classes.phpt b/Zend/tests/lazy_objects/support_no_internal_classes.phpt index b87b096f1882d..f5c8cd1e06738 100644 --- a/Zend/tests/lazy_objects/support_no_internal_classes.phpt +++ b/Zend/tests/lazy_objects/support_no_internal_classes.phpt @@ -16,7 +16,7 @@ try { printf("%s: %s\n", $e::class, $e->getMessage()); } -print "# Virtual:\n"; +print "# Proxy:\n"; try { $obj = $reflector->newLazyProxy(function ($obj) { @@ -30,5 +30,5 @@ try { --EXPECTF-- # Ghost: Error: Cannot make instance of internal class lazy: DateTime is internal -# Virtual: +# Proxy: Error: Cannot make instance of internal class lazy: DateTime is internal diff --git a/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt index 9629f63b20dc8..47a8214626048 100644 --- a/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt +++ b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt @@ -19,7 +19,7 @@ try { printf("%s: %s\n", $e::class, $e->getMessage()); } -print "# Virtual:\n"; +print "# Proxy:\n"; try { $obj = $reflector->newLazyProxy(function ($obj) { @@ -33,5 +33,5 @@ try { --EXPECTF-- # Ghost: Error: Cannot make instance of internal class lazy: C inherits internal class DateTime -# Virtual: +# Proxy: Error: Cannot make instance of internal class lazy: C inherits internal class DateTime diff --git a/Zend/tests/lazy_objects/support_readonly_class.phpt b/Zend/tests/lazy_objects/support_readonly_class.phpt index bb47b0b8af922..cdd420cc121b8 100644 --- a/Zend/tests/lazy_objects/support_readonly_class.phpt +++ b/Zend/tests/lazy_objects/support_readonly_class.phpt @@ -24,7 +24,7 @@ var_dump($obj); var_dump($obj->a); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -48,7 +48,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/support_readonly_prop.phpt b/Zend/tests/lazy_objects/support_readonly_prop.phpt index 05d674392da5a..2aabc3a6d18c4 100644 --- a/Zend/tests/lazy_objects/support_readonly_prop.phpt +++ b/Zend/tests/lazy_objects/support_readonly_prop.phpt @@ -24,7 +24,7 @@ var_dump($obj); var_dump($obj->a); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -48,7 +48,7 @@ object(C)#%d (1) { ["a"]=> int(1) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["a"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/support_stdClass.phpt b/Zend/tests/lazy_objects/support_stdClass.phpt index 2bc61929cdc81..dac4884584133 100644 --- a/Zend/tests/lazy_objects/support_stdClass.phpt +++ b/Zend/tests/lazy_objects/support_stdClass.phpt @@ -13,7 +13,7 @@ $obj = $reflector->newLazyGhost(function ($obj) { }); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -25,6 +25,6 @@ var_dump($obj); # Ghost: object(stdClass)#%d (0) { } -# Virtual: +# Proxy: object(stdClass)#%d (0) { } diff --git a/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt index 1730dc2fb28ac..bb73b2a54ec0f 100644 --- a/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt +++ b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt @@ -16,7 +16,7 @@ $obj = $reflector->newLazyGhost(function ($obj) { }); var_dump($obj); -print "# Virtual:\n"; +print "# Proxy:\n"; $obj = $reflector->newLazyProxy(function ($obj) { var_dump("initializer"); @@ -28,6 +28,6 @@ var_dump($obj); # Ghost: object(C)#%d (0) { } -# Virtual: +# Proxy: object(C)#%d (0) { } diff --git a/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt index 164f027c69556..7f09504564d2b 100644 --- a/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt +++ b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -49,7 +49,7 @@ object(C)#%d (0) { ["a"]=> uninitialized(int) } -# Virtual: +# Proxy: object(C)#%d (1) { ["a"]=> int(1) diff --git a/Zend/tests/lazy_objects/unset_hook.phpt b/Zend/tests/lazy_objects/unset_hook.phpt index 2144af5d7c108..e174b22f2cdc4 100644 --- a/Zend/tests/lazy_objects/unset_hook.phpt +++ b/Zend/tests/lazy_objects/unset_hook.phpt @@ -43,7 +43,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -56,7 +56,7 @@ lazy ghost object(C)#%d (0) { ["b"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt index 23b40753694a6..0705db85fad9a 100644 --- a/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt +++ b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -52,7 +52,7 @@ object(C)#%d (1) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt index 66c2a6f35dba8..4b0cf95763109 100644 --- a/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt +++ b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -53,7 +53,7 @@ object(C)#%d (1) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt index df25ae71f462e..8d22cb4a3cdc9 100644 --- a/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt +++ b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt @@ -37,7 +37,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -49,7 +49,7 @@ lazy ghost object(C)#%d (0) { ["b"]=> uninitialized(int) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt index 9c61e2406bab7..d990b696c24fc 100644 --- a/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt +++ b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt @@ -44,7 +44,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: object(C)#%d (2) { @@ -61,7 +61,7 @@ object(C)#%d (0) { ["c"]=> uninitialized(int) } -# Virtual: +# Proxy: object(C)#%d (2) { ["a"]=> NULL diff --git a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt index 61362aa6c2e3f..792ca9c1cf7b7 100644 --- a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -49,7 +49,7 @@ object(C)#%d (1) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt index 23944286f221f..c27198f3f1968 100644 --- a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -47,7 +47,7 @@ object(C)#%d (1) { ["b"]=> int(2) } -# Virtual: +# Proxy: string(12) "before unset" string(11) "initializer" string(14) "C::__construct" diff --git a/Zend/tests/lazy_objects/unset_undefined_initializes.phpt b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt index d582280b57b30..59fc95f902e8f 100644 --- a/Zend/tests/lazy_objects/unset_undefined_initializes.phpt +++ b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(1); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ object(C)#%d (1) { ["b"]=> int(2) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/write_dynamic_initializes.phpt b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt index b275d24a9aae5..7864426463456 100644 --- a/Zend/tests/lazy_objects/write_dynamic_initializes.phpt +++ b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt @@ -36,7 +36,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -54,7 +54,7 @@ object(C)#%d (3) { ["custom"]=> int(3) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/write_initializes.phpt b/Zend/tests/lazy_objects/write_initializes.phpt index bc32d8bfff0c9..2505352308719 100644 --- a/Zend/tests/lazy_objects/write_initializes.phpt +++ b/Zend/tests/lazy_objects/write_initializes.phpt @@ -35,7 +35,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -51,7 +51,7 @@ object(C)#%d (2) { ["b"]=> int(3) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { ["b"]=> uninitialized(int) diff --git a/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt index 8fdc882bbe5e1..52a7ae90cbde0 100644 --- a/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt +++ b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ object(C)#%d (1) { ["a"]=> int(3) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { } string(11) "initializer" diff --git a/Zend/tests/lazy_objects/write_magic_may_initialize.phpt b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt index 4804a72fce438..b90bb3cbc57b1 100644 --- a/Zend/tests/lazy_objects/write_magic_may_initialize.phpt +++ b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt @@ -38,7 +38,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -50,7 +50,7 @@ object(C)#%d (1) { ["a"]=> int(3) } -# Virtual: +# Proxy: lazy proxy object(C)#%d (0) { } string(11) "initializer" diff --git a/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt index e2ee38e9ecb5b..387b1a1cd8fed 100644 --- a/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt +++ b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt @@ -42,7 +42,7 @@ $obj = $reflector->newLazyProxy(function ($obj) { return new C(); }); -test('Virtual', $obj); +test('Proxy', $obj); --EXPECTF-- # Ghost: @@ -62,7 +62,7 @@ object(C)#%d (3) { ["c"]=> int(2) } -# Virtual: +# Proxy: object(C)#%d (2) { ["a"]=> NULL From 80b422890e27806bf870c04840694e747dc683e4 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 7 Aug 2024 17:12:47 +0200 Subject: [PATCH 228/280] Fix build --- Zend/zend_object_handlers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index cceede535cb8d..0a7ba56c5bc6f 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1475,7 +1475,8 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void if (!zobj) { return; } - return zend_std_unset_property(zobj, name, cache_slot); + zend_std_unset_property(zobj, name, cache_slot); + return; } /* Reset the IS_PROP_UNINIT flag, if it exists and bypass __unset(). */ @@ -1527,7 +1528,8 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void if (!zobj) { return; } - return zend_std_unset_property(zobj, name, cache_slot); + zend_std_unset_property(zobj, name, cache_slot); + return; } } /* }}} */ From 0832ea2022a62b6d6c8f1e3c737088552ac937f0 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 7 Aug 2024 17:34:24 +0200 Subject: [PATCH 229/280] Hooks --- .../init_trigger_foreach_hooks.phpt | 96 +++++++++++++++++++ .../init_trigger_json_encode_hooks.phpt | 80 ++++++++++++++++ Zend/zend_object_handlers.h | 7 +- Zend/zend_property_hooks.c | 9 ++ ext/reflection/php_reflection.c | 2 +- 5 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt create mode 100644 Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt diff --git a/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt b/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt new file mode 100644 index 0000000000000..d955c92c5ab01 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt @@ -0,0 +1,96 @@ +--TEST-- +Lazy objects: Foreach initializes object +--FILE-- +b; } + set(int $value) { $this->b = $value; } + } + public int $c { + get { return $this->a + 2; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + $this->b = 2; + $this->d = 4; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Ghost (init exception):\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy (init exception):\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +string(1) "d" +int(4) +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +# Ghost (init exception): +Exception: +# Proxy (init exception): +Exception: diff --git a/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt b/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt new file mode 100644 index 0000000000000..c754d030e4305 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt @@ -0,0 +1,80 @@ +--TEST-- +Lazy objects: json_encode initializes object +--FILE-- +b; } + set(int $value) { $this->b = $value; } + } + public int $c { + get { return $this->a + 2; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + $this->b = 2; + $this->d = 4; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(json_encode($obj)); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(json_encode($obj)); + +print "# Ghost (init exception):\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy (init exception):\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(25) "{"a":1,"b":2,"c":3,"d":4}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(25) "{"a":1,"b":2,"c":3,"d":4}" +# Ghost (init exception): +Exception: +# Proxy (init exception): +Exception: diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 7ac2051ea3870..c84f13f4411a7 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -22,6 +22,7 @@ #include +#include "zend_hash.h" #include "zend_types.h" #include "zend_property_hooks.h" #include "zend_lazy_objects.h" @@ -275,9 +276,9 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { if (UNEXPECTED(zend_lazy_object_must_init(object))) { - zend_object *instance = zend_lazy_object_init(object); - if (EXPECTED(instance)) { - object = instance; + object = zend_lazy_object_init(object); + if (UNEXPECTED(!object)) { + return object->properties = (zend_array*) &zend_empty_array; } } if (!object->properties) { diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index b00a526125c27..9cfa15ecafa4d 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -18,6 +18,8 @@ #include "zend.h" #include "zend_API.h" +#include "zend_hash.h" +#include "zend_lazy_objects.h" #include "zend_property_hooks.h" typedef struct { @@ -49,6 +51,13 @@ static uint32_t zho_num_backed_props(zend_object *zobj) static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access, bool include_dynamic_props) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(!zobj)) { + return (zend_array*) &zend_empty_array; + } + } + zend_class_entry *ce = zobj->ce; zend_array *properties = zend_new_array(ce->default_properties_count); zend_hash_real_init_mixed(properties); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 9354bf626877e..5114df206913f 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5327,7 +5327,7 @@ ZEND_METHOD(ReflectionClass, initializeLazyObject) if (zend_lazy_object_initialized(object)) { RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); } else { - ZEND_ASSERT(EG(exception)); + RETURN_THROWS(); } } /* }}} */ From 0b2f63246be31967ca4ff21b79bbca2d19c55618 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 10 Aug 2024 17:38:36 +0200 Subject: [PATCH 230/280] Fix windows build --- win32/build/config.w32 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 668995045725b..08edb81d11947 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -240,7 +240,8 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c"); + zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \ + zend_lazy_objects.c"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); var PHP_ASSEMBLER = PATH_PROG({ From 6460680834efc62601759630b25780163d02d811 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 12:47:28 +0200 Subject: [PATCH 231/280] Fix test --- Zend/tests/lazy_objects/unclean_shutdown.phpt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Zend/tests/lazy_objects/unclean_shutdown.phpt b/Zend/tests/lazy_objects/unclean_shutdown.phpt index d162ae2973678..9ec02b5a7c4d7 100644 --- a/Zend/tests/lazy_objects/unclean_shutdown.phpt +++ b/Zend/tests/lazy_objects/unclean_shutdown.phpt @@ -10,9 +10,10 @@ class C { $reflector = new ReflectionClass(C::class); $obj = $reflector->newLazyGhost(function ($obj) { - trigger_error('Fatal', E_USER_ERROR); + // Trigger a fatal error to get an unclean shutdown + class bool {} }); var_dump($obj->a); --EXPECTF-- -Fatal error: Fatal in %s on line %d +Fatal error: Cannot use 'bool' as class name%s on line %d From a674d55a61baa6aa1532c70ea581343cbde1efc5 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 14:00:10 +0200 Subject: [PATCH 232/280] JIT --- .../lazy_objects/jit_assign_obj_dynamic.phpt | 69 ++++++++++++++++++ .../jit_assign_obj_op_dynamic.phpt | 70 +++++++++++++++++++ .../jit_assign_obj_op_prop_info.phpt | 69 ++++++++++++++++++ .../jit_assign_obj_op_unknown_prop_info.phpt | 47 +++++++++++++ ...sign_obj_op_unknown_prop_info_untyped.phpt | 48 +++++++++++++ .../jit_assign_obj_prop_info.phpt | 69 ++++++++++++++++++ .../jit_assign_obj_unknown_prop_info.phpt | 46 ++++++++++++ ..._assign_obj_unknown_prop_info_untyped.phpt | 47 +++++++++++++ ext/opcache/jit/zend_jit_ir.c | 26 ++++--- 9 files changed, 477 insertions(+), 14 deletions(-) create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt create mode 100644 Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt diff --git a/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt b/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt new file mode 100644 index 0000000000000..d49fb585cecc9 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with dynamic prop +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt new file mode 100644 index 0000000000000..cdf639815e3bb --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with dynamic prop +--FILE-- +a = 1; + $this->b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a += 1; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["b"]=> + int(1) + ["a"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt new file mode 100644 index 0000000000000..31689723c202c --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with known prop_info +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a += 1; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt new file mode 100644 index 0000000000000..7c812514eb2e9 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with unknown prop info +--FILE-- +a = 1; + $this->b = 2; + } + function test(object $obj) { + $obj->a += 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt new file mode 100644 index 0000000000000..211090110245a --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with unknown prop info untyped +--FILE-- +a = 1; + $this->b = 2; + } + function test(object $obj) { + $obj->a += 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +?> +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt new file mode 100644 index 0000000000000..631ba647e8859 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with known prop_info +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt new file mode 100644 index 0000000000000..6d48cbd2861c1 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt @@ -0,0 +1,46 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with unknown prop info +--FILE-- +b = 2; + } + function test(object $obj) { + $obj->a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt new file mode 100644 index 0000000000000..f3c2d7dbe722a --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with unknown prop info untyped +--FILE-- +b = 2; + } + function test(object $obj) { + $obj->a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +?> +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 49ddf40a0e7ce..9b1bf9a71dde1 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -14466,22 +14466,20 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ZEND_ASSERT(slow_inputs == IR_UNUSED); goto slow_path; } - if (!ce || ce_is_instanceof || !(ce->ce_flags & ZEND_ACC_IMMUTABLE) || ce->__get || ce->__set) { - // Undefined property with magic __get()/__set() - if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { - int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); - const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + // Undefined property with potential magic __get()/__set() or lazy object + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } - ir_GUARD(jit_Z_TYPE_INFO(jit, prop_addr), ir_CONST_ADDR(exit_addr)); - } else { - ir_ref if_def = ir_IF(jit_Z_TYPE_INFO(jit, prop_addr)); - ir_IF_FALSE_cold(if_def); - ir_END_list(slow_inputs); - ir_IF_TRUE(if_def); + if (!exit_addr) { + return 0; } + ir_GUARD(jit_Z_TYPE_INFO(jit, prop_addr), ir_CONST_ADDR(exit_addr)); + } else { + ir_ref if_def = ir_IF(jit_Z_TYPE_INFO(jit, prop_addr)); + ir_IF_FALSE_cold(if_def); + ir_END_list(slow_inputs); + ir_IF_TRUE(if_def); } if (ZEND_TYPE_IS_SET(prop_info->type)) { ir_ref ref, arg3, arg4; From 627de1f0afa5bc3f5f2a47e297e18a3129a61aa0 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 14:20:01 +0200 Subject: [PATCH 233/280] Remove TODO --- Zend/zend_lazy_objects.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 3e2740a08ed07..91ccad3af5655 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -469,7 +469,6 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) /* unset() properties of the proxy. This ensures that all accesses are be * delegated to the backing instance from now on. */ - // TODO: test that props are undef after initialization zend_object_dtor_dynamic_properties(obj); obj->properties = NULL; From a7249389664e8a83c1c4abc4d2c042318dc62b9d Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 14:20:28 +0200 Subject: [PATCH 234/280] Expose initializer zv to gc --- Zend/zend_lazy_objects.c | 37 +++++++++++++++++++++++++++++++++++++ Zend/zend_lazy_objects.h | 1 + Zend/zend_object_handlers.c | 30 +----------------------------- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 91ccad3af5655..eee168b0afd70 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -39,6 +39,7 @@ #include "zend_API.h" #include "zend_compile.h" #include "zend_execute.h" +#include "zend_gc.h" #include "zend_hash.h" #include "zend_object_handlers.h" #include "zend_objects_API.h" @@ -665,3 +666,39 @@ HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp) *is_temp = 0; return zend_get_properties_no_init(object); } + +HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n) +{ + ZEND_ASSERT(zend_object_is_lazy(zobj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(zobj); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + + if (zend_lazy_object_initialized(zobj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(zobj)); + zend_get_gc_buffer_add_obj(gc_buffer, info->u.instance); + zend_get_gc_buffer_use(gc_buffer, table, n); + /* Initialized proxy object can not have properties */ + return NULL; + } + + zend_fcall_info_cache *fcc = &info->u.initializer.fcc; + if (fcc->object) { + zend_get_gc_buffer_add_obj(gc_buffer, fcc->object); + } + if (fcc->closure) { + zend_get_gc_buffer_add_obj(gc_buffer, fcc->closure); + } + zend_get_gc_buffer_add_zval(gc_buffer, &info->u.initializer.zv); + + /* Uninitialized lazy objects can not have dynamic properties, so we can + * ignore zobj->properties. */ + zval *prop = zobj->properties_table; + zval *end = prop + zobj->ce->default_properties_count; + for ( ; prop < end; prop++) { + zend_get_gc_buffer_add_zval(gc_buffer, prop); + } + + zend_get_gc_buffer_use(gc_buffer, table, n); + return NULL; +} diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index ca1ad4a630a3d..87654b1396095 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -74,6 +74,7 @@ zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); void zend_lazy_object_del_info(zend_object *obj); zend_object *zend_lazy_object_clone(zend_object *old_obj); HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); +HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n); bool zend_lazy_object_decr_lazy_props(zend_object *obj); void zend_lazy_object_realize(zend_object *obj); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 0a7ba56c5bc6f..97793bf597a8b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -164,35 +164,7 @@ ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /* return zobj->handlers->get_properties(zobj); } else { if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); - if (zend_lazy_object_initialized(zobj)) { - ZEND_ASSERT(zend_object_is_lazy_proxy(zobj)); - zend_object *instance = zend_lazy_object_get_instance(zobj); - zend_get_gc_buffer_add_obj(gc_buffer, instance); - } else { - zend_fcall_info_cache* initializer = zend_lazy_object_get_initializer_fcc(zobj); - if (initializer) { - // TODO: also expose _get_initializer_zv() to the GC - if (initializer->object) { - zend_get_gc_buffer_add_obj(gc_buffer, initializer->object); - } - if (initializer->closure) { - zend_get_gc_buffer_add_obj(gc_buffer, initializer->closure); - } - } - } - if (zobj->properties) { - zend_get_gc_buffer_use(gc_buffer, table, n); - return zobj->properties; - } else { - zval *prop = zobj->properties_table; - zval *end = prop + zobj->ce->default_properties_count; - for ( ; prop < end; prop++) { - zend_get_gc_buffer_add_zval(gc_buffer, prop); - } - zend_get_gc_buffer_use(gc_buffer, table, n); - return NULL; - } + return zend_lazy_object_get_gc(zobj, table, n); } else if (zobj->properties) { *table = NULL; *n = 0; From ac439e8b2bd1b57782f9c55ce88ed520bd547812 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 14:21:07 +0200 Subject: [PATCH 235/280] Add test --- .../reset_as_lazy_accepts_sub_classes.phpt | 28 +++++++++++++++++++ ext/reflection/php_reflection.c | 1 - 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt diff --git a/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt b/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt new file mode 100644 index 0000000000000..b836fbfea58d7 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt @@ -0,0 +1,28 @@ +--TEST-- +Lazy objects: resetAsLazy*() accept a sub-class of the reflected class +--FILE-- +resetAsLazyGhost(new A(), function () {}); +$reflector->resetAsLazyGhost(new B(), function () {}); + +try { + $reflector->resetAsLazyGhost(new C(), function () {}); +} catch (TypeError $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +==DONE== +--EXPECT-- +TypeError: ReflectionClass::resetAsLazyGhost(): Argument #1 ($object) must be of type A, C given +==DONE== diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5114df206913f..70c3f4f198369 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5208,7 +5208,6 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, if (is_reset) { ZEND_PARSE_PARAMETERS_START(2, 3) - // TODO: check that obj->ce matches ce Z_PARAM_OBJ_OF_CLASS(obj, ce) Z_PARAM_FUNC(fci, fcc) Z_PARAM_OPTIONAL From bd03b05548db63cc5dd2cf473cb50efb7e1da93b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 13 Aug 2024 14:21:37 +0200 Subject: [PATCH 236/280] Internal param name consistency with api --- ext/reflection/php_reflection.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 70c3f4f198369..5cf1d936faeed 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5199,7 +5199,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce; zend_fcall_info fci; zend_fcall_info_cache fcc; - zend_long flags = 0; + zend_long options = 0; ZEND_ASSERT(strategy == ZEND_LAZY_OBJECT_STRATEGY_GHOST || strategy == ZEND_LAZY_OBJECT_STRATEGY_PROXY); @@ -5211,20 +5211,19 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, Z_PARAM_OBJ_OF_CLASS(obj, ce) Z_PARAM_FUNC(fci, fcc) Z_PARAM_OPTIONAL - // TODO: check named param - Z_PARAM_LONG(flags) + Z_PARAM_LONG(options) ZEND_PARSE_PARAMETERS_END(); } else { ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_FUNC(fci, fcc) Z_PARAM_OPTIONAL - Z_PARAM_LONG(flags) + Z_PARAM_LONG(options) ZEND_PARSE_PARAMETERS_END(); obj = NULL; } - if (flags & ~ZEND_LAZY_OBJECT_USER_FLAGS) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Invalid flags"); + if (options & ~ZEND_LAZY_OBJECT_USER_FLAGS) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Invalid options"); RETURN_THROWS(); } @@ -5245,7 +5244,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, } obj = zend_object_make_lazy(obj, ce, &fci.function_name, &fcc, - strategy | flags); + strategy | options); if (!obj) { RETURN_THROWS(); From ed7d39ca8368097d167b3aaa2b462609ac16b8b5 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 16 Aug 2024 16:03:11 +0200 Subject: [PATCH 237/280] Update comment --- Zend/zend_lazy_objects.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index eee168b0afd70..4a35d35fedbae 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -22,7 +22,8 @@ * This is implemented by using the same fallback mechanism as __get and __set * magic methods that is triggered when an undefined property is accessed. * - * Execution of methods or virtual property hooks do not trigger initialization. + * Execution of methods or virtual property hooks do not trigger initialization + * until they access properties. * * A lazy object can be created via the Reflection API. The user specifies an * initializer function that is called when initialization is required. From 56d10dbb1088de5394652a308cba0fab294dabbf Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 16 Aug 2024 16:03:23 +0200 Subject: [PATCH 238/280] Add assertion --- Zend/zend_object_handlers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 97793bf597a8b..f26fd4311b571 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -153,6 +153,8 @@ ZEND_API HashTable *zend_get_properties_no_init(zend_object *zobj) return zobj->properties; } + ZEND_ASSERT(!zend_object_is_lazy(zobj)); + return zobj->handlers->get_properties(zobj); } From a509e91ee21e33abfc22b03122e8cfa72586c16e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 16 Aug 2024 16:03:37 +0200 Subject: [PATCH 239/280] Cleanup --- Zend/zend_object_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index f26fd4311b571..4ce9e21ca7c06 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1168,7 +1168,7 @@ found:; } Z_TRY_ADDREF_P(value); - variable_ptr = zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + variable_ptr = zend_hash_add_new(zend_std_get_properties(zobj), name, value); } } From e8d1b9da1a2bc6c2ed72710b2e25d4dbde24f847 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 16:27:22 +0200 Subject: [PATCH 240/280] Rename zend_object.flags --- Zend/zend_objects.c | 2 +- Zend/zend_types.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index bdfc2a814aa35..3c824702e95f8 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -32,7 +32,7 @@ static zend_always_inline void _zend_object_std_init(zend_object *object, zend_c GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT; object->ce = ce; - object->flags = 0; + object->extra_flags = 0; object->handlers = ce->default_object_handlers; object->properties = NULL; zend_objects_store_put(object); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index d6aec3a35b4bd..00c4b652988a5 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -556,7 +556,7 @@ typedef struct _HashTableIterator { struct _zend_object { zend_refcounted_h gc; uint32_t handle; // TODO: may be removed ??? - uint32_t flags; + uint32_t extra_flags; /* OBJ_EXTRA_FLAGS() */ zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; @@ -835,7 +835,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define IS_OBJ_LAZY (1U<<31) /* Virtual proxy or uninitialized Ghost */ #define IS_OBJ_LAZY_PROXY (1U<<30) /* Virtual proxy (may be initialized) */ -#define OBJ_EXTRA_FLAGS(obj) ((obj)->flags) +#define OBJ_EXTRA_FLAGS(obj) ((obj)->extra_flags) /* Fast class cache */ #define ZSTR_HAS_CE_CACHE(s) (GC_FLAGS(s) & IS_STR_CLASS_NAME_MAP_PTR) From d7bf62401ef51ceea0488be25f5487acb8b75e59 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 16:28:36 +0200 Subject: [PATCH 241/280] Rename zend_get_properties_no_init --- Zend/zend_builtin_functions.c | 2 +- Zend/zend_lazy_objects.c | 2 +- Zend/zend_object_handlers.c | 8 ++++---- Zend/zend_object_handlers.h | 2 +- ext/reflection/php_reflection.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 9b797880684f1..654ba7e7ea129 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -885,7 +885,7 @@ ZEND_FUNCTION(get_mangled_object_vars) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); - properties = zend_get_properties_no_init(obj); + properties = zend_get_properties_no_lazy_init(obj); if (!properties) { ZVAL_EMPTY_ARRAY(return_value); return; diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 4a35d35fedbae..84e26faccb418 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -665,7 +665,7 @@ HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp) } *is_temp = 0; - return zend_get_properties_no_init(object); + return zend_get_properties_no_lazy_init(object); } HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 4ce9e21ca7c06..345772fc2083a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -138,13 +138,13 @@ ZEND_API HashTable *zend_std_get_properties(zend_object *zobj) /* {{{ */ /* }}} */ /* Fetch properties HashTable without triggering lazy initialization */ -ZEND_API HashTable *zend_get_properties_no_init(zend_object *zobj) +ZEND_API HashTable *zend_get_properties_no_lazy_init(zend_object *zobj) { if (zobj->handlers->get_properties == zend_std_get_properties) { if (UNEXPECTED(zend_object_is_lazy_proxy(zobj) && zend_lazy_object_initialized(zobj))) { zend_object *instance = zend_lazy_object_get_instance(zobj); - return zend_get_properties_no_init(instance); + return zend_get_properties_no_lazy_init(instance); } if (!zobj->properties) { @@ -2379,7 +2379,7 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp } return ht; case ZEND_PROP_PURPOSE_ARRAY_CAST: - ht = zend_get_properties_no_init(obj); + ht = zend_get_properties_no_lazy_init(obj); if (ht) { GC_TRY_ADDREF(ht); } @@ -2387,7 +2387,7 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp case ZEND_PROP_PURPOSE_SERIALIZE: { if (zend_object_is_lazy(obj) && !zend_lazy_object_initialize_on_serialize(obj)) { - ht = zend_get_properties_no_init(obj); + ht = zend_get_properties_no_lazy_init(obj); } else { ht = obj->handlers->get_properties(obj); } diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index c84f13f4411a7..e392aefbfd5cb 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -253,7 +253,7 @@ ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zen ZEND_API zend_function *zend_std_get_constructor(zend_object *object); ZEND_API struct _zend_property_info *zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent); ZEND_API HashTable *zend_std_get_properties(zend_object *object); -ZEND_API HashTable *zend_get_properties_no_init(zend_object *zobj); +ZEND_API HashTable *zend_get_properties_no_lazy_init(zend_object *zobj); ZEND_API HashTable *zend_std_get_gc(zend_object *object, zval **table, int *n); ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp); ZEND_API zend_result zend_std_cast_object_tostring(zend_object *object, zval *writeobj, int type); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5cf1d936faeed..a45c78d64e85d 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -478,7 +478,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char smart_str_append_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - HashTable *properties = zend_get_properties_no_init(Z_OBJ_P(obj)); + HashTable *properties = zend_get_properties_no_lazy_init(Z_OBJ_P(obj)); zend_string *prop_name; smart_str prop_str = {0}; From f70412c281ca57f67b031c312798f1d90465e535 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 16:33:11 +0200 Subject: [PATCH 242/280] De-dup --- ext/standard/var.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/ext/standard/var.c b/ext/standard/var.c index 479412de4aea2..8db4b2d755445 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -88,6 +88,18 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze } /* }}} */ +static const char *php_var_dump_object_prefix(zend_object *obj) { + if (EXPECTED(!zend_object_is_lazy(obj))) { + return ""; + } + + if (zend_object_is_lazy_proxy(obj)) { + return "lazy proxy "; + } + + return "lazy ghost "; +} + PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ { HashTable *myht; @@ -165,17 +177,7 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - - const char *prefix; - if (zend_object_is_lazy(Z_OBJ_P(struc))) { - if (zend_object_is_lazy_proxy(Z_OBJ_P(struc))) { - prefix = "lazy proxy "; - } else { - prefix = "lazy ghost "; - } - } else { - prefix = ""; - } + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); zend_string_release_ex(class_name, 0); @@ -374,17 +376,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - - const char *prefix; - if (zend_object_is_lazy(Z_OBJ_P(struc))) { - if (zend_object_is_lazy_proxy(Z_OBJ_P(struc))) { - prefix = "lazy proxy "; - } else { - prefix = "lazy ghost "; - } - } else { - prefix = ""; - } + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc)); zend_string_release_ex(class_name, 0); From 89c86562d7b504291db104c8fb637bc27a9f6c8e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 16:47:50 +0200 Subject: [PATCH 243/280] Do not serialize as N; --- ext/standard/var.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/var.c b/ext/standard/var.c index 8db4b2d755445..14af705b6331f 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1232,7 +1232,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ && zend_lazy_object_initialize_on_serialize(Z_OBJ_P(struc))) { obj = zend_lazy_object_init(Z_OBJ_P(struc)); if (!obj) { - smart_str_appendl(buf, "N;", 2); + ZEND_ASSERT(EG(exception)); return; } } From c9eec207875c71ae252bf7430d8d3a11efda103e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 16:48:03 +0200 Subject: [PATCH 244/280] WS / naming --- ext/reflection/php_reflection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a45c78d64e85d..71de41937ce80 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5259,7 +5259,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, PHP_METHOD(ReflectionClass, newLazyGhost) { reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, - ZEND_LAZY_OBJECT_STRATEGY_GHOST, /*is_make_lazy */ false); + ZEND_LAZY_OBJECT_STRATEGY_GHOST, /* is_reset */ false); } /* }}} */ @@ -5267,7 +5267,7 @@ PHP_METHOD(ReflectionClass, newLazyGhost) PHP_METHOD(ReflectionClass, newLazyProxy) { reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, - ZEND_LAZY_OBJECT_STRATEGY_PROXY, /*is_make_lazy */ false); + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /* is_reset */ false); } /* }}} */ @@ -5283,7 +5283,7 @@ PHP_METHOD(ReflectionClass, resetAsLazyGhost) PHP_METHOD(ReflectionClass, resetAsLazyProxy) { reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, - ZEND_LAZY_OBJECT_STRATEGY_PROXY, /*is_reset */ true); + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /* is_reset */ true); } /* }}} */ From 07331a48f79563ad044e1a665d2e4e33d795da99 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:29:53 +0200 Subject: [PATCH 245/280] Use zend_argument_error --- Zend/tests/lazy_objects/invalid_options.phpt | 43 ++++++++++++++++++++ ext/reflection/php_reflection.c | 4 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/lazy_objects/invalid_options.phpt diff --git a/Zend/tests/lazy_objects/invalid_options.phpt b/Zend/tests/lazy_objects/invalid_options.phpt new file mode 100644 index 0000000000000..97b938c51a7a8 --- /dev/null +++ b/Zend/tests/lazy_objects/invalid_options.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: invalid options +--FILE-- +newLazyGhost(function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +try { + $obj = $reflector->newLazyProxy(function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +$obj = new C(); + +try { + $reflector->resetAsLazyGhost($obj, function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +try { + $reflector->resetAsLazyProxy($obj, function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECT-- +ReflectionException: ReflectionClass::newLazyGhost(): Argument #2 ($options) contains invalid flags +ReflectionException: ReflectionClass::newLazyProxy(): Argument #2 ($options) contains invalid flags +ReflectionException: ReflectionClass::resetAsLazyGhost(): Argument #3 ($options) contains invalid flags +ReflectionException: ReflectionClass::resetAsLazyProxy(): Argument #3 ($options) contains invalid flags diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 71de41937ce80..c0436a7c17925 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5223,7 +5223,9 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, } if (options & ~ZEND_LAZY_OBJECT_USER_FLAGS) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Invalid options"); + uint32_t arg_num = 2 + is_reset; + zend_argument_error(reflection_exception_ptr, arg_num, + "contains invalid flags"); RETURN_THROWS(); } From 2c740fd0bd28ce263bb6ed8c8c606a955f9614ce Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:41:13 +0200 Subject: [PATCH 246/280] De-dup --- Zend/zend_API.c | 2 +- Zend/zend_compile.h | 9 ++++++++- Zend/zend_lazy_objects.c | 18 ++++++++---------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 1d10f61e62175..aa6e15b633334 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1795,7 +1795,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) * calling zend_merge_properties(). */ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties) /* {{{ */ { - if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) { + if (UNEXPECTED(class_type->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { if (class_type->ce_flags & ZEND_ACC_INTERFACE) { zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(class_type->name)); } else if (class_type->ce_flags & ZEND_ACC_TRAIT) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 92a31764a89f8..0f7c39676c614 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -398,7 +398,6 @@ typedef struct _zend_oparray_context { /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ - #define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE) #define ZEND_ACC_PPP_SET_MASK (ZEND_ACC_PUBLIC_SET | ZEND_ACC_PROTECTED_SET | ZEND_ACC_PRIVATE_SET) @@ -418,6 +417,14 @@ static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t vi /* call through internal function handler. e.g. Closure::invoke() */ #define ZEND_ACC_CALL_VIA_HANDLER ZEND_ACC_CALL_VIA_TRAMPOLINE +#define ZEND_ACC_UNINSTANTIABLE ( \ + ZEND_ACC_INTERFACE | \ + ZEND_ACC_TRAIT | \ + ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | \ + ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | \ + ZEND_ACC_ENUM \ +) + #define ZEND_SHORT_CIRCUITING_CHAIN_MASK 0x3 #define ZEND_SHORT_CIRCUITING_CHAIN_EXPR 0 #define ZEND_SHORT_CIRCUITING_CHAIN_ISSET 1 diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 84e26faccb418..4ac7a2dcc817b 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -207,18 +207,16 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, int lazy_properties_count = 0; if (!obj) { - zval zobj; - if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) { - /* Slow path: use object_init_ex() */ - if (object_init_ex(&zobj, ce) == FAILURE) { - ZEND_ASSERT(EG(exception)); - return NULL; - } - obj = Z_OBJ(zobj); - } else { - obj = zend_objects_new(ce); + if (UNEXPECTED(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { + zval zobj; + /* Call object_init_ex() for the generated exception */ + zend_result result = object_init_ex(&zobj, ce); + ZEND_ASSERT(result == FAILURE && EG(exception)); + return NULL; } + obj = zend_objects_new(ce); + for (int i = 0; i < obj->ce->default_properties_count; i++) { zval *p = &obj->properties_table[i]; ZVAL_UNDEF(p); From 6f0a92728c3492aae6ca2eb56ac25c65e57fa01a Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:43:40 +0200 Subject: [PATCH 247/280] Improve naming: rename ce to reflection_ce --- Zend/zend_lazy_objects.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 4ac7a2dcc817b..6050f0c06c052 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -178,9 +178,9 @@ bool zend_lazy_object_decr_lazy_props(zend_object *obj) */ /* Make object 'obj' lazy. If 'obj' is NULL, create a lazy instance of - * class 'class_type' */ + * class 'reflection_ce' */ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, - zend_class_entry *ce, zval *initializer_zv, + zend_class_entry *reflection_ce, zval *initializer_zv, zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags) { ZEND_ASSERT(!(flags & ~(ZEND_LAZY_OBJECT_USER_FLAGS|ZEND_LAZY_OBJECT_STRATEGY_FLAGS))); @@ -188,18 +188,18 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, || (flags & ZEND_LAZY_OBJECT_STRATEGY_FLAGS) == ZEND_LAZY_OBJECT_STRATEGY_PROXY); ZEND_ASSERT(!obj || (!zend_object_is_lazy(obj) || zend_lazy_object_initialized(obj))); - ZEND_ASSERT(!obj || instanceof_function(obj->ce, ce)); + ZEND_ASSERT(!obj || instanceof_function(obj->ce, reflection_ce)); /* Internal classes are not supported */ - if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) { - zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s is internal", ZSTR_VAL(ce->name)); + if (UNEXPECTED(reflection_ce->type == ZEND_INTERNAL_CLASS && reflection_ce != zend_standard_class_def)) { + zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s is internal", ZSTR_VAL(reflection_ce->name)); return NULL; } - for (zend_class_entry *parent = ce->parent; parent; parent = parent->parent) { + for (zend_class_entry *parent = reflection_ce->parent; parent; parent = parent->parent) { if (UNEXPECTED(parent->type == ZEND_INTERNAL_CLASS && parent != zend_standard_class_def)) { zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s inherits internal class %s", - ZSTR_VAL(ce->name), ZSTR_VAL(parent->name)); + ZSTR_VAL(reflection_ce->name), ZSTR_VAL(parent->name)); return NULL; } } @@ -207,15 +207,15 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, int lazy_properties_count = 0; if (!obj) { - if (UNEXPECTED(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { + if (UNEXPECTED(reflection_ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { zval zobj; /* Call object_init_ex() for the generated exception */ - zend_result result = object_init_ex(&zobj, ce); + zend_result result = object_init_ex(&zobj, reflection_ce); ZEND_ASSERT(result == FAILURE && EG(exception)); return NULL; } - obj = zend_objects_new(ce); + obj = zend_objects_new(reflection_ce); for (int i = 0; i < obj->ce->default_properties_count; i++) { zval *p = &obj->properties_table[i]; @@ -253,7 +253,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, obj->properties = NULL; /* unset() declared properties */ - for (int i = 0; i < ce->default_properties_count; i++) { + for (int i = 0; i < reflection_ce->default_properties_count; i++) { zend_property_info *prop_info = obj->ce->properties_info_table[i]; if (EXPECTED(prop_info)) { zval *p = &obj->properties_table[i]; From 3a3b755f8cef1cce4b454d655930b917180beb5e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:46:10 +0200 Subject: [PATCH 248/280] RETURN_THROWS / RETURN_NULL --- ext/reflection/php_reflection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c0436a7c17925..e3d48306568af 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5353,7 +5353,7 @@ ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized) if (zend_lazy_object_initialized(object)) { RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); } else { - ZEND_ASSERT(EG(exception)); + RETURN_THROWS(); } } /* }}} */ @@ -5373,7 +5373,7 @@ ZEND_METHOD(ReflectionClass, getLazyInitializer) if (!zend_object_is_lazy(object) || zend_lazy_object_initialized(object)) { - return; + RETURN_NULL(); } RETURN_ZVAL(zend_lazy_object_get_initializer_zv(object), 1, 0); From 0e24294eff83bef61f400b97353fdfde807cdfb0 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:54:40 +0200 Subject: [PATCH 249/280] Fallback in case zend_std_write_property is overridden --- Zend/zend_lazy_objects.c | 16 ++++++++++++++++ Zend/zend_lazy_objects.h | 1 + ext/reflection/php_reflection.c | 24 ++++++++++++++---------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 6050f0c06c052..5b0e0ff4a856d 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -177,6 +177,22 @@ bool zend_lazy_object_decr_lazy_props(zend_object *obj) * Making objects lazy */ +ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce) +{ + /* Internal classes are not supported */ + if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) { + return false; + } + + for (zend_class_entry *parent = ce->parent; parent; parent = parent->parent) { + if (UNEXPECTED(parent->type == ZEND_INTERNAL_CLASS && parent != zend_standard_class_def)) { + return false; + } + } + + return true; +} + /* Make object 'obj' lazy. If 'obj' is NULL, create a lazy instance of * class 'reflection_ce' */ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index 87654b1396095..b7fd1a5140fb1 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -59,6 +59,7 @@ typedef struct _zend_lazy_objects_store { typedef struct _zend_fcall_info zend_fcall_info; typedef struct _zend_fcall_info_cache zend_fcall_info_cache; +ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce); ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, zend_class_entry *class_type, zval *initializer_zv, zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index e3d48306568af..a298b56b5627b 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6145,11 +6145,13 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) Z_PARAM_ZVAL(value) } ZEND_PARSE_PARAMETERS_END(); - if (object->handlers->write_property != zend_std_write_property) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use setRawValueWithoutLazyInitialization on internal class %s", - ZSTR_VAL(intern->ce->name)); - RETURN_THROWS(); + if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { + if (!zend_class_can_be_lazy(object->ce)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use setRawValueWithoutLazyInitialization on internal class %s", + ZSTR_VAL(intern->ce->name)); + RETURN_THROWS(); + } } ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); @@ -6218,11 +6220,13 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) Z_PARAM_OBJ_OF_CLASS(object, intern->ce) } ZEND_PARSE_PARAMETERS_END(); - if (object->handlers->write_property != zend_std_write_property) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use skipLazyInitialization on internal class %s", - ZSTR_VAL(intern->ce->name)); - RETURN_THROWS(); + if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { + if (!zend_class_can_be_lazy(object->ce)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use skipLazyInitialization on internal class %s", + ZSTR_VAL(intern->ce->name)); + RETURN_THROWS(); + } } ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); From 2a57a75375fb1d42826e043c708b4fb4563ac2c1 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 17:56:33 +0200 Subject: [PATCH 250/280] Remove unreachable condition --- ext/reflection/php_reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a298b56b5627b..4996f54339d31 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6162,7 +6162,7 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) /* Do not trigger initialization */ Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_LAZY; - if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + if (!ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); } else { zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); From d92db6e85c769556e12a681086e3a6b4071cf545 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:01:22 +0200 Subject: [PATCH 251/280] Extract common logic for setRawValue / setRawValueWithoutLazyInitialization --- ext/reflection/php_reflection.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 4996f54339d31..a71bc335ba1cc 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6083,6 +6083,16 @@ ZEND_METHOD(ReflectionProperty, getRawValue) } } +static void reflection_property_set_raw_value(property_reference *ref, reflection_object *intern, zend_object *object, zval *value) +{ + if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); + } else { + zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); + zend_call_known_instance_method_with_1_params(func, object, NULL, value); + } +} + ZEND_METHOD(ReflectionProperty, setRawValue) { reflection_object *intern; @@ -6101,12 +6111,7 @@ ZEND_METHOD(ReflectionProperty, setRawValue) RETURN_THROWS(); } - if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_update_property_ex(intern->ce, Z_OBJ_P(object), ref->unmangled_name, value); - } else { - zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); - zend_call_known_instance_method_with_1_params(func, Z_OBJ_P(object), NULL, value); - } + reflection_property_set_raw_value(ref, intern, Z_OBJ_P(object), value); } /* {{{ Set property value withtout triggering initializer while skipping hooks if any */ @@ -6162,12 +6167,7 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) /* Do not trigger initialization */ Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_LAZY; - if (!ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); - } else { - zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); - zend_call_known_instance_method_with_1_params(func, object, NULL, value); - } + reflection_property_set_raw_value(ref, intern, object, value); /* Mark property as lazy again if an exception prevented update */ if (EG(exception) && Z_TYPE_P(var_ptr) == IS_UNDEF From 81bfdb1475056fc032dc1ce4029f6b834911b327 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:12:15 +0200 Subject: [PATCH 252/280] Do not set prop as lazy after setRawValueWithoutLazyInitialization failure, if it was not originally lazy --- ...houtLazyInitialization_exception_001.phpt} | 0 ...thoutLazyInitialization_exception_002.phpt | 60 +++++++++++++++++++ ext/reflection/php_reflection.c | 2 +- 3 files changed, 61 insertions(+), 1 deletion(-) rename Zend/tests/lazy_objects/{setRawValueWithoutLazyInitialization_exception.phpt => setRawValueWithoutLazyInitialization_exception_001.phpt} (100%) create mode 100644 Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_001.phpt similarity index 100% rename from Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception.phpt rename to Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_001.phpt diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt new file mode 100644 index 0000000000000..40221269893bd --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() leaves non-lazy properties as non-lazy in case of exception +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + try { + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Prop is still non-lazy: This does not trigger initialization + $obj->a = 1; + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + throw new Exception('Unreachable'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new Exception('Unreachable'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +TypeError: Cannot assign stdClass to property C::$a of type int +bool(true) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) + ["b"]=> + uninitialized(int) +} +# Proxy +TypeError: Cannot assign stdClass to property C::$a of type int +bool(true) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) + ["b"]=> + uninitialized(int) +} diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a71bc335ba1cc..8ca80e19c455e 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6170,7 +6170,7 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) reflection_property_set_raw_value(ref, intern, object, value); /* Mark property as lazy again if an exception prevented update */ - if (EG(exception) && Z_TYPE_P(var_ptr) == IS_UNDEF + if (EG(exception) && prop_was_lazy && Z_TYPE_P(var_ptr) == IS_UNDEF && zend_object_is_lazy(object) && !zend_lazy_object_initialized(object)) { Z_PROP_FLAG_P(var_ptr) |= IS_PROP_LAZY; From eace7108b9b2267a99e60b8554e2c6e104471767 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:20:54 +0200 Subject: [PATCH 253/280] Extract common logic between setRawValueWithoutLazyInitialization / skipLazyInitialization --- ext/reflection/php_reflection.c | 99 ++++++++++++++------------------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 8ca80e19c455e..32f129e5e7547 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6114,53 +6114,67 @@ ZEND_METHOD(ReflectionProperty, setRawValue) reflection_property_set_raw_value(ref, intern, Z_OBJ_P(object), value); } -/* {{{ Set property value withtout triggering initializer while skipping hooks if any */ -ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +static zend_result reflection_property_check_lazy_compatible(reflection_object *intern, + property_reference *ref, zend_object *object, const char *method) { - reflection_object *intern; - property_reference *ref; - zend_object *object; - zval *value; - - GET_REFLECTION_OBJECT_PTR(ref); - if (!ref->prop) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use setRawValueWithoutLazyInitialization on dynamic property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); + "Can not use %s on dynamic property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; } if (ref->prop->flags & ZEND_ACC_STATIC) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use setRawValueWithoutLazyInitialization on static property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); + "Can not use %s on static property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; } if (ref->prop->flags & ZEND_ACC_VIRTUAL) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use setRawValueWithoutLazyInitialization on virtual property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); + "Can not use %s on virtual property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; } - ZEND_PARSE_PARAMETERS_START(2, 2) { - Z_PARAM_OBJ_OF_CLASS(object, intern->ce) - Z_PARAM_ZVAL(value) - } ZEND_PARSE_PARAMETERS_END(); - if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { if (!zend_class_can_be_lazy(object->ce)) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use setRawValueWithoutLazyInitialization on internal class %s", - ZSTR_VAL(intern->ce->name)); - RETURN_THROWS(); + "Can not use %s on internal class %s", + method, ZSTR_VAL(intern->ce->name)); + return FAILURE; } } ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); + return SUCCESS; +} + +/* {{{ Set property value withtout triggering initializer while skipping hooks if any */ +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +{ + reflection_object *intern; + property_reference *ref; + zend_object *object; + zval *value; + + GET_REFLECTION_OBJECT_PTR(ref); + + ZEND_PARSE_PARAMETERS_START(2, 2) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + Z_PARAM_ZVAL(value) + } ZEND_PARSE_PARAMETERS_END(); + + if (reflection_property_check_lazy_compatible(intern, ref, object, + "setRawValueWithoutLazyInitialization") == FAILURE) { + RETURN_THROWS(); + } + zval *var_ptr = OBJ_PROP(object, ref->prop->offset); bool prop_was_lazy = Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY; @@ -6195,42 +6209,15 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) GET_REFLECTION_OBJECT_PTR(ref); - if (!ref->prop) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use skipLazyInitialization on dynamic property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - - if (ref->prop->flags & ZEND_ACC_STATIC) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use skipLazyInitialization on static property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - - if (ref->prop->flags & ZEND_ACC_VIRTUAL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use skipLazyInitialization on virtual property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - ZEND_PARSE_PARAMETERS_START(1, 1) { Z_PARAM_OBJ_OF_CLASS(object, intern->ce) } ZEND_PARSE_PARAMETERS_END(); - if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { - if (!zend_class_can_be_lazy(object->ce)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use skipLazyInitialization on internal class %s", - ZSTR_VAL(intern->ce->name)); - RETURN_THROWS(); - } + if (reflection_property_check_lazy_compatible(intern, ref, object, + "skipLazyInitialization") == FAILURE) { + RETURN_THROWS(); } - ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); - bool prop_was_lazy = (Z_PROP_FLAG_P(OBJ_PROP(object, ref->prop->offset)) & IS_PROP_LAZY); zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; From db0bf616c2f87ebeb01398aff615f38e5402b2d5 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:26:59 +0200 Subject: [PATCH 254/280] Use ZVAL_COPY_PROP --- ext/reflection/php_reflection.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 32f129e5e7547..fa149a36a02b9 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6230,8 +6230,7 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) ZEND_ASSERT(Z_TYPE_P(dst) == IS_UNDEF && "Lazy property should be UNDEF"); - ZVAL_COPY_OR_DUP_PROP(dst, src); - Z_PROP_FLAG_P(dst) &= ~(IS_PROP_LAZY | IS_PROP_REINITABLE); + ZVAL_COPY_PROP(dst, src); /* Object becomes non-lazy if this was the last lazy prop */ if (prop_was_lazy && zend_object_is_lazy(object) From e5af928a635d8a939812c987a5f3e6b3f81727fb Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:39:10 +0200 Subject: [PATCH 255/280] Add comment / extract logic --- Zend/zend_object_handlers.h | 13 +++++++++++++ Zend/zend_operators.c | 5 +---- Zend/zend_vm_def.h | 5 +---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index e392aefbfd5cb..418a93de3ccd2 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -290,6 +290,19 @@ static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *obj /* Implements the fast path for array cast */ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj); +#define ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(object) ( \ + /* We can use zend_std_build_object_properties_array() for objects \ + * without properties ht and with standard handlers */ \ + Z_OBJ_P(object)->properties == NULL \ + && Z_OBJ_HT_P(object)->get_properties_for == NULL \ + && Z_OBJ_HT_P(object)->get_properties == zend_std_get_properties \ + /* For initialized proxies we need to forward to the real instance */ \ + && ( \ + !zend_object_is_lazy_proxy(Z_OBJ_P(object)) \ + || !zend_lazy_object_initialized(Z_OBJ_P(object)) \ + ) \ +) + /* Handler for objects that cannot be meaningfully compared. * Only objects with the same identity will be considered equal. */ ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index a3446bdcc4a99..ae75e95a71c1d 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -812,10 +812,7 @@ ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */ case IS_OBJECT: if (Z_OBJCE_P(op) == zend_ce_closure) { convert_scalar_to_array(op); - } else if (Z_OBJ_P(op)->properties == NULL - && Z_OBJ_HT_P(op)->get_properties_for == NULL - && Z_OBJ_HT_P(op)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(op)) && !zend_lazy_object_initialized(Z_OBJ_P(op)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(op)) { /* Optimized version without rebuilding properties HashTable */ HashTable *ht = zend_std_build_object_properties_array(Z_OBJ_P(op)); OBJ_RELEASE(Z_OBJ_P(op)); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 772bc27869121..49bdd99189838 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6429,10 +6429,7 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { From 7b4545fee49f6f1c4906419c9b24b386d0cc6690 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:50:21 +0200 Subject: [PATCH 256/280] Add test --- Zend/tests/lazy_objects/convert_to_array.phpt | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Zend/tests/lazy_objects/convert_to_array.phpt diff --git a/Zend/tests/lazy_objects/convert_to_array.phpt b/Zend/tests/lazy_objects/convert_to_array.phpt new file mode 100644 index 0000000000000..72eb3fd4f670e --- /dev/null +++ b/Zend/tests/lazy_objects/convert_to_array.phpt @@ -0,0 +1,93 @@ +--TEST-- +Lazy objects: Convertion to array +--FILE-- +a = 1; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 3); + + $a = []; + // Converts $obj to array internally + array_splice($a, 0, 0, $obj); + var_dump($a, $obj); + + $reflector->initializeLazyObject($obj); + + $a = []; + array_splice($a, 0, 0, $obj); + var_dump($a, $obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +array(1) { + [0]=> + int(3) +} +lazy ghost object(C)#%d (1) { + ["a"]=> + int(3) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy +array(1) { + [0]=> + int(3) +} +lazy proxy object(C)#%d (1) { + ["a"]=> + int(3) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} From 8415e9d611f7ef9f9bbd6e0be40e0ef776f80bd8 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:53:13 +0200 Subject: [PATCH 257/280] Rename IS_OBJ_LAZY -> IS_OBJ_LAZY_UNINITIALIZED --- Zend/zend_lazy_objects.c | 28 ++++++++++++++-------------- Zend/zend_lazy_objects.h | 4 ++-- Zend/zend_types.h | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 5b0e0ff4a856d..0bd1c73bfb0fa 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -95,7 +95,7 @@ void zend_lazy_objects_destroy(zend_lazy_objects_store *store) void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) { - ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY)); + ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); ZEND_ASSERT(zv); @@ -103,7 +103,7 @@ void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) { - ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY)); + ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); zend_lazy_object_info *info = zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); ZEND_ASSERT(info); @@ -246,7 +246,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, } else { if (zend_object_is_lazy(obj)) { ZEND_ASSERT(zend_object_is_lazy_proxy(obj) && zend_lazy_object_initialized(obj)); - OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); zend_lazy_object_del_info(obj); } else if (!(flags & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) && !(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { @@ -294,7 +294,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, return obj; } - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED; if (flags & ZEND_LAZY_OBJECT_STRATEGY_PROXY) { OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_PROXY; @@ -335,7 +335,7 @@ ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj) zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce); zval *properties_table = obj->properties_table; - OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); for (int i = 0; i < ce->default_properties_count; i++) { if (Z_PROP_FLAG_P(&properties_table[i]) & IS_PROP_LAZY) { @@ -385,7 +385,7 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl obj->properties = NULL; } - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED; } static bool zend_lazy_object_compatible(zend_object *real_object, zend_object *lazy_object) @@ -418,7 +418,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) zend_lazy_object_info *info = zend_lazy_object_get_info(obj); /* prevent reentrant initialization */ - OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); /* Call factory */ zval retval; @@ -432,12 +432,12 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params); if (UNEXPECTED(EG(exception))) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; return NULL; } if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT || !zend_lazy_object_compatible(Z_OBJ(retval), obj))) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; zend_type_error("The real instance class %s is not compatible with the proxy class %s. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.", zend_zval_value_name(&retval), ZSTR_VAL(obj->ce->name)); @@ -446,7 +446,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) } if (UNEXPECTED(Z_OBJ(retval) == obj || zend_object_is_lazy(Z_OBJ(retval)))) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); zval_ptr_dtor(&retval); return NULL; @@ -458,7 +458,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) zend_object *clone = Z_OBJ_HT(retval)->clone_obj(Z_OBJ(retval)); if (EG(exception)) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; zval_ptr_dtor(&retval); OBJ_RELEASE(clone); return NULL; @@ -467,7 +467,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) ZEND_ASSERT(zend_lazy_object_compatible(clone, obj)); if (zend_object_is_lazy(clone)) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY|IS_OBJ_LAZY_PROXY; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); zval_ptr_dtor(&retval); return NULL; @@ -533,7 +533,7 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) zend_fcall_info_cache *initializer = zend_lazy_object_get_initializer_fcc(obj); /* Prevent reentrant initialization */ - OBJ_EXTRA_FLAGS(obj) &= ~IS_OBJ_LAZY; + OBJ_EXTRA_FLAGS(obj) &= ~IS_OBJ_LAZY_UNINITIALIZED; /* Snapshot dynamic properties */ HashTable *properties_snapshot = obj->properties; @@ -614,7 +614,7 @@ void zend_lazy_object_realize(zend_object *obj) } #endif - OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY | IS_OBJ_LAZY_PROXY); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY); } /* Initialize object and clone it. For proxies, we clone both the proxy and its diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index b7fd1a5140fb1..f042b056980df 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -81,7 +81,7 @@ void zend_lazy_object_realize(zend_object *obj); static zend_always_inline bool zend_object_is_lazy(zend_object *obj) { - return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY | IS_OBJ_LAZY_PROXY)); + return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY)); } static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj) @@ -91,7 +91,7 @@ static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj) static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj) { - return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY); + return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_UNINITIALIZED); } /* True if accessing a lazy prop on obj mandates a call to diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 00c4b652988a5..8f012868ddab4 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -832,7 +832,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { /* object extra flags (zend_object.flags) */ -#define IS_OBJ_LAZY (1U<<31) /* Virtual proxy or uninitialized Ghost */ +#define IS_OBJ_LAZY_UNINITIALIZED (1U<<31) /* Virtual proxy or uninitialized Ghost */ #define IS_OBJ_LAZY_PROXY (1U<<30) /* Virtual proxy (may be initialized) */ #define OBJ_EXTRA_FLAGS(obj) ((obj)->extra_flags) From e85595c5b304a443d9f8a5cd0994847b7444853e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 18:54:19 +0200 Subject: [PATCH 258/280] Early return --- Zend/zend_objects.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 3c824702e95f8..348b3f3416b91 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -309,20 +309,20 @@ ZEND_API zend_object *zend_objects_clone_obj(zend_object *old_object) if (UNEXPECTED(zend_object_is_lazy(old_object))) { return zend_lazy_object_clone(old_object); - } else { - /* assume that create isn't overwritten, so when clone depends on the - * overwritten one then it must itself be overwritten */ - new_object = zend_objects_new(old_object->ce); - - /* zend_objects_clone_members() expect the properties to be initialized. */ - if (new_object->ce->default_properties_count) { - zval *p = new_object->properties_table; - zval *end = p + new_object->ce->default_properties_count; - do { - ZVAL_UNDEF(p); - p++; - } while (p != end); - } + } + + /* assume that create isn't overwritten, so when clone depends on the + * overwritten one then it must itself be overwritten */ + new_object = zend_objects_new(old_object->ce); + + /* zend_objects_clone_members() expect the properties to be initialized. */ + if (new_object->ce->default_properties_count) { + zval *p = new_object->properties_table; + zval *end = p + new_object->ce->default_properties_count; + do { + ZVAL_UNDEF(p); + p++; + } while (p != end); } zend_objects_clone_members(new_object, old_object); From bf20f0a91d713caabc430df4ba879a558a5cbd16 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 19:10:55 +0200 Subject: [PATCH 259/280] Fix null pointer deref --- Zend/tests/lazy_objects/get_properties.phpt | 27 +++++++++++++++++++++ Zend/zend_object_handlers.h | 6 +++-- 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/lazy_objects/get_properties.phpt diff --git a/Zend/tests/lazy_objects/get_properties.phpt b/Zend/tests/lazy_objects/get_properties.phpt new file mode 100644 index 0000000000000..38b752c2f8b5b --- /dev/null +++ b/Zend/tests/lazy_objects/get_properties.phpt @@ -0,0 +1,27 @@ +--TEST-- +Lazy objects: get_properties failure +--FILE-- +newLazyProxy(function () { + throw new \Exception('Initializer'); +}); + +$b = new C(); + +try { + var_dump($a > $b); +} catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECT-- +Exception: Initializer diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 418a93de3ccd2..add97f47c0ef1 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -276,10 +276,12 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { if (UNEXPECTED(zend_lazy_object_must_init(object))) { - object = zend_lazy_object_init(object); - if (UNEXPECTED(!object)) { + zend_object *tmp = zend_lazy_object_init(object); + if (UNEXPECTED(!tmp)) { + ZEND_ASSERT(!object->properties || object->properties == &zend_empty_array); return object->properties = (zend_array*) &zend_empty_array; } + object = tmp; } if (!object->properties) { return rebuild_object_properties_internal(object); From f8867263447f6118a2548036e0fa90d7416cb885 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 19:11:17 +0200 Subject: [PATCH 260/280] Fix comparison of lazy objects --- .../lazy_objects/init_trigger_compare.phpt | 54 +++++++++++++++++++ Zend/zend_object_handlers.c | 3 +- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/lazy_objects/init_trigger_compare.phpt diff --git a/Zend/tests/lazy_objects/init_trigger_compare.phpt b/Zend/tests/lazy_objects/init_trigger_compare.phpt new file mode 100644 index 0000000000000..bebd5e9c5f0c7 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_compare.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: comparison initializes object +--FILE-- +newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +$b = $reflector->newLazyProxy(function ($obj) { + return new C(); +}); + +var_dump($a > $b); + +$a = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +$b = $reflector->newLazyProxy(function ($obj) { + return new C(); +}); + +var_dump($a == $b); + +$a = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +var_dump('A' < $a); +?> +--EXPECT-- +string(14) "C::__construct" +string(14) "C::__construct" +bool(false) +string(14) "C::__construct" +string(14) "C::__construct" +bool(true) +bool(true) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 345772fc2083a..91cea49220842 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -2072,7 +2072,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ if (zobj1->ce != zobj2->ce) { return ZEND_UNCOMPARABLE; /* different classes */ } - if (!zobj1->properties && !zobj2->properties) { + if (!zobj1->properties && !zobj2->properties + && !zend_object_is_lazy(zobj1) && !zend_object_is_lazy(zobj2)) { zend_property_info *info; int i; From f8df7ae136166ba755fdff5a2b7974b7560dfca0 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 19:58:59 +0200 Subject: [PATCH 261/280] Skip zend_std_get_properties() --- Zend/zend_object_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 91cea49220842..8a973f4fc0927 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1384,7 +1384,7 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { zend_error(E_WARNING, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); } - retval = zend_hash_add(zend_std_get_properties(zobj), name, &EG(uninitialized_zval)); + retval = zend_hash_add(zobj->properties, name, &EG(uninitialized_zval)); } } else if (!IS_HOOKED_PROPERTY_OFFSET(property_offset) && zobj->ce->__get == NULL) { retval = &EG(error_zval); From 23e1a4bb6b1cb1678cad0c1e2672d4b7ef6094b9 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 20:00:49 +0200 Subject: [PATCH 262/280] Remove dead code for clone handling --- Zend/zend_lazy_objects.c | 25 ------------------------- Zend/zend_lazy_objects.h | 3 --- 2 files changed, 28 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 0bd1c73bfb0fa..0472e826a50bb 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -452,31 +452,6 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) return NULL; } - if (info->flags & ZEND_LAZY_OBJECT_CLONE) { - /* For uninitialized lazy proxies, cloning of the real instance is - * postponed until initialization */ - - zend_object *clone = Z_OBJ_HT(retval)->clone_obj(Z_OBJ(retval)); - if (EG(exception)) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; - zval_ptr_dtor(&retval); - OBJ_RELEASE(clone); - return NULL; - } - - ZEND_ASSERT(zend_lazy_object_compatible(clone, obj)); - - if (zend_object_is_lazy(clone)) { - OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; - zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); - zval_ptr_dtor(&retval); - return NULL; - } - - zval_ptr_dtor(&retval); - ZVAL_OBJ(&retval, clone); - } - zend_fcc_dtor(&info->u.initializer.fcc); zval_ptr_dtor(&info->u.initializer.zv); info->u.instance = Z_OBJ(retval); diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index f042b056980df..d5eb20d7dcde7 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -36,9 +36,6 @@ /* Do not call destructor when making existing object lazy */ #define ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR (1<<4) -/* The object is a clone */ -#define ZEND_LAZY_OBJECT_CLONE (1<<5) - #define ZEND_LAZY_OBJECT_USER_FLAGS ( \ ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE | \ ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR \ From 33acce5591d28f98edb7fc51cb3eb25ee097815f Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 20:09:03 +0200 Subject: [PATCH 263/280] newLazy*() do not accept SKIP_DESTRUCTOR --- Zend/tests/lazy_objects/invalid_options.phpt | 8 ++++++++ ext/reflection/php_reflection.c | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Zend/tests/lazy_objects/invalid_options.phpt b/Zend/tests/lazy_objects/invalid_options.phpt index 97b938c51a7a8..96c965ec4175d 100644 --- a/Zend/tests/lazy_objects/invalid_options.phpt +++ b/Zend/tests/lazy_objects/invalid_options.phpt @@ -21,6 +21,13 @@ try { printf("%s: %s\n", $e::class, $e->getMessage()); } +try { + // SKIP_DESTRUCTOR is only allowed on resetAsLazyProxy() + $obj = $reflector->newLazyGhost(function ($obj) { }, ReflectionClass::SKIP_DESTRUCTOR); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + $obj = new C(); try { @@ -39,5 +46,6 @@ try { --EXPECT-- ReflectionException: ReflectionClass::newLazyGhost(): Argument #2 ($options) contains invalid flags ReflectionException: ReflectionClass::newLazyProxy(): Argument #2 ($options) contains invalid flags +ReflectionException: ReflectionClass::newLazyGhost(): Argument #2 ($options) does not accept ReflectionClass::SKIP_DESTRUCTOR ReflectionException: ReflectionClass::resetAsLazyGhost(): Argument #3 ($options) contains invalid flags ReflectionException: ReflectionClass::resetAsLazyProxy(): Argument #3 ($options) contains invalid flags diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index fa149a36a02b9..b5c62e006639a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5222,13 +5222,20 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, obj = NULL; } - if (options & ~ZEND_LAZY_OBJECT_USER_FLAGS) { + zend_long accepted_flags = ZEND_LAZY_OBJECT_USER_FLAGS; + if (options & ~accepted_flags) { uint32_t arg_num = 2 + is_reset; zend_argument_error(reflection_exception_ptr, arg_num, "contains invalid flags"); RETURN_THROWS(); } + if (!is_reset && options & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) { + zend_argument_error(reflection_exception_ptr, 2, + "does not accept ReflectionClass::SKIP_DESTRUCTOR"); + RETURN_THROWS(); + } + if (is_reset) { if (zend_object_is_lazy(obj) && !zend_lazy_object_initialized(obj)) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Object is already lazy"); From e25d16a9152b3a2fa1096275aa0e78e79cb79b56 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 20:59:15 +0200 Subject: [PATCH 264/280] Make functions static when possible --- Zend/zend_lazy_objects.c | 6 +++--- Zend/zend_lazy_objects.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 0472e826a50bb..8606d6aa9a93d 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -93,7 +93,7 @@ void zend_lazy_objects_destroy(zend_lazy_objects_store *store) zend_hash_destroy(&store->infos); } -void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) +static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) { ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); @@ -101,7 +101,7 @@ void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) ZEND_ASSERT(zv); } -zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) +static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) { ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); @@ -122,7 +122,7 @@ zval* zend_lazy_object_get_initializer_zv(zend_object *obj) return &info->u.initializer.zv; } -zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj) +static zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj) { ZEND_ASSERT(!zend_lazy_object_initialized(obj)); diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index d5eb20d7dcde7..a10e2205673a5 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -66,7 +66,6 @@ ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj); void zend_lazy_objects_init(zend_lazy_objects_store *store); void zend_lazy_objects_destroy(zend_lazy_objects_store *store); zval* zend_lazy_object_get_initializer_zv(zend_object *obj); -zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj); zend_object *zend_lazy_object_get_instance(zend_object *obj); zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); void zend_lazy_object_del_info(zend_object *obj); From a31e777e6113a0799a8e3f005f2a4e5e5594d131 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:00:17 +0200 Subject: [PATCH 265/280] Simplify assertions --- Zend/zend_lazy_objects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 8606d6aa9a93d..3b82b733d00cf 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -95,7 +95,7 @@ void zend_lazy_objects_destroy(zend_lazy_objects_store *store) static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) { - ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); + ZEND_ASSERT(zend_object_is_lazy(obj)); zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); ZEND_ASSERT(zv); @@ -103,7 +103,7 @@ static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *i static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) { - ZEND_ASSERT(OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY)); + ZEND_ASSERT(zend_object_is_lazy(obj)); zend_lazy_object_info *info = zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); ZEND_ASSERT(info); From 6cf649655d9705d2c48504dd7beb82fdc6ec5cb6 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:01:08 +0200 Subject: [PATCH 266/280] Prevent warning --- Zend/zend_lazy_objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 3b82b733d00cf..fb450a251d7a2 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -99,6 +99,7 @@ static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *i zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); ZEND_ASSERT(zv); + (void)zv; } static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) From 8841964146a6600bc5d4afacdcfb6cb853566f9b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:07:02 +0200 Subject: [PATCH 267/280] Check final property --- Zend/zend_lazy_objects.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index fb450a251d7a2..72e752c3de5a3 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -276,7 +276,8 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, zval *p = &obj->properties_table[i]; if (Z_TYPE_P(p) != IS_UNDEF) { if ((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(p) & IS_PROP_REINITABLE) - && (obj->ce->ce_flags & ZEND_ACC_FINAL)) { + /* TODO: test final property */ + && ((obj->ce->ce_flags & ZEND_ACC_FINAL) || (prop_info->flags & ZEND_ACC_FINAL))) { continue; } zend_object_dtor_property(obj, p); From 77fe4fc8cfd2729ab9eeddd32e3d0d8ffd77c635 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:08:53 +0200 Subject: [PATCH 268/280] Avoid redundant addref/delref --- Zend/zend_lazy_objects.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 72e752c3de5a3..75ba3de07efe0 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -362,8 +362,7 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl for (int i = 0; i < ce->default_properties_count; i++) { zval *p = &properties_table[i]; zend_object_dtor_property(obj, p); - ZVAL_COPY_PROP(p, &properties_table_snapshot[i]); - Z_TRY_DELREF_P(p); + ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[i]); zend_property_info *prop_info = ce->properties_info_table[i]; if (Z_ISREF_P(p) && prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { From d0c9e36acffc6e8d121a4d5e9b997b365995aeed Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:26:16 +0200 Subject: [PATCH 269/280] Prevent making object lazy during its initialization --- .../reset_as_lazy_while_init_exception.phpt | 57 +++++++++++++++++++ Zend/zend_lazy_objects.c | 32 ++++++++--- 2 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt diff --git a/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt new file mode 100644 index 0000000000000..756bad70621da --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: resetAsLazy*() on object being initialized +--FILE-- +resetAsLazyGhost($obj, function ($obj) use ($reflector) { + try { + $reflector->resetAsLazyGhost($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + try { + $reflector->resetAsLazyProxy($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + +}); +$reflector->initializeLazyObject($obj); + +printf("# Proxy:\n"); + +$obj = new C(); +$reflector->resetAsLazyProxy($obj, function ($obj) use ($reflector) { + try { + $reflector->resetAsLazyProxy($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + try { + $reflector->resetAsLazyGhost($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + return new C(); +}); +$reflector->initializeLazyObject($obj); + +?> +==DONE== +--EXPECT-- +# Ghost: +Error: Can not reset an object while it is being initialized +Error: Can not reset an object while it is being initialized +# Proxy: +Error: Can not reset an object while it is being initialized +Error: Can not reset an object while it is being initialized +==DONE== diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 75ba3de07efe0..861f8e2f8168a 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -112,6 +112,11 @@ static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) return info; } +static bool zend_lazy_object_has_stale_info(zend_object *obj) +{ + return zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); +} + zval* zend_lazy_object_get_initializer_zv(zend_object *obj) { ZEND_ASSERT(!zend_lazy_object_initialized(obj)); @@ -249,16 +254,23 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, ZEND_ASSERT(zend_object_is_lazy_proxy(obj) && zend_lazy_object_initialized(obj)); OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); zend_lazy_object_del_info(obj); - } else if (!(flags & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) + } else { + if (zend_lazy_object_has_stale_info(obj)) { + zend_throw_error(NULL, "Can not reset an object while it is being initialized"); + return NULL; + } + + if (!(flags & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) && !(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { - if (obj->handlers->dtor_obj != zend_objects_destroy_object - || obj->ce->destructor) { - GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); - GC_ADDREF(obj); - obj->handlers->dtor_obj(obj); - GC_DELREF(obj); - if (EG(exception)) { - return NULL; + if (obj->handlers->dtor_obj != zend_objects_destroy_object + || obj->ce->destructor) { + GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); + GC_ADDREF(obj); + obj->handlers->dtor_obj(obj); + GC_DELREF(obj); + if (EG(exception)) { + return NULL; + } } } } @@ -571,6 +583,8 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) zend_release_properties(properties_snapshot); } + /* Must be very last in this function, for the + * zend_lazy_object_has_stale_info() check */ zend_lazy_object_del_info(obj); return obj; From 9248c394ec4fffc33594070f8bbd136132327668 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 21:30:26 +0200 Subject: [PATCH 270/280] Improve error message --- .../initializer_must_return_the_right_type.phpt | 2 +- Zend/zend_lazy_objects.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt index dd68a88406eeb..7f796684e1bd8 100644 --- a/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt +++ b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt @@ -152,7 +152,7 @@ string(11) "initializer" TypeError: The real instance class DateTime is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. ## C vs NULL string(11) "initializer" -TypeError: The real instance class null is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +TypeError: Lazy proxy factory must return an instance of a class compatible with C, null returned ## C vs D string(11) "initializer" TypeError: The real instance class D is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 861f8e2f8168a..e0b300b14667c 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -449,6 +449,16 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) return NULL; } + if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT)) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; + zend_type_error("Lazy proxy factory must return an instance of a class compatible with %s, %s returned", + ZSTR_VAL(obj->ce->name), + zend_zval_value_name(&retval)); + zval_ptr_dtor(&retval); + return NULL; + + } + if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT || !zend_lazy_object_compatible(Z_OBJ(retval), obj))) { OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; zend_type_error("The real instance class %s is not compatible with the proxy class %s. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.", From 4a0eb5fce3e37f25be6fe261082c1ce86a974bfc Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 22:00:25 +0200 Subject: [PATCH 271/280] Fix build --- ext/ffi/ffi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index f5fe23f955398..6d9216b6f7f3f 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -246,7 +246,7 @@ static zend_always_inline void zend_ffi_object_init(zend_object *object, zend_cl { GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT | (IS_OBJ_DESTRUCTOR_CALLED << GC_FLAGS_SHIFT); - object->flags = 0; + object->extra_flags = 0; object->ce = ce; object->handlers = ce->default_object_handlers; object->properties = NULL; From b960778695302b04527de266564cf18439526f41 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 22:05:45 +0200 Subject: [PATCH 272/280] Rename constants --- Zend/zend_lazy_objects.c | 6 +++--- Zend/zend_lazy_objects.h | 4 ++-- ext/reflection/php_reflection.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index e0b300b14667c..cda1410c1c264 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -205,9 +205,9 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, zend_class_entry *reflection_ce, zval *initializer_zv, zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags) { - ZEND_ASSERT(!(flags & ~(ZEND_LAZY_OBJECT_USER_FLAGS|ZEND_LAZY_OBJECT_STRATEGY_FLAGS))); - ZEND_ASSERT((flags & ZEND_LAZY_OBJECT_STRATEGY_FLAGS) == ZEND_LAZY_OBJECT_STRATEGY_GHOST - || (flags & ZEND_LAZY_OBJECT_STRATEGY_FLAGS) == ZEND_LAZY_OBJECT_STRATEGY_PROXY); + ZEND_ASSERT(!(flags & ~(ZEND_LAZY_OBJECT_USER_MASK|ZEND_LAZY_OBJECT_STRATEGY_MASK))); + ZEND_ASSERT((flags & ZEND_LAZY_OBJECT_STRATEGY_MASK) == ZEND_LAZY_OBJECT_STRATEGY_GHOST + || (flags & ZEND_LAZY_OBJECT_STRATEGY_MASK) == ZEND_LAZY_OBJECT_STRATEGY_PROXY); ZEND_ASSERT(!obj || (!zend_object_is_lazy(obj) || zend_lazy_object_initialized(obj))); ZEND_ASSERT(!obj || instanceof_function(obj->ce, reflection_ce)); diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index a10e2205673a5..ecfd0293a57f0 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -36,12 +36,12 @@ /* Do not call destructor when making existing object lazy */ #define ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR (1<<4) -#define ZEND_LAZY_OBJECT_USER_FLAGS ( \ +#define ZEND_LAZY_OBJECT_USER_MASK ( \ ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE | \ ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR \ ) -#define ZEND_LAZY_OBJECT_STRATEGY_FLAGS ( \ +#define ZEND_LAZY_OBJECT_STRATEGY_MASK ( \ ZEND_LAZY_OBJECT_STRATEGY_PROXY | \ ZEND_LAZY_OBJECT_STRATEGY_GHOST \ ) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b5c62e006639a..972f119b51dd5 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5222,7 +5222,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, obj = NULL; } - zend_long accepted_flags = ZEND_LAZY_OBJECT_USER_FLAGS; + zend_long accepted_flags = ZEND_LAZY_OBJECT_USER_MASK; if (options & ~accepted_flags) { uint32_t arg_num = 2 + is_reset; zend_argument_error(reflection_exception_ptr, arg_num, From 174fe00bd3158fbdf3acd6884b5abf82278012a4 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Tue, 20 Aug 2024 22:15:56 +0200 Subject: [PATCH 273/280] CS --- ext/reflection/php_reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 972f119b51dd5..5c43c6004807f 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5230,7 +5230,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, RETURN_THROWS(); } - if (!is_reset && options & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) { + if (!is_reset && (options & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR)) { zend_argument_error(reflection_exception_ptr, 2, "does not accept ReflectionClass::SKIP_DESTRUCTOR"); RETURN_THROWS(); From 7f2190e4ef759b48580c74adc819d8be65957f05 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 21 Aug 2024 12:16:05 +0200 Subject: [PATCH 274/280] Generated file --- Zend/zend_vm_execute.h | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index edcab7848cc10..90e50d7362de8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5172,10 +5172,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -20046,10 +20043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -22700,10 +22694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -40746,10 +40737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties - && (!zend_object_is_lazy_proxy(Z_OBJ_P(expr)) || !zend_lazy_object_initialized(Z_OBJ_P(expr)))) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { From 5864de35926b0b3bd02d564bc491f0a267672f56 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 21 Aug 2024 14:34:06 +0200 Subject: [PATCH 275/280] Do not inline slow path --- Zend/zend_lazy_objects.c | 16 ++++++++++++++++ Zend/zend_lazy_objects.h | 1 + Zend/zend_object_handlers.h | 7 +------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index cda1410c1c264..227f47ef28f1b 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -617,6 +617,22 @@ void zend_lazy_object_realize(zend_object *obj) OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY); } +ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object) +{ + ZEND_ASSERT(zend_object_is_lazy(object)); + + zend_object *tmp = zend_lazy_object_init(object); + if (UNEXPECTED(!tmp)) { + ZEND_ASSERT(!object->properties || object->properties == &zend_empty_array); + return object->properties = (zend_array*) &zend_empty_array; + } + + object = tmp; + ZEND_ASSERT(!zend_lazy_object_must_init(object)); + + return zend_std_get_properties_ex(object); +} + /* Initialize object and clone it. For proxies, we clone both the proxy and its * real instance, and we don't call __clone() on the proxy. */ zend_object *zend_lazy_object_clone(zend_object *old_obj) diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index ecfd0293a57f0..addb07173c3f4 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -69,6 +69,7 @@ zval* zend_lazy_object_get_initializer_zv(zend_object *obj); zend_object *zend_lazy_object_get_instance(zend_object *obj); zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); void zend_lazy_object_del_info(zend_object *obj); +ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object); zend_object *zend_lazy_object_clone(zend_object *old_obj); HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n); diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index add97f47c0ef1..f36eb765c24a5 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -276,12 +276,7 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { if (UNEXPECTED(zend_lazy_object_must_init(object))) { - zend_object *tmp = zend_lazy_object_init(object); - if (UNEXPECTED(!tmp)) { - ZEND_ASSERT(!object->properties || object->properties == &zend_empty_array); - return object->properties = (zend_array*) &zend_empty_array; - } - object = tmp; + return zend_lazy_object_get_properties(object); } if (!object->properties) { return rebuild_object_properties_internal(object); From d1a10acab724824f78c41828962b37e88f996876 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 21 Aug 2024 14:36:00 +0200 Subject: [PATCH 276/280] Ensure separation --- .../lazy_objects/init_exception_001.phpt | 29 ++ Zend/zend_vm_def.h | 12 +- Zend/zend_vm_execute.h | 432 ++++++++++++++++-- 3 files changed, 436 insertions(+), 37 deletions(-) create mode 100644 Zend/tests/lazy_objects/init_exception_001.phpt diff --git a/Zend/tests/lazy_objects/init_exception_001.phpt b/Zend/tests/lazy_objects/init_exception_001.phpt new file mode 100644 index 0000000000000..81469b9992d6b --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_001.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: init exception 001 +--FILE-- +newLazyGhost(function ($obj) use ($i) { + if ($i === 1) { + throw new \Exception(); + } + }); + $obj->c = 1; +} + +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(Object(C)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 49bdd99189838..b46952a81718b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2481,6 +2481,16 @@ ZEND_VM_C_LABEL(fast_assign_obj): } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + ZEND_VM_C_GOTO(free_and_exit_assign_obj); + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -2519,7 +2529,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 90e50d7362de8..6738674667e74 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -23975,6 +23975,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24013,7 +24023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24119,6 +24129,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24157,7 +24177,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24263,6 +24283,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24301,7 +24331,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24407,6 +24437,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24445,7 +24485,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -26937,6 +26977,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -26975,7 +27025,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27081,6 +27131,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27119,7 +27179,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27225,6 +27285,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27263,7 +27333,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27369,6 +27439,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27407,7 +27487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31261,6 +31341,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31299,7 +31389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31405,6 +31495,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31443,7 +31543,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31549,6 +31649,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31587,7 +31697,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31693,6 +31803,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31731,7 +31851,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -33979,6 +34099,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34017,7 +34147,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34123,6 +34253,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34161,7 +34301,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34267,6 +34407,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34305,7 +34455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34411,6 +34561,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34449,7 +34609,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36118,6 +36278,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36156,7 +36326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36262,6 +36432,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36300,7 +36480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36406,6 +36586,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36444,7 +36634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36550,6 +36740,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36588,7 +36788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -38735,6 +38935,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -38773,7 +38983,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -38879,6 +39089,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -38917,7 +39137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39023,6 +39243,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -39061,7 +39291,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39167,6 +39397,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -39205,7 +39445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43089,6 +43329,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43127,7 +43377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43233,6 +43483,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43271,7 +43531,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43377,6 +43637,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43415,7 +43685,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43521,6 +43791,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43559,7 +43839,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47012,6 +47292,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47050,7 +47340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47156,6 +47446,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47194,7 +47494,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47300,6 +47600,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47338,7 +47648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47444,6 +47754,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47482,7 +47802,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52482,6 +52802,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52520,7 +52850,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52626,6 +52956,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52664,7 +53004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52770,6 +53110,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52808,7 +53158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52914,6 +53264,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52952,7 +53312,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } From 3e5c95c6b9522646b7afd5cb76355ffc0aabd823 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 21 Aug 2024 14:44:18 +0200 Subject: [PATCH 277/280] Simplify --- .../json_encode_dynamic_props.phpt | 49 +++++++++++++++ .../lazy_objects/serialize_dynamic_props.phpt | 48 +++++++++++++++ .../serialize_failed_lazy_object.phpt | 50 ++++++++++++++++ ...ed_lazy_object_skip_init_on_serialize.phpt | 60 +++++++++++++++++++ ext/json/json_encoder.c | 11 +--- ext/standard/var.c | 13 +--- 6 files changed, 211 insertions(+), 20 deletions(-) create mode 100644 Zend/tests/lazy_objects/json_encode_dynamic_props.phpt create mode 100644 Zend/tests/lazy_objects/serialize_dynamic_props.phpt create mode 100644 Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt create mode 100644 Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt diff --git a/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt b/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt new file mode 100644 index 0000000000000..19b4e7c86005a --- /dev/null +++ b/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: json_encode with dynamic props on initialized object +--FILE-- +newLazyGhost(function ($obj) { + $obj->dyn = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + $c = new C(); + $c->dyn = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost +object(stdClass)#%d (2) { + ["a"]=> + int(1) + ["dyn"]=> + int(1) +} +# Proxy +object(stdClass)#%d (2) { + ["a"]=> + int(1) + ["dyn"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_dynamic_props.phpt b/Zend/tests/lazy_objects/serialize_dynamic_props.phpt new file mode 100644 index 0000000000000..b2465ded4f4b5 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_dynamic_props.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: serialize() with dynamic props on initialized object +--FILE-- +newLazyGhost(function ($obj) { + $obj->dyn = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + $c = new C(); + $c->dyn = 1; + return $c; +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["dyn"]=> + int(1) +} +# Proxy +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["dyn"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt b/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt new file mode 100644 index 0000000000000..7fdf8fb771652 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: serialize() a lazy object that previously failed to initialize +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + var_dump(unserialize(serialize($obj))); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('Initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('Initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +Exception: Initializer +Exception: Initializer +# Proxy +Exception: Initializer +Exception: Initializer diff --git a/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt b/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt new file mode 100644 index 0000000000000..4fbda267d52a4 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: serialize() a lazy object that previously failed to initialize, with SKIP_INITIALIZATION_ON_SERIALIZE +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + var_dump(unserialize(serialize($obj))); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('Initializer'); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('Initializer'); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Exception: Initializer +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + NULL +} +# Proxy +Exception: Initializer +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + NULL +} diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 6d28ab033336d..de3106601b9c5 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -125,17 +125,10 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } else if (Z_OBJ_P(val)->properties == NULL && Z_OBJ_HT_P(val)->get_properties_for == NULL && Z_OBJ_HT_P(val)->get_properties == zend_std_get_properties - && Z_OBJ_P(val)->ce->num_hooked_props == 0) { + && Z_OBJ_P(val)->ce->num_hooked_props == 0 + && !zend_object_is_lazy(Z_OBJ_P(val))) { /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(val); - - if (zend_lazy_object_must_init(Z_OBJ_P(val))) { - obj = zend_lazy_object_init(Z_OBJ_P(val)); - if (!obj) { - return FAILURE; - } - } - zend_class_entry *ce = obj->ce; zend_property_info *prop_info; zval *prop; diff --git a/ext/standard/var.c b/ext/standard/var.c index 14af705b6331f..0d08a0a338309 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1224,19 +1224,10 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ if (Z_OBJ_P(struc)->properties == NULL && Z_OBJ_HT_P(struc)->get_properties_for == NULL - && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties + && !zend_object_is_lazy(Z_OBJ_P(struc))) { /* Optimized version without rebulding properties HashTable */ zend_object *obj = Z_OBJ_P(struc); - - if (zend_lazy_object_must_init(Z_OBJ_P(struc)) - && zend_lazy_object_initialize_on_serialize(Z_OBJ_P(struc))) { - obj = zend_lazy_object_init(Z_OBJ_P(struc)); - if (!obj) { - ZEND_ASSERT(EG(exception)); - return; - } - } - zend_class_entry *ce = obj->ce; zend_property_info *prop_info; zval *prop; From c332fa5e8dc86c71316be1358470abad6fcfaa3c Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:42:21 +0200 Subject: [PATCH 278/280] Add assertion --- Zend/zend_API.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index aa6e15b633334..b4f13bedecc56 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1803,6 +1803,7 @@ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zen } else if (class_type->ce_flags & ZEND_ACC_ENUM) { zend_throw_error(NULL, "Cannot instantiate enum %s", ZSTR_VAL(class_type->name)); } else { + ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(class_type->name)); } ZVAL_NULL(arg); From 9114a71e2ac4d76bd23584da7122144179d625a9 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:42:30 +0200 Subject: [PATCH 279/280] Prevent compiler warning --- Zend/zend_lazy_objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 227f47ef28f1b..357150bc63876 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -234,6 +234,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, /* Call object_init_ex() for the generated exception */ zend_result result = object_init_ex(&zobj, reflection_ce); ZEND_ASSERT(result == FAILURE && EG(exception)); + (void)result; return NULL; } From 3b3a2008325a5936bd03bd5616cb827911e927e9 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 28 Aug 2024 17:42:39 +0200 Subject: [PATCH 280/280] Simplify --- ext/reflection/php_reflection.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5c43c6004807f..531db004b3ba6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5222,8 +5222,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, obj = NULL; } - zend_long accepted_flags = ZEND_LAZY_OBJECT_USER_MASK; - if (options & ~accepted_flags) { + if (options & ~ZEND_LAZY_OBJECT_USER_MASK) { uint32_t arg_num = 2 + is_reset; zend_argument_error(reflection_exception_ptr, arg_num, "contains invalid flags");