diff --git a/.appveyor.yml b/.appveyor.yml index b1f6fa985bbc2..de9c3e78446be 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -16,7 +16,7 @@ environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache PHP_BUILD_OBJ_DIR: c:\obj PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta4 + PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta5 PHP_BUILD_CRT: vc15 # ext and env setup for tests #MYSQL_TEST_PASSWD: Password12! diff --git a/.gitignore b/.gitignore index ca7179b7b0389..52ab256ba3000 100644 --- a/.gitignore +++ b/.gitignore @@ -66,9 +66,6 @@ configure confdefs.h conftest* -# Generated by `./buildconf` script as a helper for further build/build2.mk file -/generated_lists - # Generated by configure scripts on all systems /main/internal_functions.c /main/internal_functions_cli.c @@ -179,11 +176,7 @@ php # ------------------------------------------------------------------------------ /ext/*/acinclude.m4 /ext/*/build/ -/ext/*/config.guess -/ext/*/config.sub /ext/*/configure.ac -/ext/*/ltmain.sh -/ext/*/Makefile.global /ext/*/run-tests.php # ------------------------------------------------------------------------------ diff --git a/.travis.yml b/.travis.yml index e256b58171026..ba6a6ba3d71b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,7 +64,7 @@ before_script: # Enable IPv6 - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' # Compile PHP - - ./travis/compile.sh + - travis_wait ./travis/compile.sh # Setup Extensions - . ./travis/ext/mysql/setup.sh - . ./travis/ext/mysqli/setup.sh @@ -74,7 +74,8 @@ before_script: # Run PHPs run-tests.php script: - - ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d opcache.protect_memory=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120 -j2 + - ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d opcache.protect_memory=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120 -j2 + - sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");' after_success: - ccache --show-stats diff --git a/NEWS b/NEWS index 178b551273bf4..08340c8536b05 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug #77345 (Stack Overflow caused by circular reference in garbage collection). (Alexandru Patranescu, Nikita, Dmitry) + . Fixed bug #77877 (call_user_func() passes $this to static methods). + (Dmitry) . Implemented request #76148 (Add array_key_exists() to the list of specially compiled functions). (Majkl578) . Fixed bug #76430 (__METHOD__ inconsistent outside of method). @@ -58,6 +60,9 @@ PHP NEWS - LDAP: . Deprecated ldap_control_paged_result_response and ldap_control_paged_result +- Mbstring: + . Fixed bug #77907 (mb-functions do not respect default_encoding). (Nikita) + - Opcache: . Implemented preloading RFC: https://wiki.php.net/rfc/preload. (Dmitry) diff --git a/README.md b/README.md index e5c48f02392e2..b6ecb033bd5a6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ PHP @@ -48,31 +48,38 @@ PHP uses autotools on Unix systems to configure the build: *See `make -h` for make options.* -The `-j` option shall set the maximum number of jobs `make` can use for the build: +The `-j` option shall set the maximum number of jobs `make` can use for the +build: make -j4 - -Shall run `make` with a maximum of 4 concurrent jobs: Generally the maximum number of jobs should not exceed the number of cores available. + +Shall run `make` with a maximum of 4 concurrent jobs: Generally the maximum +number of jobs should not exceed the number of cores available. ## Testing PHP source code -PHP ships with an extensive test suite, the command `make test` is used after successful compilation of the sources to run this test suite. +PHP ships with an extensive test suite, the command `make test` is used after +successful compilation of the sources to run this test suite. -It is possible to run tests using multiple cores by setting `-jN` in `TEST_PHP_ARGS`: +It is possible to run tests using multiple cores by setting `-jN` in +`TEST_PHP_ARGS`: make TEST_PHP_ARGS=-j4 test - -Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum number of jobs should not exceed the number of cores available. -The [qa.php.net](https://qa.php.net) site provides more detailed info about testing and quality assurance. +Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum +number of jobs should not exceed the number of cores available. + +The [qa.php.net](https://qa.php.net) site provides more detailed info about +testing and quality assurance. ## Installing PHP built from source After a successful build (and test), PHP may be installed with: make install - -Depending on your permissions and prefix, `make install` may need super user permissions. + +Depending on your permissions and prefix, `make install` may need super user +permissions. ## PHP extensions diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index d70c09d2b529a..34080eed96272 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -244,12 +244,12 @@ TSRM_API void tsrm_shutdown(void) /* {{{ */ /* environ lock api */ -TSRM_API int tsrm_env_lock() { - return tsrm_mutex_lock(tsrm_env_mutex); +TSRM_API void tsrm_env_lock() { + tsrm_mutex_lock(tsrm_env_mutex); } -TSRM_API int tsrm_env_unlock() { - return tsrm_mutex_unlock(tsrm_env_mutex); +TSRM_API void tsrm_env_unlock() { + tsrm_mutex_unlock(tsrm_env_mutex); } /* }}} */ /* enlarge the arrays for the already active threads */ diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 64661c1ebf111..89eea4783f006 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -98,8 +98,8 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu TSRM_API void tsrm_shutdown(void); /* environ lock API */ -TSRM_API int tsrm_env_lock(); -TSRM_API int tsrm_env_unlock(); +TSRM_API void tsrm_env_lock(); +TSRM_API void tsrm_env_unlock(); /* allocates a new thread-safe-resource id */ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); @@ -207,8 +207,8 @@ TSRM_API const char *tsrm_api_name(void); #else /* non ZTS */ -#define tsrm_env_lock() 0 -#define tsrm_env_unlock() 0 +#define tsrm_env_lock() +#define tsrm_env_unlock() #define TSRMLS_FETCH() #define TSRMLS_FETCH_FROM_CTX(ctx) diff --git a/UPGRADING b/UPGRADING index 7b460da4a0202..9768e5f7e41c0 100644 --- a/UPGRADING +++ b/UPGRADING @@ -87,6 +87,11 @@ PHP 7.4 UPGRADE NOTES . SplPriorityQueue::setExtractFlags() will throw an exception if zero is passed. Previously this would generate a recoverable fatal error on the next extraction operation. + . ArrayObject, ArrayIterator, SplDoublyLinkedList and SplObjectStorage now + support the __serialize() + __unserialize() mechanism in addition to the + Serializable interface. This means that serialization payloads created on + older PHP versions can still be unserialized, but new payloads created by + PHP 7.4 will not be understood by older versions. - Standard: . The "o" serialization format has been removed. As it is never produced by @@ -276,7 +281,7 @@ PHP 7.4 UPGRADE NOTES by passing -1 as $new_width. - Filter: - . The filter extension no longer exposes --with-pcre-dir for Unix builds and + . The filter extension no longer exposes --with-pcre-dir for Unix builds and can now reliably be built as shared when using ./configure once more. - Hash: @@ -389,7 +394,7 @@ PHP 7.4 UPGRADE NOTES PHP, so they're a fake. - CTRL+C and CTRL+BREAK on console can be caught by setting a handler function - with sapi_windows_set_ctrl_handler(). + with sapi_windows_set_ctrl_handler(). ======================================== 13. Migration to pkg-config @@ -407,6 +412,9 @@ The following extensions are affected: - Curl: . --with-curl no longer accepts a directory. +- IMAP: + . --with-kerberos no longer accepts a directory. + - Intl: . --with-icu-dir has been removed. If --enable-intl is passed, then libicu is always required. @@ -417,6 +425,7 @@ The following extensions are affected: - OpenSSL: . --with-openssl no longer accepts a directory. + . --with-kerberos no longer accepts a directory. - PCRE: . --with-pcre-regex has been removed. Instead --with-external-pcre is provided @@ -436,6 +445,10 @@ The following extensions are affected: . --with-webp-dir becomes --with-webp. . --with-xpm-dir becomes --with-xpm. +- Libxml: + . --with-libxml-dir has been removed. + . --enable-libxml becomes --with-libxml. + ======================================== 14. Other Changes ======================================== diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index afa4ed91e4aeb..5505184092e25 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -19,7 +19,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES p. ZEND_EXT_FCALL_BEGIN can access arguments q. ZEND_COMPILE_IGNORE_USER_FUNCTIONS and ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS r. TSRM environment locking - + 2. Build system changes a. Abstract b. Unix build system changes @@ -184,11 +184,11 @@ PHP 7.4 INTERNALS UPGRADE NOTES are respected by zend_get_call_op such that when set, the only possible call opcodes are ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME, previously they were ignored by zend_get_call_op. - - r. TSRM adds tsrm_env_lock() and tsrm_env_unlock() for ZTS: + + r. TSRM adds tsrm_env_lock() and tsrm_env_unlock() for ZTS: code that may change environ and may run concurrently with user code in ZTS is expected to use this exclusion API to maintain as much safety as reasonable. - This results in "thread safe" getenv/putenv in Windows and Unix, however + This results in "thread safe" getenv/putenv in Windows and Unix, however functions that may read the environment without exclusion still exist, for example: - setlocale @@ -197,7 +197,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES The above is not an exhaustive list of such functions, while getenv/putenv will behave as if they are safe, care should still be taken in multi-threaded environments. - + ======================== 2. Build system changes ======================== @@ -205,8 +205,8 @@ PHP 7.4 INTERNALS UPGRADE NOTES a. Abstract - The hash extension is now always available, meaning the --enable-hash configure argument has been removed. - - The filter extension no longer exposes the --with-pcre-dir configure - argument and therefore allows shared builds with ./configure for Unix + - The filter extension no longer exposes the --with-pcre-dir configure + argument and therefore allows shared builds with ./configure for Unix builds. b. Unix build system changes @@ -218,7 +218,8 @@ PHP 7.4 INTERNALS UPGRADE NOTES - Local PHP m4 unused or obsolete macros have been removed: PHP_TARGET_RDYNAMIC, PHP_SOLARIS_PIC_WEIRDNESS, PHP_SYS_LFS, PHP_AC_BROKEN_SPRINTF, PHP_EXTENSION, PHP_DECLARED_TIMEZONE, - PHP_CHECK_TYPES, PHP_TM_GMTOFF, PHP_CHECK_64BIT. + PHP_CHECK_TYPES, PHP_TM_GMTOFF, PHP_CHECK_64BIT, PHP_READDIR_R_TYPE, + PHP_SETUP_KERBEROS. - new --enable-rtld-now build option allow to switch dlopen behavior from RTLD_LAZY to RTLD_NOW - Minimum Bison version is 3.0+ for generating parser files. diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 0755a58f14cb3..08f000dd2b5d7 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -2,6 +2,120 @@ dnl dnl This file contains Zend specific autoconf functions. dnl +dnl x87 floating point internal precision control checks +dnl See: http://wiki.php.net/rfc/rounding +AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[ + AC_MSG_CHECKING([for usable _FPU_SETCW]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[ + fpu_control_t fpu_oldcw, fpu_cw; + volatile double result; + double a = 2877.0; + volatile double b = 1000000.0; + + _FPU_GETCW(fpu_oldcw); + fpu_cw = (fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; + _FPU_SETCW(fpu_cw); + result = a / b; + _FPU_SETCW(fpu_oldcw); + ]])],[ac_cfp_have__fpu_setcw=yes],[ac_cfp_have__fpu_setcw=no]) + if test "$ac_cfp_have__fpu_setcw" = "yes" ; then + AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([for usable fpsetprec]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[ + fp_prec_t fpu_oldprec; + volatile double result; + double a = 2877.0; + volatile double b = 1000000.0; + + fpu_oldprec = fpgetprec(); + fpsetprec(FP_PD); + result = a / b; + fpsetprec(fpu_oldprec); + ]])], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no]) + if test "$ac_cfp_have_fpsetprec" = "yes" ; then + AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([for usable _controlfp]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[ + unsigned int fpu_oldcw; + volatile double result; + double a = 2877.0; + volatile double b = 1000000.0; + + fpu_oldcw = _controlfp(0, 0); + _controlfp(_PC_53, _MCW_PC); + result = a / b; + _controlfp(fpu_oldcw, _MCW_PC); + ]])], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no]) + if test "$ac_cfp_have__controlfp" = "yes" ; then + AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([for usable _controlfp_s]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[ + unsigned int fpu_oldcw, fpu_cw; + volatile double result; + double a = 2877.0; + volatile double b = 1000000.0; + + _controlfp_s(&fpu_cw, 0, 0); + fpu_oldcw = fpu_cw; + _controlfp_s(&fpu_cw, _PC_53, _MCW_PC); + result = a / b; + _controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC); + ]])], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no]) + if test "$ac_cfp_have__controlfp_s" = "yes" ; then + AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + /* nothing */ + ]],[[ + unsigned int oldcw, cw; + volatile double result; + double a = 2877.0; + volatile double b = 1000000.0; + + __asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw)); + cw = (oldcw & ~0x0 & ~0x300) | 0x200; + __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); + + result = a / b; + + __asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw)); + ]])], [ac_cfp_have_fpu_inline_asm_x86=yes], [ac_cfp_have_fpu_inline_asm_x86=no]) + if test "$ac_cfp_have_fpu_inline_asm_x86" = "yes" ; then + AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +]) + AC_DEFUN([LIBZEND_BASIC_CHECKS],[ AC_REQUIRE([AC_PROG_CC]) @@ -101,13 +215,13 @@ if test "$ZEND_DEBUG" = "yes"; then if test "$CFLAGS" = "-g -O2"; then CFLAGS=-g fi - test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall" test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \ DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations" else AC_DEFINE(ZEND_DEBUG,0,[ ]) fi +test -n "$GCC" && CFLAGS="$CFLAGS -Wall -Wno-strict-aliasing" test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS" if test "$ZEND_MAINTAINER_ZTS" = "yes"; then diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4 deleted file mode 100644 index a2930b62cde05..0000000000000 --- a/Zend/acinclude.m4 +++ /dev/null @@ -1,115 +0,0 @@ -dnl This file contains local autoconf functions. - -dnl x87 floating point internal precision control checks -dnl See: http://wiki.php.net/rfc/rounding -AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[ - AC_MSG_CHECKING([for usable _FPU_SETCW]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[ - fpu_control_t fpu_oldcw, fpu_cw; - volatile double result; - double a = 2877.0; - volatile double b = 1000000.0; - - _FPU_GETCW(fpu_oldcw); - fpu_cw = (fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; - _FPU_SETCW(fpu_cw); - result = a / b; - _FPU_SETCW(fpu_oldcw); - ]])],[ac_cfp_have__fpu_setcw=yes],[ac_cfp_have__fpu_setcw=no]) - if test "$ac_cfp_have__fpu_setcw" = "yes" ; then - AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - - AC_MSG_CHECKING([for usable fpsetprec]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[ - fp_prec_t fpu_oldprec; - volatile double result; - double a = 2877.0; - volatile double b = 1000000.0; - - fpu_oldprec = fpgetprec(); - fpsetprec(FP_PD); - result = a / b; - fpsetprec(fpu_oldprec); - ]])], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no]) - if test "$ac_cfp_have_fpsetprec" = "yes" ; then - AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - - AC_MSG_CHECKING([for usable _controlfp]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[ - unsigned int fpu_oldcw; - volatile double result; - double a = 2877.0; - volatile double b = 1000000.0; - - fpu_oldcw = _controlfp(0, 0); - _controlfp(_PC_53, _MCW_PC); - result = a / b; - _controlfp(fpu_oldcw, _MCW_PC); - ]])], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no]) - if test "$ac_cfp_have__controlfp" = "yes" ; then - AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - - AC_MSG_CHECKING([for usable _controlfp_s]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - ]],[[ - unsigned int fpu_oldcw, fpu_cw; - volatile double result; - double a = 2877.0; - volatile double b = 1000000.0; - - _controlfp_s(&fpu_cw, 0, 0); - fpu_oldcw = fpu_cw; - _controlfp_s(&fpu_cw, _PC_53, _MCW_PC); - result = a / b; - _controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC); - ]])], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no]) - if test "$ac_cfp_have__controlfp_s" = "yes" ; then - AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - - AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - /* nothing */ - ]],[[ - unsigned int oldcw, cw; - volatile double result; - double a = 2877.0; - volatile double b = 1000000.0; - - __asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw)); - cw = (oldcw & ~0x0 & ~0x300) | 0x200; - __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); - - result = a / b; - - __asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw)); - ]])], [ac_cfp_have_fpu_inline_asm_x86=yes], [ac_cfp_have_fpu_inline_asm_x86=no]) - if test "$ac_cfp_have_fpu_inline_asm_x86" = "yes" ; then - AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi -]) diff --git a/Zend/tests/array_unpack/basic.phpt b/Zend/tests/array_unpack/basic.phpt new file mode 100644 index 0000000000000..0e10638f0645a --- /dev/null +++ b/Zend/tests/array_unpack/basic.phpt @@ -0,0 +1,119 @@ +--TEST-- +Basic array unpacking +--FILE-- + + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(4) { + [0]=> + int(11) + [1]=> + int(12) + [2]=> + int(13) + [3]=> + int(14) +} +array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(15) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + [11]=> + int(11) + [12]=> + int(12) + [13]=> + int(13) + [14]=> + int(14) +} +array(8) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(1) + [5]=> + int(2) + [6]=> + int(3) + [7]=> + string(3) "end" +} diff --git a/Zend/tests/array_unpack/classes.phpt b/Zend/tests/array_unpack/classes.phpt new file mode 100644 index 0000000000000..349c5d95a8f6a --- /dev/null +++ b/Zend/tests/array_unpack/classes.phpt @@ -0,0 +1,46 @@ +--TEST-- +Array unpacking with classes +--FILE-- +getMessage() . "\n"; +} +--EXPECT-- +array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +Exception: Cannot declare self-referencing constant 'self::B' \ No newline at end of file diff --git a/Zend/tests/array_unpack/non_integer_keys.phpt b/Zend/tests/array_unpack/non_integer_keys.phpt new file mode 100644 index 0000000000000..5c93102907959 --- /dev/null +++ b/Zend/tests/array_unpack/non_integer_keys.phpt @@ -0,0 +1,17 @@ +--TEST-- +Array unpacking does not work with non-integer keys +--FILE-- + 1; + yield 1.23 => 123; +} + +try { + [...gen()]; +} catch (Error $ex) { + echo "Exception: " . $ex->getMessage() . "\n"; +} + +--EXPECT-- +Exception: Cannot unpack Traversable with non-integer keys diff --git a/Zend/tests/array_unpack/string_keys.phpt b/Zend/tests/array_unpack/string_keys.phpt new file mode 100644 index 0000000000000..6032d7cc3f23d --- /dev/null +++ b/Zend/tests/array_unpack/string_keys.phpt @@ -0,0 +1,21 @@ +--TEST-- +array unpacking with string keys (not supported) +--FILE-- + 3, 4]; + var_dump([...$array]); +} catch (Error $ex) { + var_dump($ex->getMessage()); +} +try { + $iterator = new ArrayIterator([1, 2, "foo" => 3, 4]); + var_dump([...$iterator]); +} catch (Error $ex) { + var_dump($ex->getMessage()); +} + +--EXPECT-- +string(36) "Cannot unpack array with string keys" +string(42) "Cannot unpack Traversable with string keys" diff --git a/Zend/tests/array_unpack/undef_var.phpt b/Zend/tests/array_unpack/undef_var.phpt new file mode 100644 index 0000000000000..fff1f6171e089 --- /dev/null +++ b/Zend/tests/array_unpack/undef_var.phpt @@ -0,0 +1,14 @@ +--TEST-- +array unpacking with undefinded variable +--FILE-- +getMessage() . "\n"; +} +echo "ok\n"; +?> +--EXPECT-- +bomb! +ok diff --git a/Zend/tests/bug29368_3.phpt b/Zend/tests/bug29368_3.phpt new file mode 100644 index 0000000000000..fafcc2a0efa8b --- /dev/null +++ b/Zend/tests/bug29368_3.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #29368.3 (The destructor is called when an exception is thrown from the constructor). +--FILE-- + +--EXPECT-- +Foo::__construct +Bar::__construct +Foo::__destruct +Caught exception! diff --git a/Zend/tests/bug77877.phpt b/Zend/tests/bug77877.phpt new file mode 100644 index 0000000000000..d4627f77c87d5 --- /dev/null +++ b/Zend/tests/bug77877.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #77877 call_user_func() passes $this to static methods +--FILE-- +getMessage() . "\n"; +} +try { + call_user_func([new Foo, 'bar']); +} catch (Throwable $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Using $this when not in object context +Using $this when not in object context diff --git a/Zend/tests/foreach_by_ref_repacking_insert.phpt b/Zend/tests/foreach_by_ref_repacking_insert.phpt new file mode 100644 index 0000000000000..1a2f9c7068b6d --- /dev/null +++ b/Zend/tests/foreach_by_ref_repacking_insert.phpt @@ -0,0 +1,18 @@ +--TEST-- +Perform a packed to hash insert when the iterator is at the end of the array +--FILE-- + + &$v) { + var_dump($v); + if ($k == 1) $a[4] = 4; + if ($k == 4) $a[2] = 2; +} + +?> +--EXPECT-- +int(1) +int(4) +int(2) diff --git a/Zend/tests/multibyte/bug68665.phpt b/Zend/tests/multibyte/bug68665.phpt index 74ff01da332d7..68467765709c6 100644 --- a/Zend/tests/multibyte/bug68665.phpt +++ b/Zend/tests/multibyte/bug68665.phpt @@ -11,7 +11,7 @@ if (!extension_loaded("mbstring")) { ?> --INI-- zend.multibyte=1 -mbstring.internal_encoding=big5 +internal_encoding=big5 --FILE-- --INI-- zend.multibyte=1 -mbstring.internal_encoding=SJIS +internal_encoding=SJIS --FILE-- --INI-- zend.multibyte=1 -mbstring.internal_encoding=iso-8859-1 +internal_encoding=iso-8859-1 --FILE-- ?name); - lcname = zend_string_alloc(name_len, 1); + lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT); zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len); lcname = zend_new_interned_string(lcname); if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) { zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name); - zend_string_release_ex(lcname, 1); + zend_string_release(lcname); return NULL; } module = module_ptr; @@ -1995,14 +1995,14 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) / if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) { zend_hash_del(&module_registry, lcname); - zend_string_release_ex(lcname, 1); + zend_string_release(lcname); EG(current_module) = NULL; zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name); return NULL; } EG(current_module) = NULL; - zend_string_release_ex(lcname, 1); + zend_string_release(lcname); return module; } /* }}} */ @@ -2209,14 +2209,14 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio return FAILURE; } } - lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1); + lowercase_name = zend_string_tolower_ex(internal_function->function_name, type == MODULE_PERSISTENT); lowercase_name = zend_new_interned_string(lowercase_name); reg_function = malloc(sizeof(zend_internal_function)); memcpy(reg_function, &function, sizeof(zend_internal_function)); if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) { unload=1; free(reg_function); - zend_string_release_ex(lowercase_name, 1); + zend_string_release(lowercase_name); break; } @@ -2312,7 +2312,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } ptr++; count++; - zend_string_release_ex(lowercase_name, 1); + zend_string_release(lowercase_name); } if (unload) { /* before unloading, display all remaining bad function in the module */ if (scope) { @@ -2608,6 +2608,7 @@ ZEND_API void zend_post_deactivate_modules(void) /* {{{ */ if (module->type != MODULE_TEMPORARY) { break; } + module_destructor(module); } ZEND_HASH_FOREACH_END_DEL(); } else { zend_module_entry **p = module_post_deactivate_handlers; @@ -2641,10 +2642,10 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class class_entry->info.internal.module = EG(current_module); if (class_entry->info.internal.builtin_functions) { - zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT); + zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, EG(current_module)->type); } - lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1); + lowercase_name = zend_string_tolower_ex(orig_class_entry->name, EG(current_module)->type == MODULE_PERSISTENT); lowercase_name = zend_new_interned_string(lowercase_name); zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry); zend_string_release_ex(lowercase_name, 1); @@ -2704,6 +2705,11 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen { zend_string *lcname; + /* TODO: Move this out of here in 7.4. */ + if (persistent && EG(current_module) && EG(current_module)->type == MODULE_TEMPORARY) { + persistent = 0; + } + if (name[0] == '\\') { lcname = zend_string_alloc(name_len-1, persistent); zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1); @@ -3170,6 +3176,10 @@ static zend_always_inline int zend_is_callable_check_func(int check_flags, zval if (fcc->object) { fcc->called_scope = fcc->object->ce; + if (fcc->function_handler + && fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC) { + fcc->object = NULL; + } } return retval; } @@ -3602,6 +3612,11 @@ static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */ return Z_STR_P(zv); } +static zend_always_inline zend_bool is_persistent_class(zend_class_entry *ce) { + return (ce->type & ZEND_INTERNAL_CLASS) + && ce->info.internal.module->type == MODULE_PERSISTENT; +} + ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type) /* {{{ */ { zend_property_info *property_info, *property_info_ptr; @@ -3687,10 +3702,10 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name if (access_type & ZEND_ACC_PUBLIC) { property_info->name = zend_string_copy(name); } else if (access_type & ZEND_ACC_PRIVATE) { - property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS); + property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce)); } else { ZEND_ASSERT(access_type & ZEND_ACC_PROTECTED); - property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS); + property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce)); } property_info->name = zend_new_interned_string(property_info->name); @@ -3840,7 +3855,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */ { - zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS); + zend_string *key = zend_string_init(name, name_length, is_persistent_class(ce)); int ret = zend_declare_property_ex(ce, key, property, access_type, NULL); zend_string_release(key); return ret; diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 2cacd532878bc..7b573db5f8e08 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -446,6 +446,98 @@ static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr) return SUCCESS; } +static int zend_ast_add_unpacked_element(zval *result, zval *expr) { + if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(expr); + zval *val; + zend_string *key; + + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (key) { + zend_throw_error(NULL, "Cannot unpack array with string keys"); + return FAILURE; + } else { + Z_TRY_ADDREF_P(val); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(val); + } + } + } ZEND_HASH_FOREACH_END(); + } else if (EXPECTED(Z_TYPE_P(expr) == IS_OBJECT)) { + zend_class_entry *ce = Z_OBJCE_P(expr); + zend_object_iterator *iter; + + if (!ce || !ce->get_iterator) { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + return FAILURE; + } else { + iter = ce->get_iterator(ce, expr, 0); + if (UNEXPECTED(!iter)) { + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) + ); + } + return FAILURE; + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + } + + for (; iter->funcs->valid(iter) == SUCCESS; ) { + zval *val; + + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + val = iter->funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (iter->funcs->get_current_key) { + zval key; + iter->funcs->get_current_key(iter, &key); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { + zend_throw_error(NULL, + (Z_TYPE(key) == IS_STRING) ? + "Cannot unpack Traversable with string keys" : + "Cannot unpack Traversable with non-integer keys"); + zval_ptr_dtor(&key); + break; + } + } + + ZVAL_DEREF(val); + Z_TRY_ADDREF_P(val); + + if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(val); + } + + iter->funcs->move_forward(iter); + } + + zend_iterator_dtor(iter); + } + } else if (EXPECTED(Z_ISREF_P(expr))) { + expr = Z_REFVAL_P(expr); + return zend_ast_add_unpacked_element(result, expr); + } else { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + return FAILURE; + } + return SUCCESS; +} + ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) { zval op1, op2; @@ -642,6 +734,18 @@ ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_c array_init(result); for (i = 0; i < list->children; i++) { zend_ast *elem = list->child[i]; + if (elem->kind == ZEND_AST_UNPACK) { + if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[0], scope) != SUCCESS)) { + zval_ptr_dtor_nogc(result); + return FAILURE; + } + if (UNEXPECTED(zend_ast_add_unpacked_element(result, &op1) != SUCCESS)) { + zval_ptr_dtor_nogc(&op1); + zval_ptr_dtor_nogc(result); + return FAILURE; + } + continue; + } if (elem->child[1]) { if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) { zval_ptr_dtor_nogc(result); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2fa847d180d6c..2c8bd995d537b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3066,7 +3066,6 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function * zend_op *opline; uint32_t opnum_init = get_next_op_number() - 1; uint32_t arg_count; - uint32_t call_flags; arg_count = zend_compile_args(args_ast, fbc); @@ -3079,10 +3078,7 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function * opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc); } - call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0); opline = zend_emit_op(result, zend_get_call_op(opline, fbc), NULL, NULL); - opline->op1.num = call_flags; - zend_do_extended_fcall_end(); } /* }}} */ @@ -3551,16 +3547,19 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ } /* }}} */ -int zend_compile_func_count(znode *result, zend_ast_list *args) /* {{{ */ +int zend_compile_func_count(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */ { znode arg_node; + zend_op *opline; if (args->children != 1) { return FAILURE; } zend_compile_expr(&arg_node, args->child[0]); - zend_emit_op_tmp(result, ZEND_COUNT, &arg_node, NULL); + opline = zend_emit_op_tmp(result, ZEND_COUNT, &arg_node, NULL); + opline->extended_value = zend_string_equals_literal(lcname, "sizeof"); + return SUCCESS; } /* }}} */ @@ -3739,8 +3738,9 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l return zend_compile_func_cuf(result, args, lcname); } else if (zend_string_equals_literal(lcname, "in_array")) { return zend_compile_func_in_array(result, args); - } else if (zend_string_equals_literal(lcname, "count")) { - return zend_compile_func_count(result, args); + } else if (zend_string_equals_literal(lcname, "count") + || zend_string_equals_literal(lcname, "sizeof")) { + return zend_compile_func_count(result, args, lcname); } else if (zend_string_equals_literal(lcname, "get_class")) { return zend_compile_func_get_class(result, args); } else if (zend_string_equals_literal(lcname, "get_called_class")) { @@ -4757,7 +4757,7 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */ znode expr_node, case_node; zend_op *opline; - uint32_t *jmpnz_opnums, opnum_default_jmp, opnum_switch; + uint32_t *jmpnz_opnums, opnum_default_jmp, opnum_switch = (uint32_t)-1; zend_uchar jumptable_type; HashTable *jumptable = NULL; @@ -4850,6 +4850,7 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_update_jump_target_to_next(opnum_default_jmp); if (jumptable) { + ZEND_ASSERT(opnum_switch != (uint32_t)-1); opline = &CG(active_op_array)->opcodes[opnum_switch]; opline->extended_value = get_next_op_number(); } @@ -4942,12 +4943,11 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ zend_bool is_last_catch = (i + 1 == catches->children); uint32_t *jmp_multicatch = safe_emalloc(sizeof(uint32_t), classes->children - 1, 0); - uint32_t opnum_catch; + uint32_t opnum_catch = (uint32_t)-1; CG(zend_lineno) = catch_ast->lineno; for (j = 0; j < classes->children; j++) { - zend_ast *class_ast = classes->child[j]; zend_bool is_last_class = (j + 1 == classes->children); @@ -4997,6 +4997,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ jmp_opnums[i + 1] = zend_emit_jump(0); } + ZEND_ASSERT(opnum_catch != (uint32_t)-1 && "Should have at least one class"); opline = &CG(active_op_array)->opcodes[opnum_catch]; if (!is_last_catch) { opline->op2.opline_num = get_next_op_number(); @@ -6892,10 +6893,12 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ } zend_eval_const_expr(&elem_ast->child[0]); - zend_eval_const_expr(&elem_ast->child[1]); + if (elem_ast->kind != ZEND_AST_UNPACK) { + zend_eval_const_expr(&elem_ast->child[1]); + } if (elem_ast->attr /* by_ref */ || elem_ast->child[0]->kind != ZEND_AST_ZVAL - || (elem_ast->child[1] && elem_ast->child[1]->kind != ZEND_AST_ZVAL) + || (elem_ast->kind != ZEND_AST_UNPACK && elem_ast->child[1] && elem_ast->child[1]->kind != ZEND_AST_ZVAL) ) { is_constant = 0; } @@ -6919,6 +6922,30 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ zend_ast *key_ast = elem_ast->child[1]; zval *value = zend_ast_get_zval(value_ast); + if (elem_ast->kind == ZEND_AST_UNPACK) { + if (EXPECTED(Z_TYPE_P(value) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(value); + zval *val; + zend_string *key; + + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (key) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot unpack array with string keys"); + } + Z_TRY_ADDREF_P(val); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) { + zval_ptr_dtor_nogc(val); + zval_ptr_dtor(result); + return 0; + } + } ZEND_HASH_FOREACH_END(); + + continue; + } else { + zend_error_noreturn(E_COMPILE_ERROR, "Only arrays and Traversables can be unpacked"); + } + } + Z_TRY_ADDREF_P(value); if (key_ast) { @@ -7653,6 +7680,16 @@ void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ key_ast = elem_ast->child[1]; by_ref = elem_ast->attr; + if (elem_ast->kind == ZEND_AST_UNPACK) { + zend_compile_expr(&value_node, value_ast); + if (i == 0) { + opline = zend_emit_op_tmp(result, ZEND_INIT_ARRAY, NULL, NULL); + } + opline = zend_emit_op(NULL, ZEND_ADD_ARRAY_UNPACK, &value_node, NULL); + SET_NODE(opline->result, result); + continue; + } + if (key_ast) { zend_compile_expr(&key_node, key_ast); zend_handle_numeric_op(&key_node); @@ -7979,6 +8016,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */ || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS || kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM + || kind == ZEND_AST_UNPACK || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST || kind == ZEND_AST_CLASS_NAME || kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_COALESCE; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 82d70fd4b026d..588022c77005e 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -172,7 +172,8 @@ typedef struct _zend_try_catch_element { #define ZEND_LIVE_LOOP 1 #define ZEND_LIVE_SILENCE 2 #define ZEND_LIVE_ROPE 3 -#define ZEND_LIVE_MASK 3 +#define ZEND_LIVE_NEW 4 +#define ZEND_LIVE_MASK 7 typedef struct _zend_live_range { uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */ @@ -481,13 +482,6 @@ union _zend_function { zend_internal_function internal_function; }; -typedef enum _zend_call_kind { - ZEND_CALL_NESTED_FUNCTION, /* stackless VM call to function */ - ZEND_CALL_NESTED_CODE, /* stackless VM call to include/require/eval */ - ZEND_CALL_TOP_FUNCTION, /* direct VM call to function from external C code */ - ZEND_CALL_TOP_CODE /* direct VM call to "main" code from external C code */ -} zend_call_kind; - struct _zend_execute_data { const zend_op *opline; /* executed opline */ zend_execute_data *call; /* current call */ @@ -501,25 +495,30 @@ struct _zend_execute_data { #endif }; -#define ZEND_CALL_FUNCTION (0 << 0) -#define ZEND_CALL_CODE (1 << 0) -#define ZEND_CALL_NESTED (0 << 1) -#define ZEND_CALL_TOP (1 << 1) -#define ZEND_CALL_FREE_EXTRA_ARGS (1 << 2) -#define ZEND_CALL_CTOR (1 << 3) -#define ZEND_CALL_HAS_SYMBOL_TABLE (1 << 4) -#define ZEND_CALL_CLOSURE (1 << 5) -#define ZEND_CALL_RELEASE_THIS (1 << 6) -#define ZEND_CALL_ALLOCATED (1 << 7) -#define ZEND_CALL_GENERATOR (1 << 8) -#define ZEND_CALL_DYNAMIC (1 << 9) -#define ZEND_CALL_FAKE_CLOSURE (1 << 10) -#define ZEND_CALL_SEND_ARG_BY_REF (1 << 11) - -#define ZEND_CALL_INFO_SHIFT 16 +#define ZEND_CALL_HAS_THIS IS_OBJECT_EX + +/* Top 16 bits of Z_TYPE_INFO(EX(This)) are used as call_info flags */ +#define ZEND_CALL_FUNCTION (0 << 16) +#define ZEND_CALL_CODE (1 << 16) +#define ZEND_CALL_NESTED (0 << 17) +#define ZEND_CALL_TOP (1 << 17) +#define ZEND_CALL_ALLOCATED (1 << 18) +#define ZEND_CALL_FREE_EXTRA_ARGS (1 << 19) +#define ZEND_CALL_HAS_SYMBOL_TABLE (1 << 20) +#define ZEND_CALL_RELEASE_THIS (1 << 21) +#define ZEND_CALL_CLOSURE (1 << 22) +#define ZEND_CALL_FAKE_CLOSURE (1 << 23) +#define ZEND_CALL_GENERATOR (1 << 24) +#define ZEND_CALL_DYNAMIC (1 << 25) +#define ZEND_CALL_SEND_ARG_BY_REF (1 << 31) + +#define ZEND_CALL_NESTED_FUNCTION (ZEND_CALL_FUNCTION | ZEND_CALL_NESTED) +#define ZEND_CALL_NESTED_CODE (ZEND_CALL_CODE | ZEND_CALL_NESTED) +#define ZEND_CALL_TOP_FUNCTION (ZEND_CALL_TOP | ZEND_CALL_FUNCTION) +#define ZEND_CALL_TOP_CODE (ZEND_CALL_CODE | ZEND_CALL_TOP) #define ZEND_CALL_INFO(call) \ - (Z_TYPE_INFO((call)->This) >> ZEND_CALL_INFO_SHIFT) + Z_TYPE_INFO((call)->This) #define ZEND_CALL_KIND_EX(call_info) \ (call_info & (ZEND_CALL_CODE | ZEND_CALL_TOP)) @@ -527,16 +526,12 @@ struct _zend_execute_data { #define ZEND_CALL_KIND(call) \ ZEND_CALL_KIND_EX(ZEND_CALL_INFO(call)) -#define ZEND_SET_CALL_INFO(call, object, info) do { \ - Z_TYPE_INFO((call)->This) = ((object) ? IS_OBJECT_EX : IS_UNDEF) | ((info) << ZEND_CALL_INFO_SHIFT); \ - } while (0) - #define ZEND_ADD_CALL_FLAG_EX(call_info, flag) do { \ - call_info |= ((flag) << ZEND_CALL_INFO_SHIFT); \ + call_info |= (flag); \ } while (0) #define ZEND_DEL_CALL_FLAG_EX(call_info, flag) do { \ - call_info &= ~((flag) << ZEND_CALL_INFO_SHIFT); \ + call_info &= ~(flag); \ } while (0) #define ZEND_ADD_CALL_FLAG(call, flag) do { \ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bb3ca87b04264..41a20ab4d5846 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1128,6 +1128,41 @@ static zend_always_inline int zend_verify_arg_type(zend_function *zf, uint32_t a return 1; } +static zend_always_inline int zend_verify_recv_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value, void **cache_slot) +{ + zend_arg_info *cur_arg_info = &zf->common.arg_info[arg_num-1]; + zend_class_entry *ce; + + ZEND_ASSERT(arg_num <= zf->common.num_args); + cur_arg_info = &zf->common.arg_info[arg_num-1]; + + ce = NULL; + if (UNEXPECTED(!zend_check_type(cur_arg_info->type, arg, &ce, cache_slot, default_value, zf->common.scope, 0))) { + zend_verify_arg_error(zf, cur_arg_info, arg_num, ce, arg); + return 0; + } + + return 1; +} + +static zend_always_inline int zend_verify_variadic_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value, void **cache_slot) +{ + zend_arg_info *cur_arg_info; + zend_class_entry *ce; + + ZEND_ASSERT(arg_num > zf->common.num_args); + ZEND_ASSERT(zf->common.fn_flags & ZEND_ACC_VARIADIC); + cur_arg_info = &zf->common.arg_info[zf->common.num_args]; + + ce = NULL; + if (UNEXPECTED(!zend_check_type(cur_arg_info->type, arg, &ce, cache_slot, default_value, zf->common.scope, 0))) { + zend_verify_arg_error(zf, cur_arg_info, arg_num, ce, arg); + return 0; + } + + return 1; +} + static zend_never_inline int zend_verify_internal_arg_types(zend_function *fbc, zend_execute_data *call) { uint32_t i; @@ -3675,12 +3710,6 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o zend_vm_stack_free_args(EX(call)); if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) { - if (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR) { - GC_DELREF(Z_OBJ(call->This)); - if (GC_REFCOUNT(Z_OBJ(call->This)) == 1) { - zend_object_store_ctor_failed(Z_OBJ(call->This)); - } - } OBJ_RELEASE(Z_OBJ(call->This)); } if (call->func->common.fn_flags & ZEND_ACC_CLOSURE) { @@ -3729,6 +3758,12 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, if (kind == ZEND_LIVE_TMPVAR) { zval_ptr_dtor_nogc(var); + } else if (kind == ZEND_LIVE_NEW) { + zend_object *obj; + ZEND_ASSERT(Z_TYPE_P(var) == IS_OBJECT); + obj = Z_OBJ_P(var); + zend_object_store_ctor_failed(obj); + OBJ_RELEASE(obj); } else if (kind == ZEND_LIVE_LOOP) { if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) { zend_hash_iterator_del(Z_FE_ITER_P(var)); @@ -3855,13 +3890,14 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s } return zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC, - fbc, num_args, called_scope, NULL); + fbc, num_args, called_scope); } /* }}} */ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval *function, uint32_t num_args) /* {{{ */ { zend_function *fbc; + void *object_or_called_scope; zend_class_entry *called_scope; zend_object *object; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; @@ -3869,6 +3905,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval * if (EXPECTED(Z_OBJ_HANDLER_P(function, get_closure)) && EXPECTED(Z_OBJ_HANDLER_P(function, get_closure)(function, &called_scope, &fbc, &object) == SUCCESS)) { + object_or_called_scope = called_scope; if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(fbc)); @@ -3876,9 +3913,14 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval * if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } + if (object) { + call_info |= ZEND_CALL_HAS_THIS; + object_or_called_scope = object; + } } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; GC_ADDREF(object); /* For $this pointer */ + object_or_called_scope = object; } } else { zend_throw_error(NULL, "Function name must be a string"); @@ -3890,15 +3932,14 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval * } return zend_vm_stack_push_call_frame(call_info, - fbc, num_args, called_scope, object); + fbc, num_args, object_or_called_scope); } /* }}} */ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_array *function, uint32_t num_args) /* {{{ */ { zend_function *fbc; - zend_class_entry *called_scope; - zend_object *object; + void *object_or_called_scope; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; if (zend_hash_num_elements(function) == 2) { @@ -3925,8 +3966,8 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar } if (Z_TYPE_P(obj) == IS_STRING) { - object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + zend_class_entry *called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(called_scope == NULL)) { return NULL; } @@ -3948,9 +3989,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar return NULL; } } + object_or_called_scope = called_scope; } else { - called_scope = Z_OBJCE_P(obj); - object = Z_OBJ_P(obj); + zend_object *object = Z_OBJ_P(obj); fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); if (UNEXPECTED(fbc == NULL)) { @@ -3961,10 +4002,11 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar } if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { - object = NULL; + object_or_called_scope = object->ce; } else { - call_info |= ZEND_CALL_RELEASE_THIS; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; GC_ADDREF(object); /* For $this pointer */ + object_or_called_scope = object; } } } else { @@ -3977,7 +4019,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar } return zend_vm_stack_push_call_frame(call_info, - fbc, num_args, called_scope, object); + fbc, num_args, object_or_called_scope); } /* }}} */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index b82592200862b..3690dfdb4498a 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -96,20 +96,19 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) { zend_bool need_copy = ZEND_CONST_COND(value_type & (IS_CONST|IS_CV), 1) || ((value_type & IS_VAR) && UNEXPECTED(ref) && GC_REFCOUNT(ref) > 1); + zend_bool ret; if (need_copy) { ZVAL_COPY(&tmp, value); value = &tmp; } - if (!zend_verify_ref_assignable_zval(Z_REF_P(variable_ptr), value, strict)) { - if (need_copy) { - Z_TRY_DELREF_P(value); - } - zval_ptr_dtor(value); - return Z_REFVAL_P(variable_ptr); - } + ret = zend_verify_ref_assignable_zval(Z_REF_P(variable_ptr), value, strict); if (need_copy) { Z_TRY_DELREF_P(value); } + if (!ret) { + zval_ptr_dtor(value); + return Z_REFVAL_P(variable_ptr); + } } variable_ptr = Z_REFVAL_P(variable_ptr); @@ -122,39 +121,32 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value); return variable_ptr; } - if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && variable_ptr == value) { - if (value_type == IS_VAR && ref) { - ZEND_ASSERT(GC_REFCOUNT(ref) > 1); - GC_DELREF(ref); + garbage = Z_COUNTED_P(variable_ptr); + ZVAL_COPY_VALUE(variable_ptr, value); + if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } else if (value_type & (IS_CONST|IS_CV)) { + if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); + } + } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); } - return variable_ptr; } - garbage = Z_COUNTED_P(variable_ptr); if (GC_DELREF(garbage) == 0) { - ZVAL_COPY_VALUE(variable_ptr, value); - if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } else if (value_type & (IS_CONST|IS_CV)) { - if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - } - } rc_dtor_func(garbage); - return variable_ptr; } else { /* we need to split */ /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ if (UNEXPECTED(GC_MAY_LEAK(garbage))) { gc_possible_root(garbage); } } + return variable_ptr; } } while (0); @@ -214,20 +206,15 @@ ZEND_API void zend_vm_stack_init_ex(size_t page_size); ZEND_API void zend_vm_stack_destroy(void); ZEND_API void* zend_vm_stack_extend(size_t size); -static zend_always_inline void zend_vm_init_call_frame(zend_execute_data *call, uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object) +static zend_always_inline void zend_vm_init_call_frame(zend_execute_data *call, uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) { call->func = func; - if (object) { - Z_OBJ(call->This) = object; - ZEND_SET_CALL_INFO(call, 1, call_info); - } else { - Z_CE(call->This) = called_scope; - ZEND_SET_CALL_INFO(call, 0, call_info); - } + Z_PTR(call->This) = object_or_called_scope; + ZEND_CALL_INFO(call) = call_info; ZEND_CALL_NUM_ARGS(call) = num_args; } -static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object) +static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) { zend_execute_data *call = (zend_execute_data*)EG(vm_stack_top); @@ -236,11 +223,11 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(ui if (UNEXPECTED(used_stack > (size_t)(((char*)EG(vm_stack_end)) - (char*)call))) { call = (zend_execute_data*)zend_vm_stack_extend(used_stack); ZEND_ASSERT_VM_STACK_GLOBAL; - zend_vm_init_call_frame(call, call_info | ZEND_CALL_ALLOCATED, func, num_args, called_scope, object); + zend_vm_init_call_frame(call, call_info | ZEND_CALL_ALLOCATED, func, num_args, object_or_called_scope); return call; } else { EG(vm_stack_top) = (zval*)((char*)call + used_stack); - zend_vm_init_call_frame(call, call_info, func, num_args, called_scope, object); + zend_vm_init_call_frame(call, call_info, func, num_args, object_or_called_scope); return call; } } @@ -255,12 +242,12 @@ static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, ze return used_stack * sizeof(zval); } -static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object) +static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) { uint32_t used_stack = zend_vm_calc_used_stack(num_args, func); return zend_vm_stack_push_call_frame_ex(used_stack, call_info, - func, num_args, called_scope, object); + func, num_args, object_or_called_scope); } static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_info, zend_execute_data *call) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 56786ae41b5a5..4c4dbc8891a2b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -655,6 +655,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; zend_function *func; + uint32_t call_info; + void *object_or_called_scope; ZVAL_UNDEF(fci->retval); @@ -727,11 +729,18 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } func = fci_cache->function_handler; - fci->object = (func->common.fn_flags & ZEND_ACC_STATIC) ? - NULL : fci_cache->object; + if ((func->common.fn_flags & ZEND_ACC_STATIC) || !fci_cache->object) { + fci->object = NULL; + object_or_called_scope = fci_cache->called_scope; + call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC; + } else { + fci->object = fci_cache->object; + object_or_called_scope = fci->object; + call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS; + } - call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC, - func, fci->param_count, fci_cache->called_scope, fci->object); + call = zend_vm_stack_push_call_frame(call_info, + func, fci->param_count, object_or_called_scope); if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", @@ -813,7 +822,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; ZVAL_NULL(fci->retval); call->prev_execute_data = EG(current_execute_data); - call->return_value = NULL; /* this is not a constructor call */ EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ @@ -1176,7 +1184,7 @@ static void zend_timeout_handler(int dummy) /* {{{ */ output_len = snprintf(log_buffer, sizeof(log_buffer), "\nFatal error: Maximum execution time of " ZEND_LONG_FMT "+" ZEND_LONG_FMT " seconds exceeded (terminated) in %s on line %d\n", EG(timeout_seconds), EG(hard_timeout), error_filename, error_lineno); if (output_len > 0) { - write(2, log_buffer, MIN(output_len, sizeof(log_buffer))); + zend_quiet_write(2, log_buffer, MIN(output_len, sizeof(log_buffer))); } _exit(124); } diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index edb952c2cd120..7ed3078ed1e79 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -54,7 +54,7 @@ * gc_scan_black will be called on that node to scan it's subgraph. * otherwise (refcount == 0), it marks the node white. * - * A node MAY be added to possbile roots when ZEND_UNSET_VAR happens or + * A node MAY be added to possible roots when ZEND_UNSET_VAR happens or * zend_assign_to_variable is called only when possible garbage node is * produced. * gc_possible_root() will be called to add the nodes to possible roots. diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index a59d84cda7e2e..6b3f148b5b374 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -40,10 +40,7 @@ ZEND_API void zend_generator_restore_call_stack(zend_generator *generator) /* {{ (ZEND_CALL_INFO(call) & ~ZEND_CALL_ALLOCATED), call->func, ZEND_CALL_NUM_ARGS(call), - (Z_TYPE(call->This) == IS_UNDEF) ? - (zend_class_entry*)Z_OBJ(call->This) : NULL, - (Z_TYPE(call->This) != IS_UNDEF) ? - Z_OBJ(call->This) : NULL); + Z_PTR(call->This)); memcpy(((zval*)new_call) + ZEND_CALL_FRAME_SLOT, ((zval*)call) + ZEND_CALL_FRAME_SLOT, ZEND_CALL_NUM_ARGS(call) * sizeof(zval)); new_call->prev_execute_data = prev_call; prev_call = new_call; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index f95034a60ffc5..e4024d9688a03 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -64,7 +64,7 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin zend_output_debug_string(1, "%s(%d) : ht=%p is inconsistent", file, line, ht); break; } - zend_bailout(); + ZEND_ASSERT(0); } #define IS_CONSISTENT(a) _zend_is_inconsistent(a, __FILE__, __LINE__); #define SET_INCONSISTENT(n) do { \ @@ -129,7 +129,8 @@ static zend_always_inline void zend_hash_real_init_packed_ex(HashTable *ht) data = emalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK)); } HT_SET_DATA_ADDR(ht, data); - HT_FLAGS(ht) = HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS; + /* Don't overwrite iterator count. */ + ht->u.v.flags = HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS; HT_HASH_RESET_PACKED(ht); } @@ -144,7 +145,8 @@ static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht) data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE))); ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE); HT_SET_DATA_ADDR(ht, data); - HT_FLAGS(ht) = HASH_FLAG_STATIC_KEYS; + /* Don't overwrite iterator count. */ + ht->u.v.flags = HASH_FLAG_STATIC_KEYS; #ifdef __SSE2__ do { __m128i xmm0 = _mm_setzero_si128(); @@ -400,10 +402,8 @@ ZEND_API uint32_t zend_array_count(HashTable *ht) } /* }}} */ -static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable *ht) +static zend_always_inline HashPosition _zend_hash_get_valid_pos(const HashTable *ht, HashPosition pos) { - HashPosition pos = 0; - while (pos < ht->nNumUsed && Z_ISUNDEF(ht->arData[pos].val)) { pos++; } @@ -412,12 +412,7 @@ static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable static zend_always_inline HashPosition _zend_hash_get_current_pos(const HashTable *ht) { - HashPosition pos = ht->nInternalPointer; - - if (pos == 0) { - pos = _zend_hash_get_first_pos(ht); - } - return pos; + return _zend_hash_get_valid_pos(ht, ht->nInternalPointer); } ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *ht) @@ -511,6 +506,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx) if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR) && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) { + ZEND_ASSERT(HT_ITERATORS_COUNT(iter->ht) != 0); HT_DEC_ITERATORS_COUNT(iter->ht); } iter->ht = NULL; @@ -1164,6 +1160,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht) p++; } while (++i < ht->nNumUsed); } else { + uint32_t old_num_used = ht->nNumUsed; do { if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) { uint32_t j = i; @@ -1220,6 +1217,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht) HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i); p++; } while (++i < ht->nNumUsed); + + /* Migrate pointer to one past the end of the array to the new one past the end, so that + * newly inserted elements are picked up correctly. */ + if (UNEXPECTED(HT_HAS_ITERATORS(ht))) { + _zend_hash_iterators_update(ht, old_num_used, ht->nNumUsed); + } } return SUCCESS; } @@ -2023,7 +2026,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) target->nTableSize = HT_MIN_SIZE; HT_SET_DATA_ADDR(target, &uninitialized_bucket); } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) { - HT_FLAGS(target) = HT_FLAGS(source); + HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; target->nTableMask = source->nTableMask; target->nNumUsed = source->nNumUsed; target->nNumOfElements = source->nNumOfElements; @@ -2033,7 +2036,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) target->nInternalPointer = source->nInternalPointer; memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source)); } else if (HT_FLAGS(source) & HASH_FLAG_PACKED) { - HT_FLAGS(target) = HT_FLAGS(source); + HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; target->nTableMask = HT_MIN_MASK; target->nNumUsed = source->nNumUsed; target->nNumOfElements = source->nNumOfElements; @@ -2052,7 +2055,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) zend_array_dup_packed_elements(source, target, 1); } } else { - HT_FLAGS(target) = HT_FLAGS(source); + HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; target->nTableMask = source->nTableMask; target->nNextFreeElement = source->nNextFreeElement; target->nInternalPointer = @@ -2237,7 +2240,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, H { IS_CONSISTENT(ht); HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1); - *pos = _zend_hash_get_first_pos(ht); + *pos = _zend_hash_get_valid_pos(ht, 0); } @@ -2265,19 +2268,13 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, Has ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos) { - uint32_t idx = *pos; + uint32_t idx; IS_CONSISTENT(ht); HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1); + idx = _zend_hash_get_valid_pos(ht, *pos); if (idx < ht->nNumUsed) { - if (idx == 0) { - idx = _zend_hash_get_first_pos(ht); - if (idx >= ht->nNumUsed) { - *pos = idx; - return SUCCESS; - } - } while (1) { idx++; if (idx >= ht->nNumUsed) { @@ -2320,17 +2317,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPositi /* This function should be made binary safe */ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos) { - uint32_t idx = *pos; + uint32_t idx; Bucket *p; IS_CONSISTENT(ht); + idx = _zend_hash_get_valid_pos(ht, *pos); if (idx < ht->nNumUsed) { - if (idx == 0) { - idx = _zend_hash_get_first_pos(ht); - if (idx >= ht->nNumUsed) { - return HASH_KEY_NON_EXISTENT; - } - } p = ht->arData + idx; if (p->key) { *str_index = p->key; @@ -2345,20 +2337,14 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zen ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) { - uint32_t idx = *pos; + uint32_t idx; Bucket *p; IS_CONSISTENT(ht); + idx = _zend_hash_get_valid_pos(ht, *pos); if (idx >= ht->nNumUsed) { ZVAL_NULL(key); } else { - if (idx == 0) { - idx = _zend_hash_get_first_pos(ht); - if (idx >= ht->nNumUsed) { - ZVAL_NULL(key); - return; - } - } p = ht->arData + idx; if (p->key) { ZVAL_STR_COPY(key, p->key); @@ -2370,17 +2356,12 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos) { - uint32_t idx = *pos; + uint32_t idx; Bucket *p; IS_CONSISTENT(ht); + idx = _zend_hash_get_valid_pos(ht, *pos); if (idx < ht->nNumUsed) { - if (idx == 0) { - idx = _zend_hash_get_first_pos(ht); - if (idx >= ht->nNumUsed) { - return HASH_KEY_NON_EXISTENT; - } - } p = ht->arData + idx; if (p->key) { return HASH_KEY_IS_STRING; @@ -2394,17 +2375,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, Hash ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos) { - uint32_t idx = *pos; + uint32_t idx; Bucket *p; IS_CONSISTENT(ht); + idx = _zend_hash_get_valid_pos(ht, *pos); if (idx < ht->nNumUsed) { - if (idx == 0) { - idx = _zend_hash_get_first_pos(ht); - if (idx >= ht->nNumUsed) { - return NULL; - } - } p = ht->arData + idx; return &p->val; } else { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 0cc34ddd4754d..3341427428a56 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -40,6 +40,9 @@ #define HASH_FLAG_HAS_EMPTY_IND (1<<5) #define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6) +/* Only the low byte are real flags */ +#define HASH_FLAG_MASK 0xff + #define HT_FLAGS(ht) (ht)->u.flags #define HT_INVALIDATE(ht) do { \ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index af5ce87fa2dac..617868c5cabb2 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1212,6 +1212,8 @@ array_pair: { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $4, $1); } | '&' variable { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); } + | T_ELLIPSIS expr + { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); } | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')' { $5->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 5b1914c99dd19..a44a7c562d203 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -603,10 +603,15 @@ static void emit_live_range( start++; break; /* Objects created via ZEND_NEW are only fully initialized - * after the DO_FCALL (constructor call). */ + * after the DO_FCALL (constructor call). + * We are creating two live-ranges: ZEND_LINE_NEW for uninitialized + * part, and ZEND_LIVE_TMPVAR for initialized. + */ case ZEND_NEW: { int level = 0; + uint32_t orig_start = start; + while (def_opline + 1 < use_opline) { def_opline++; start++; @@ -635,6 +640,7 @@ static void emit_live_range( } } } + emit_live_range_raw(op_array, var_num, ZEND_LIVE_NEW, orig_start + 1, start + 1); if (start + 1 == end) { /* Trivial live-range, no need to store it. */ return; diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 56b7a1ada3d7e..b0eb20bf40d73 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -256,14 +256,6 @@ char *alloca(); # define ZEND_FASTCALL #endif -#ifndef restrict -# if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 -# else -# define __restrict__ -# endif -# define restrict __restrict__ -#endif - #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn) # define HAVE_NORETURN # define ZEND_NORETURN __attribute__((noreturn)) diff --git a/Zend/zend_string.c b/Zend/zend_string.c index b94d4d533403f..75e7e6249f48a 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -232,7 +232,13 @@ static zend_string* ZEND_FASTCALL zend_new_interned_string_request(zend_string * } /* Create a short living interned, freed after the request. */ - ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT)); +#if ZEND_RC_DEBUG + if (zend_rc_debug) { + /* PHP shouldn't create persistent interned string during request, + * but at least dl() may do this */ + ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT)); + } +#endif if (GC_REFCOUNT(str) > 1) { zend_ulong h = ZSTR_H(str); zend_string_delref(str); @@ -255,6 +261,7 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_permanent(const char return ret; } + ZEND_ASSERT(permanent); ret = zend_string_init(str, size, permanent); ZSTR_H(ret) = h; return zend_add_interned_string(ret, &interned_strings_permanent, IS_STR_PERMANENT); @@ -276,6 +283,13 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_request(const char * return ret; } +#if ZEND_RC_DEBUG + if (zend_rc_debug) { + /* PHP shouldn't create persistent interned string during request, + * but at least dl() may do this */ + ZEND_ASSERT(!permanent); + } +#endif ret = zend_string_init(str, size, permanent); ZSTR_H(ret) = h; diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index a6648978c4926..f327ef4cd502e 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -3751,7 +3751,7 @@ zend_dtoa */ int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + j, j1 = 0, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case = 0, try_quick; Long L; #ifndef Sudden_Underflow diff --git a/Zend/zend_types.h b/Zend/zend_types.h index a5ca56e0cf67e..3f6e1c1402b71 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -201,7 +201,6 @@ struct _zval_struct { zend_uchar type, /* active type */ zend_uchar type_flags, union { - uint16_t call_info; /* call info for EX(This) */ uint16_t extra; /* not further specified */ } u) } v; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0f74e4280e684..977d10cd5aea7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2636,11 +2636,11 @@ ZEND_VM_HANDLER(200, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C } else if (OP_DATA_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (OP_DATA_TYPE == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -2740,16 +2740,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -2771,16 +2762,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) } EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -3445,27 +3427,29 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, FREE_OP2(); } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; FREE_OP1(); if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (OP1_TYPE == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ FREE_OP1(); } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -3477,7 +3461,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -3578,33 +3562,34 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + ZEND_VM_C_GOTO(check_parent_and_self); } - } - - if (OP1_TYPE == IS_UNUSED) { + } else { +ZEND_VM_C_LABEL(check_parent_and_self): /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (OP1_TYPE == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -3632,7 +3617,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) CACHE_PTR(opline->result.num, fbc); } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3704,8 +3689,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; - zend_class_entry *called_scope; - zend_object *object; + void *object_or_called_scope; zend_execute_data *call; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; @@ -3713,8 +3697,6 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; - called_scope = fcc.called_scope; - object = fcc.object; if (error) { efree(error); /* This is the only soft error is_callable() can generate */ @@ -3724,6 +3706,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) HANDLE_EXCEPTION(); } } + object_or_called_scope = fcc.called_scope; if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); @@ -3731,18 +3714,22 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; - GC_ADDREF(object); /* For $this pointer */ + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } FREE_OP2(); if ((OP2_TYPE & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } - if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(object); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); } HANDLE_EXCEPTION(); } @@ -3758,12 +3745,11 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) HANDLE_EXCEPTION(); } func = (zend_function*)&zend_pass_function; - called_scope = NULL; - object = NULL; + object_or_called_scope = NULL; } call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, called_scope, object); + func, opline->extended_value, object_or_called_scope); call->prev_execute_data = EX(call); EX(call) = call; @@ -3796,7 +3782,7 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3827,7 +3813,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT) call = zend_vm_stack_push_call_frame_ex( opline->op1.num, ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3892,7 +3878,6 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL)) ret = NULL; if (RETURN_VALUE_USED(opline)) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -3917,7 +3902,6 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) ret = NULL; if (RETURN_VALUE_USED(opline)) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -3985,7 +3969,6 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) USE_OPLINE zend_execute_data *call = EX(call); zend_function *fbc = call->func; - zend_object *object; zval *ret; SAVE_OPLINE(); @@ -4006,7 +3989,6 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) ret = NULL; if (RETURN_VALUE_USED(opline)) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -4079,16 +4061,7 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) ZEND_VM_C_LABEL(fcall_end): if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - object = Z_OBJ(call->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(call->This)); } zend_vm_stack_free_call_frame(call); @@ -4326,7 +4299,7 @@ ZEND_VM_HANDLER(41, ZEND_GENERATOR_CREATE, ANY, ANY) gen_execute_data->return_value = (zval*)generator; call_info = Z_TYPE_INFO(EX(This)); if ((call_info & Z_TYPE_MASK) == IS_OBJECT - && (!(call_info & ((ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS) << ZEND_CALL_INFO_SHIFT)) + && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS)) /* Bug #72523 */ || UNEXPECTED(zend_execute_ex != execute_ex))) { ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); @@ -4944,13 +4917,12 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY, NUM) zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args))); if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func)); - } - if (Z_TYPE(EX(call)->This) == IS_OBJECT) { + } else if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_RELEASE_THIS) { OBJ_RELEASE(Z_OBJ(EX(call)->This)); } EX(call)->func = (zend_function*)&zend_pass_function; Z_OBJ(EX(call)->This) = NULL; - ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + ZEND_CALL_INFO(EX(call)) &= ~(ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS); FREE_UNFETCHED_OP2(); } else { uint32_t arg_num; @@ -5065,11 +5037,11 @@ ZEND_VM_HOT_HANDLER(63, ZEND_RECV, NUM, UNUSED|CACHE_SLOT) SAVE_OPLINE(); zend_missing_arg_error(execute_data); HANDLE_EXCEPTION(); - } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + } else { zval *param = EX_VAR(opline->result.var); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { + if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -5117,7 +5089,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT) zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { + if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -5146,7 +5118,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED|CACHE_SLOT) param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { - zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); + zend_verify_variadic_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); ZEND_HASH_FILL_ADD(param); param++; @@ -5315,17 +5287,16 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N /* Perform a dummy function call */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); + opline->extended_value, NULL); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, constructor, opline->extended_value, - ce, Z_OBJ_P(result)); Z_ADDREF_P(result); } @@ -5583,7 +5554,112 @@ ZEND_VM_C_LABEL(num_index): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF) +ZEND_VM_HANDLER(208, ZEND_ADD_ARRAY_UNPACK, ANY, ANY) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + + SAVE_OPLINE(); + op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); + + SEPARATE_ARRAY(EX_VAR(opline->result.var)); +ZEND_VM_C_LABEL(add_again): + if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(op1); + zval *val; + zend_string *key; + + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (key) { + zend_throw_error(NULL, "Cannot unpack array with string keys"); + FREE_OP1(); + HANDLE_EXCEPTION(); + } else { + Z_TRY_ADDREF_P(val); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + } + } + } ZEND_HASH_FOREACH_END(); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) { + zend_class_entry *ce = Z_OBJCE_P(op1); + zend_object_iterator *iter; + + if (!ce || !ce->get_iterator) { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + } else { + iter = ce->get_iterator(ce, op1, 0); + if (UNEXPECTED(!iter)) { + FREE_OP1(); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) + ); + } + HANDLE_EXCEPTION(); + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + } + + for (; iter->funcs->valid(iter) == SUCCESS; ) { + zval *val; + + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + val = iter->funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (iter->funcs->get_current_key) { + zval key; + iter->funcs->get_current_key(iter, &key); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { + zend_throw_error(NULL, + (Z_TYPE(key) == IS_STRING) ? + "Cannot unpack Traversable with string keys" : + "Cannot unpack Traversable with non-integer keys"); + zval_ptr_dtor(&key); + break; + } + } + + ZVAL_DEREF(val); + Z_TRY_ADDREF_P(val); + + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + } + + iter->funcs->move_forward(iter); + } + + zend_iterator_dtor(iter); + + } + } else if (EXPECTED(Z_ISREF_P(op1))) { + op1 = Z_REFVAL_P(op1); + ZEND_VM_C_GOTO(add_again); + } else { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + } + + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF) { zval *array; uint32_t size; @@ -5727,15 +5803,14 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL) if (RETURN_VALUE_USED(opline)) { return_value = EX_VAR(opline->result.var); - ZVAL_NULL(return_value); } new_op_array->scope = EX(func)->op_array.scope; - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, (zend_function*)new_op_array, 0, - Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, - Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); + Z_PTR(EX(This))); if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { call->symbol_table = EX(symbol_table); @@ -7222,6 +7297,10 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca zend_generator_close(generator, 1); ZEND_VM_RETURN(); } else { + /* We didn't execute RETURN, and have to initialize return_value */ + if (EX(return_value)) { + ZVAL_UNDEF(EX(return_value)); + } ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } } @@ -7260,6 +7339,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { switch (throw_op->opcode) { case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_ADD_ARRAY_UNPACK: case ZEND_ROPE_INIT: case ZEND_ROPE_ADD: break; /* exception while building structures, live range handling will free those */ @@ -7958,7 +8038,7 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, UNUSED|CLASS_FETCH, ANY) ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) { - zend_array *args; + zend_array *args = NULL; zend_function *fbc = EX(func); zval *ret = EX(return_value); uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS); @@ -7989,7 +8069,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) ZEND_CALL_NUM_ARGS(call) = 2; ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); - if (num_args) { + if (args) { ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); } else { ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2)); @@ -8379,7 +8459,7 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMP|VAR|CV, UNUSED) } else { count = 1; } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count"); } while (0); ZVAL_LONG(EX_VAR(opline->result.var), count); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 05c6101bcc09f..ad03a186b0a71 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -612,7 +612,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_us static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *prop, *value; zend_property_info *prop_info; @@ -708,7 +708,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *prop, *value; zend_property_info *prop_info; @@ -796,16 +796,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -827,16 +818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ } EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -1013,7 +995,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV ret = NULL; if (0) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1037,7 +1018,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV ret = NULL; if (1) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1062,7 +1042,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S ret = NULL; if (0) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1139,7 +1118,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S ret = NULL; if (1) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1207,7 +1185,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV USE_OPLINE zend_execute_data *call = EX(call); zend_function *fbc = call->func; - zend_object *object; zval *ret; SAVE_OPLINE(); @@ -1228,7 +1205,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ret = NULL; if (0) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1301,16 +1277,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV fcall_end: if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - object = Z_OBJ(call->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(call->This)); } zend_vm_stack_free_call_frame(call); @@ -1328,7 +1295,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV USE_OPLINE zend_execute_data *call = EX(call); zend_function *fbc = call->func; - zend_object *object; zval *ret; SAVE_OPLINE(); @@ -1349,7 +1315,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ret = NULL; if (1) { ret = EX_VAR(opline->result.var); - ZVAL_NULL(ret); } call->prev_execute_data = execute_data; @@ -1422,16 +1387,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV fcall_end: if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - object = Z_OBJ(call->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(call->This)); } zend_vm_stack_free_call_frame(call); @@ -1489,7 +1445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER( gen_execute_data->return_value = (zval*)generator; call_info = Z_TYPE_INFO(EX(This)); if ((call_info & Z_TYPE_MASK) == IS_OBJECT - && (!(call_info & ((ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS) << ZEND_CALL_INFO_SHIFT)) + && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS)) /* Bug #72523 */ || UNEXPECTED(zend_execute_ex != execute_ex))) { ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); @@ -1706,13 +1662,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args))); if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func)); - } - if (Z_TYPE(EX(call)->This) == IS_OBJECT) { + } else if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_RELEASE_THIS) { OBJ_RELEASE(Z_OBJ(EX(call)->This)); } EX(call)->func = (zend_function*)&zend_pass_function; Z_OBJ(EX(call)->This) = NULL; - ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + ZEND_CALL_INFO(EX(call)) &= ~(ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS); FREE_UNFETCHED_OP(opline->op2_type, opline->op2.var); } else { uint32_t arg_num; @@ -1798,6 +1753,111 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + + SAVE_OPLINE(); + op1 = get_zval_ptr(opline->op1_type, opline->op1, &free_op1, BP_VAR_R); + + SEPARATE_ARRAY(EX_VAR(opline->result.var)); +add_again: + if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(op1); + zval *val; + zend_string *key; + + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (key) { + zend_throw_error(NULL, "Cannot unpack array with string keys"); + FREE_OP(free_op1); + HANDLE_EXCEPTION(); + } else { + Z_TRY_ADDREF_P(val); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + } + } + } ZEND_HASH_FOREACH_END(); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) { + zend_class_entry *ce = Z_OBJCE_P(op1); + zend_object_iterator *iter; + + if (!ce || !ce->get_iterator) { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + } else { + iter = ce->get_iterator(ce, op1, 0); + if (UNEXPECTED(!iter)) { + FREE_OP(free_op1); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) + ); + } + HANDLE_EXCEPTION(); + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + } + + for (; iter->funcs->valid(iter) == SUCCESS; ) { + zval *val; + + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + val = iter->funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (iter->funcs->get_current_key) { + zval key; + iter->funcs->get_current_key(iter, &key); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { + zend_throw_error(NULL, + (Z_TYPE(key) == IS_STRING) ? + "Cannot unpack Traversable with string keys" : + "Cannot unpack Traversable with non-integer keys"); + zval_ptr_dtor(&key); + break; + } + } + + ZVAL_DEREF(val); + Z_TRY_ADDREF_P(val); + + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + } + + iter->funcs->move_forward(iter); + } + + zend_iterator_dtor(iter); + + } + } else if (EXPECTED(Z_ISREF_P(op1))) { + op1 = Z_REFVAL_P(op1); + goto add_again; + } else { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + } + + FREE_OP(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2003,6 +2063,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try_catch_finally_hel zend_generator_close(generator, 1); ZEND_VM_RETURN(); } else { + /* We didn't execute RETURN, and have to initialize return_value */ + if (EX(return_value)) { + ZVAL_UNDEF(EX(return_value)); + } ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -2041,6 +2105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { switch (throw_op->opcode) { case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_ADD_ARRAY_UNPACK: case ZEND_ROPE_INIT: case ZEND_ROPE_ADD: break; /* exception while building structures, live range handling will free those */ @@ -2173,7 +2238,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_array *args; + zend_array *args = NULL; zend_function *fbc = EX(func); zval *ret = EX(return_value); uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS); @@ -2204,7 +2269,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z ZEND_CALL_NUM_ARGS(call) = 2; ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); - if (num_args) { + if (args) { ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); } else { ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2)); @@ -2337,7 +2402,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME CACHE_PTR(opline->result.num, fbc); } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -2347,7 +2412,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *function_name; zend_execute_data *call; @@ -2426,7 +2491,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -2457,7 +2522,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO call = zend_vm_stack_push_call_frame_ex( opline->op1.num, ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL); + fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -2504,7 +2569,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { + if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -2579,11 +2644,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_SPEC_UNUSED_H SAVE_OPLINE(); zend_missing_arg_error(execute_data); HANDLE_EXCEPTION(); - } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + } else { zval *param = EX_VAR(opline->result.var); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { + if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -2611,7 +2676,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { - zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); + zend_verify_variadic_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); ZEND_HASH_FILL_ADD(param); param++; @@ -2634,7 +2699,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *function_name; zend_execute_data *call; @@ -2690,7 +2755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HAND static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; op1 = RT_CONSTANT(opline, opline->op1); @@ -2710,7 +2775,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CON { USE_OPLINE zval *val; - + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { @@ -2734,7 +2799,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CON static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *z; SAVE_OPLINE(); @@ -2763,7 +2828,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_O static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = RT_CONSTANT(opline, opline->op1); @@ -2794,7 +2859,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_H static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = RT_CONSTANT(opline, opline->op1); @@ -2825,7 +2890,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = RT_CONSTANT(opline, opline->op1); @@ -2857,7 +2922,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; int ret; @@ -2894,7 +2959,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONS static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; int ret; @@ -3000,7 +3065,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE { USE_OPLINE zval *retval_ptr; - + SAVE_OPLINE(); @@ -3060,7 +3125,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA { USE_OPLINE zval *retval; - + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); @@ -3104,7 +3169,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_ { USE_OPLINE zval *value; - + SAVE_OPLINE(); value = RT_CONSTANT(opline, opline->op1); @@ -3197,7 +3262,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS { USE_OPLINE zval *value, *arg; - + value = RT_CONSTANT(opline, opline->op1); arg = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -3214,7 +3279,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER { USE_OPLINE zval *value, *arg; - + uint32_t arg_num = opline->op2.num; if (EXPECTED(0)) { @@ -3240,7 +3305,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_C { USE_OPLINE zval *value, *arg; - + uint32_t arg_num = opline->op2.num; if (EXPECTED(1)) { @@ -3266,7 +3331,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CONST_HANDLER(Z { USE_OPLINE zval *arg, *param; - + SAVE_OPLINE(); arg = RT_CONSTANT(opline, opline->op1); @@ -3285,7 +3350,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_H { USE_OPLINE zval *val; - + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { @@ -3309,7 +3374,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_H static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *obj; zend_class_entry *ce, *scope; zend_function *clone; @@ -3375,7 +3440,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr; zval *result = EX_VAR(opline->result.var); HashTable *ht; @@ -3469,7 +3534,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN { USE_OPLINE zend_op_array *new_op_array; - + zval *inc_filename; SAVE_OPLINE(); @@ -3493,15 +3558,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN if (RETURN_VALUE_USED(opline)) { return_value = EX_VAR(opline->result.var); - ZVAL_NULL(return_value); } new_op_array->scope = EX(func)->op_array.scope; - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, (zend_function*)new_op_array, 0, - Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, - Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); + Z_PTR(EX(This))); if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { call->symbol_table = EX(symbol_table); @@ -3535,7 +3599,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *array_ptr, *result; SAVE_OPLINE(); @@ -3590,7 +3654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER( static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *array_ptr, *array_ref; SAVE_OPLINE(); @@ -3686,7 +3750,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_CONST_H SAVE_OPLINE(); if (IS_CONST != IS_UNUSED) { - + zval *ptr = RT_CONSTANT(opline, opline->op1); do { @@ -3712,7 +3776,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_CONST_H static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *ref = NULL; int ret; @@ -3761,7 +3825,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONS static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *ref = NULL; @@ -3801,7 +3865,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *result = EX_VAR(opline->result.var); @@ -3853,7 +3917,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER( zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); zval *val; - + SAVE_OPLINE(); val = RT_CONSTANT(opline, opline->op1); @@ -3954,7 +4018,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST { USE_OPLINE zval *value; - + value = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { @@ -4004,7 +4068,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_C USE_OPLINE zval *value; int result = 0; - + value = RT_CONSTANT(opline, opline->op1); if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { @@ -4070,7 +4134,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; value = RT_CONSTANT(opline, opline->op1); @@ -4081,7 +4145,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_S static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; value = RT_CONSTANT(opline, opline->op1); @@ -4093,7 +4157,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SIMPLE_SP { USE_OPLINE zval *value, *arg; - + value = RT_CONSTANT(opline, opline->op1); arg = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -4105,7 +4169,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SIMPLE { USE_OPLINE zval *value, *arg; - + uint32_t arg_num = opline->op2.num; if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { @@ -4120,7 +4184,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SIMPLE static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -4163,7 +4227,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -4206,7 +4270,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -4252,7 +4316,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -4267,7 +4331,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -4303,7 +4367,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -4331,7 +4395,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -4359,7 +4423,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -4374,7 +4438,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -4392,7 +4456,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -4410,7 +4474,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -4484,7 +4548,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -4558,7 +4622,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -4621,7 +4685,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_C static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -4684,7 +4748,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQU static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -4699,7 +4763,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -4726,7 +4790,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -4753,7 +4817,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -4780,7 +4844,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -4943,7 +5007,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONS static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; SAVE_OPLINE(); @@ -4979,7 +5043,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -5008,9 +5072,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_AR static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -5109,9 +5173,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -5212,7 +5276,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_AR static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -5225,7 +5289,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_string *op1_str, *op2_str, *str; @@ -5450,26 +5514,28 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -5481,7 +5547,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -5520,7 +5586,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { - + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -5582,33 +5648,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_CONST == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -5618,13 +5685,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *function_name; zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; - zend_class_entry *called_scope; - zend_object *object; + void *object_or_called_scope; zend_execute_data *call; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; @@ -5632,8 +5698,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS function_name = RT_CONSTANT(opline, opline->op2); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; - called_scope = fcc.called_scope; - object = fcc.object; if (error) { efree(error); /* This is the only soft error is_callable() can generate */ @@ -5643,6 +5707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS HANDLE_EXCEPTION(); } } + object_or_called_scope = fcc.called_scope; if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); @@ -5650,17 +5715,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; - GC_ADDREF(object); /* For $this pointer */ + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } - if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(object); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); } HANDLE_EXCEPTION(); } @@ -5676,12 +5745,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS HANDLE_EXCEPTION(); } func = (zend_function*)&zend_pass_function; - called_scope = NULL; - object = NULL; + object_or_called_scope = NULL; } call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, called_scope, object); + func, opline->extended_value, object_or_called_scope); call->prev_execute_data = EX(call); EX(call) = call; @@ -5762,7 +5830,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -5801,7 +5869,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C } if (IS_CONST != IS_UNUSED) { - + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -5880,7 +5948,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -5931,7 +5999,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zend_ulong hval; @@ -6011,7 +6079,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -6055,7 +6123,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO { USE_OPLINE - + zval *key, *subject; HashTable *ht; uint32_t result; @@ -6156,7 +6224,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_S static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *name; zval *val; zend_constant c; @@ -6204,7 +6272,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER /* Set the new yielded value */ if (IS_CONST != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -6270,7 +6338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ @@ -6325,7 +6393,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op, *jump_zv; HashTable *jumptable; @@ -6354,7 +6422,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op, *jump_zv; HashTable *jumptable; @@ -6388,7 +6456,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPE static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; @@ -6632,7 +6700,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; zend_long offset; HashTable *ht; @@ -7255,7 +7323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -7356,7 +7424,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -7697,26 +7765,28 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ zval_ptr_dtor_nogc(free_op2); } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -7728,7 +7798,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -7829,33 +7899,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_CONST == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -7870,8 +7941,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; - zend_class_entry *called_scope; - zend_object *object; + void *object_or_called_scope; zend_execute_data *call; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; @@ -7879,8 +7949,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; - called_scope = fcc.called_scope; - object = fcc.object; if (error) { efree(error); /* This is the only soft error is_callable() can generate */ @@ -7890,6 +7958,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV HANDLE_EXCEPTION(); } } + object_or_called_scope = fcc.called_scope; if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); @@ -7897,18 +7966,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; - GC_ADDREF(object); /* For $this pointer */ + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } zval_ptr_dtor_nogc(free_op2); if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } - if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(object); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); } HANDLE_EXCEPTION(); } @@ -7924,12 +7997,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV HANDLE_EXCEPTION(); } func = (zend_function*)&zend_pass_function; - called_scope = NULL; - object = NULL; + object_or_called_scope = NULL; } call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, called_scope, object); + func, opline->extended_value, object_or_called_scope); call->prev_execute_data = EX(call); EX(call) = call; @@ -7939,7 +8011,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -8228,7 +8300,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z /* Set the new yielded value */ if (IS_CONST != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -8406,7 +8478,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -8473,7 +8545,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z /* Set the new yielded value */ if (IS_CONST != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -8709,7 +8781,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_STATIC_PROP_SPEC_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *varname; zval *retval; zend_string *name, *tmp_name; @@ -8879,7 +8951,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -8918,7 +8990,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { - + function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -8980,33 +9052,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_CONST == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -9024,7 +9097,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP /* prevents "undefined variable opline" errors */ #if 0 || (IS_CONST != IS_UNUSED) zval *retval_ref, *retval_ptr; - + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; retval_ref = retval_ptr = RT_CONSTANT(opline, opline->op1); @@ -9115,17 +9188,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER( /* Perform a dummy function call */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); + opline->extended_value, NULL); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, constructor, opline->extended_value, - ce, Z_OBJ_P(result)); Z_ADDREF_P(result); } @@ -9138,7 +9210,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER( static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -9177,7 +9249,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U } if (IS_UNUSED != IS_UNUSED) { - + zval *offset = NULL; zend_string *str; zend_ulong hval; @@ -9256,7 +9328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA zval *varname; zend_string *name, *tmp_name; HashTable *target_symbol_table; - + SAVE_OPLINE(); @@ -9290,7 +9362,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -9343,7 +9415,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U USE_OPLINE zval *value; int result; - + zval *varname; zend_string *name, *tmp_name; HashTable *target_symbol_table; @@ -9432,7 +9504,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE /* Set the new yielded value */ if (IS_CONST != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -9498,7 +9570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE /* Set the new yielded key */ if (IS_UNUSED != IS_UNUSED) { - + zval *key = NULL; /* Consts, temporary variables and references need copying */ @@ -9553,7 +9625,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; zend_long count; @@ -9588,7 +9660,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_ } else { count = 1; } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count"); } while (0); ZVAL_LONG(EX_VAR(opline->result.var), count); @@ -9611,7 +9683,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CO ZEND_VM_NEXT_OPCODE(); } } else { - + zval *op1; SAVE_OPLINE(); @@ -9630,7 +9702,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CO static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; zend_string *type; @@ -9722,7 +9794,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -9765,7 +9837,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -9808,7 +9880,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -9823,7 +9895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); @@ -9859,7 +9931,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -9887,7 +9959,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -9915,7 +9987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -9930,7 +10002,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); @@ -9992,7 +10064,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -10055,7 +10127,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -10118,7 +10190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -10133,7 +10205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; SAVE_OPLINE(); @@ -10169,7 +10241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HAND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -10198,9 +10270,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -10299,9 +10371,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -10402,7 +10474,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_AR static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -10415,7 +10487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_string *op1_str, *op2_str, *str; @@ -10640,26 +10712,28 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -10671,7 +10745,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -10710,7 +10784,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { - + function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -10772,33 +10846,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_CONST == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -10808,13 +10883,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *function_name; zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; - zend_class_entry *called_scope; - zend_object *object; + void *object_or_called_scope; zend_execute_data *call; uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; @@ -10822,8 +10896,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; - called_scope = fcc.called_scope; - object = fcc.object; if (error) { efree(error); /* This is the only soft error is_callable() can generate */ @@ -10833,6 +10905,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H HANDLE_EXCEPTION(); } } + object_or_called_scope = fcc.called_scope; if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); @@ -10840,17 +10913,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; - GC_ADDREF(object); /* For $this pointer */ + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } - if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(object); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); } HANDLE_EXCEPTION(); } @@ -10866,12 +10943,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H HANDLE_EXCEPTION(); } func = (zend_function*)&zend_pass_function; - called_scope = NULL; - object = NULL; + object_or_called_scope = NULL; } call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, called_scope, object); + func, opline->extended_value, object_or_called_scope); call->prev_execute_data = EX(call); EX(call) = call; @@ -10881,7 +10957,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -10920,7 +10996,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C } if (IS_CV != IS_UNUSED) { - + zval *offset = EX_VAR(opline->op2.var); zend_string *str; zend_ulong hval; @@ -10996,7 +11072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zend_ulong hval; @@ -11076,7 +11152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -11120,7 +11196,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV { USE_OPLINE - + zval *key, *subject; HashTable *ht; uint32_t result; @@ -11169,7 +11245,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE /* Set the new yielded value */ if (IS_CONST != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -11235,7 +11311,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE /* Set the new yielded key */ if (IS_CV != IS_UNUSED) { - + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ @@ -11538,7 +11614,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_OR_D static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; value = EX_VAR(opline->op1.var); @@ -11549,7 +11625,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_S static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; value = EX_VAR(opline->op1.var); @@ -11560,7 +11636,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -11573,7 +11649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CON static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op, *jump_zv; HashTable *jumptable; @@ -11602,7 +11678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op, *jump_zv; HashTable *jumptable; @@ -12541,7 +12617,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -12952,15 +13028,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA if (RETURN_VALUE_USED(opline)) { return_value = EX_VAR(opline->result.var); - ZVAL_NULL(return_value); } new_op_array->scope = EX(func)->op_array.scope; - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, (zend_function*)new_op_array, 0, - Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, - Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); + Z_PTR(EX(This))); if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { call->symbol_table = EX(symbol_table); @@ -13961,7 +14036,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_ USE_OPLINE zend_free_op free_op1; zval *container; - + zval *offset; void **cache_slot = NULL; @@ -14062,7 +14137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST USE_OPLINE zend_free_op free_op1; zval *container; - + zval *offset; void **cache_slot = NULL; @@ -14375,27 +14450,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; zval_ptr_dtor_nogc(free_op1); if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ zval_ptr_dtor_nogc(free_op1); } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -16010,27 +16087,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T zval_ptr_dtor_nogc(free_op2); } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; zval_ptr_dtor_nogc(free_op1); if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ zval_ptr_dtor_nogc(free_op1); } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -17259,7 +17338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN USE_OPLINE zend_free_op free_op1; zval *container; - + zval *offset; void **cache_slot = NULL; @@ -17360,7 +17439,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA USE_OPLINE zend_free_op free_op1; zval *container; - + zval *offset; void **cache_slot = NULL; @@ -17673,27 +17752,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; zval_ptr_dtor_nogc(free_op1); if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ zval_ptr_dtor_nogc(free_op1); } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -18822,7 +18903,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CO static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var; @@ -18858,7 +18939,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var, *ret; uint32_t i; @@ -18954,7 +19035,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON } if (IS_CONST != IS_UNUSED) { - + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -19112,7 +19193,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ @@ -20045,7 +20126,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU } if (IS_UNUSED != IS_UNUSED) { - + zval *offset = NULL; zend_string *str; zend_ulong hval; @@ -20203,7 +20284,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER( /* Set the new yielded key */ if (IS_UNUSED != IS_UNUSED) { - + zval *key = NULL; /* Consts, temporary variables and references need copying */ @@ -20293,7 +20374,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER( } else { count = 1; } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count"); } while (0); ZVAL_LONG(EX_VAR(opline->result.var), count); @@ -20382,7 +20463,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var; @@ -20418,7 +20499,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var, *ret; uint32_t i; @@ -20514,7 +20595,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_ } if (IS_CV != IS_UNUSED) { - + zval *offset = EX_VAR(opline->op2.var); zend_string *str; zend_ulong hval; @@ -20672,7 +20753,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND /* Set the new yielded key */ if (IS_CV != IS_UNUSED) { - + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ @@ -20929,7 +21010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_H SAVE_OPLINE(); if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_NULL(var_ptr); + ZVAL_NULL(var_ptr); ZVAL_UNDEFINED_OP1(); } @@ -20975,7 +21056,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND SAVE_OPLINE(); if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_NULL(var_ptr); + ZVAL_NULL(var_ptr); ZVAL_UNDEFINED_OP1(); } @@ -24416,11 +24497,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_ } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -24498,11 +24579,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_ } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -24548,7 +24629,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -24587,7 +24668,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { - + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -24649,33 +24730,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_VAR == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -24795,7 +24877,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON } if (IS_CONST != IS_UNUSED) { - + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -25076,7 +25158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ @@ -27115,11 +27197,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -27197,11 +27279,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -27247,7 +27329,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -27348,33 +27430,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_VAR == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -28927,7 +29010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -28966,7 +29049,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { - + function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -29028,33 +29111,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_VAR == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -29163,17 +29247,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE /* Perform a dummy function call */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); + opline->extended_value, NULL); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, constructor, opline->extended_value, - ce, Z_OBJ_P(result)); Z_ADDREF_P(result); } @@ -29225,7 +29308,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU } if (IS_UNUSED != IS_UNUSED) { - + zval *offset = NULL; zend_string *str; zend_ulong hval; @@ -29399,7 +29482,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( /* Set the new yielded key */ if (IS_UNUSED != IS_UNUSED) { - + zval *key = NULL; /* Consts, temporary variables and references need copying */ @@ -29522,7 +29605,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_VAR_UNUSED_HANDLER( } else { count = 1; } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count"); } while (0); ZVAL_LONG(EX_VAR(opline->result.var), count); @@ -31523,11 +31606,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_ } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -31605,11 +31688,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_ } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -31655,7 +31738,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -31694,7 +31777,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { - + function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -31756,33 +31839,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_VAR == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -31831,7 +31915,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_ } if (IS_CV != IS_UNUSED) { - + zval *offset = EX_VAR(opline->op2.var); zend_string *str; zend_ulong hval; @@ -32112,7 +32196,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND /* Set the new yielded key */ if (IS_CV != IS_UNUSED) { - + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ @@ -32309,7 +32393,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *obj; zend_class_entry *ce, *scope; zend_function *clone; @@ -32378,7 +32462,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_UNUSED_ SAVE_OPLINE(); if (IS_UNUSED != IS_UNUSED) { - + zval *ptr = NULL; do { @@ -32629,7 +32713,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -32695,7 +32779,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -32761,9 +32845,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -32910,9 +32994,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -33036,7 +33120,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -33438,7 +33522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -33606,11 +33690,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -33653,7 +33737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *property; zval *container; zval variable, *variable_ptr = &variable; @@ -33687,11 +33771,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -33734,7 +33818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var; @@ -33769,7 +33853,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - + zval *class_name; USE_OPLINE @@ -33927,26 +34011,28 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -33958,7 +34044,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -33997,7 +34083,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { - + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -34059,33 +34145,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_UNUSED == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -34179,10 +34266,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; zval *offset; @@ -34214,7 +34322,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -34273,7 +34381,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE /* Set the new yielded value */ if (IS_UNUSED != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -34339,7 +34447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ @@ -34708,7 +34816,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -34857,7 +34965,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -35553,11 +35661,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -35634,11 +35742,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -35875,26 +35983,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T zval_ptr_dtor_nogc(free_op2); } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -35906,7 +36016,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -36007,39 +36117,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_UNUSED == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -36135,7 +36267,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER( /* Set the new yielded value */ if (IS_UNUSED != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -36272,7 +36404,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER( /* Set the new yielded value */ if (IS_UNUSED != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -36392,7 +36524,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER( static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - + zval *class_name; USE_OPLINE @@ -36438,7 +36570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -36477,7 +36609,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { - + function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -36539,33 +36671,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_UNUSED == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; @@ -36583,7 +36716,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED /* prevents "undefined variable opline" errors */ #if 0 || (IS_UNUSED != IS_UNUSED) zval *retval_ref, *retval_ptr; - + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; retval_ref = retval_ptr = NULL; @@ -36674,17 +36807,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER /* Perform a dummy function call */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); + opline->extended_value, NULL); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, constructor, opline->extended_value, - ce, Z_OBJ_P(result)); Z_ADDREF_P(result); } @@ -36694,6 +36826,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -36713,7 +36866,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL /* Set the new yielded value */ if (IS_UNUSED != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -36779,7 +36932,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL /* Set the new yielded key */ if (IS_UNUSED != IS_UNUSED) { - + zval *key = NULL; /* Consts, temporary variables and references need copying */ @@ -36871,7 +37024,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_H ZEND_VM_NEXT_OPCODE(); } } else { - + zval *op1; SAVE_OPLINE(); @@ -37170,7 +37323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_CV_OBJ_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -37236,7 +37389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -37302,9 +37455,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -37451,9 +37604,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -37577,7 +37730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -37979,7 +38132,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -38147,11 +38300,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_ } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -38194,7 +38347,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *property; zval *container; zval variable, *variable_ptr = &variable; @@ -38228,11 +38381,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_ } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -38275,7 +38428,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_string **rope; zval *var; @@ -38310,7 +38463,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - + zval *class_name; USE_OPLINE @@ -38468,26 +38621,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -38499,7 +38654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U USE_OPLINE zval *function_name; zend_class_entry *ce; - zend_object *object; + uint32_t call_info; zend_function *fbc; zend_execute_data *call; @@ -38538,7 +38693,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { - + function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -38600,43 +38755,65 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U } } - object = NULL; if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { zend_non_static_method_call(fbc); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } + goto check_parent_and_self; } - } - - if (IS_UNUSED == IS_UNUSED) { + } else { +check_parent_and_self: /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { if (Z_TYPE(EX(This)) == IS_OBJECT) { ce = Z_OBJCE(EX(This)); } else { ce = Z_CE(EX(This)); } } + call_info = ZEND_CALL_NESTED_FUNCTION; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); call->prev_execute_data = EX(call); EX(call) = call; ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; zval *offset; @@ -38668,7 +38845,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -38727,7 +38904,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z /* Set the new yielded value */ if (IS_UNUSED != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -38793,7 +38970,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z /* Set the new yielded key */ if (IS_CV != IS_UNUSED) { - + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ @@ -38848,7 +39025,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; op1 = EX_VAR(opline->op1.var); @@ -38868,7 +39045,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_ { USE_OPLINE zval *val; - + val = EX_VAR(opline->op1.var); if (Z_TYPE_INFO_P(val) == IS_TRUE) { @@ -38892,7 +39069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -38940,7 +39117,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -38988,7 +39165,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -39010,7 +39187,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_ SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_NULL(var_ptr); + ZVAL_NULL(var_ptr); ZVAL_UNDEFINED_OP1(); } @@ -39037,7 +39214,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -39059,7 +39236,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HA SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_NULL(var_ptr); + ZVAL_NULL(var_ptr); ZVAL_UNDEFINED_OP1(); } @@ -39086,7 +39263,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -39129,7 +39306,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); @@ -39172,7 +39349,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *z; SAVE_OPLINE(); @@ -39201,7 +39378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCO static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = EX_VAR(opline->op1.var); @@ -39232,7 +39409,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDL static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = EX_VAR(opline->op1.var); @@ -39263,7 +39440,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HAND static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; val = EX_VAR(opline->op1.var); @@ -39295,7 +39472,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; int ret; @@ -39332,7 +39509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *val; int ret; @@ -39438,7 +39615,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER( { USE_OPLINE zval *retval_ptr; - + SAVE_OPLINE(); @@ -39498,7 +39675,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDL { USE_OPLINE zval *retval; - + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); @@ -39542,7 +39719,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC { USE_OPLINE zval *value; - + SAVE_OPLINE(); value = EX_VAR(opline->op1.var); @@ -39582,7 +39759,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_H { USE_OPLINE zval *varptr, *arg; - + varptr = EX_VAR(opline->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { @@ -39619,7 +39796,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_H static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *varptr, *arg; SAVE_OPLINE(); @@ -39646,7 +39823,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZE { USE_OPLINE zval *varptr, *arg; - + uint32_t arg_num = opline->op2.num; if (EXPECTED(0)) { @@ -39694,7 +39871,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_C { USE_OPLINE zval *varptr, *arg; - + uint32_t arg_num = opline->op2.num; if (EXPECTED(1)) { @@ -39742,7 +39919,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND { USE_OPLINE zval *arg, *param; - + SAVE_OPLINE(); arg = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -39761,7 +39938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO { USE_OPLINE zval *val; - + val = EX_VAR(opline->op1.var); if (Z_TYPE_INFO_P(val) == IS_TRUE) { @@ -39785,7 +39962,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *obj; zend_class_entry *ce, *scope; zend_function *clone; @@ -39851,7 +40028,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr; zval *result = EX_VAR(opline->result.var); HashTable *ht; @@ -39945,7 +40122,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE { USE_OPLINE zend_op_array *new_op_array; - + zval *inc_filename; SAVE_OPLINE(); @@ -39969,15 +40146,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE if (RETURN_VALUE_USED(opline)) { return_value = EX_VAR(opline->result.var); - ZVAL_NULL(return_value); } new_op_array->scope = EX(func)->op_array.scope; - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, (zend_function*)new_op_array, 0, - Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, - Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); + Z_PTR(EX(This))); if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { call->symbol_table = EX(symbol_table); @@ -40011,7 +40187,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *array_ptr, *result; SAVE_OPLINE(); @@ -40066,7 +40242,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *array_ptr, *array_ref; SAVE_OPLINE(); @@ -40162,7 +40338,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_CV_HAND SAVE_OPLINE(); if (IS_CV != IS_UNUSED) { - + zval *ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); do { @@ -40188,7 +40364,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_CV_HAND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *ref = NULL; int ret; @@ -40237,7 +40413,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *ref = NULL; @@ -40277,7 +40453,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *result = EX_VAR(opline->result.var); @@ -40320,7 +40496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); zval *val; - + SAVE_OPLINE(); val = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -40421,7 +40597,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP { USE_OPLINE zval *value; - + value = EX_VAR(opline->op1.var); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { @@ -40471,7 +40647,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV USE_OPLINE zval *value; int result = 0; - + value = EX_VAR(opline->op1.var); if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { @@ -40511,7 +40687,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SP { USE_OPLINE zval *varptr, *arg; - + varptr = EX_VAR(opline->op1.var); arg = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -40529,7 +40705,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE { USE_OPLINE zval *varptr, *arg; - + uint32_t arg_num = opline->op2.num; if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { @@ -40551,7 +40727,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -40594,7 +40770,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -40637,7 +40813,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -40683,7 +40859,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -40698,7 +40874,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -40734,7 +40910,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -40762,7 +40938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -40790,7 +40966,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -40805,7 +40981,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -40867,7 +41043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -40885,7 +41061,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -40903,7 +41079,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -40977,7 +41153,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -41051,7 +41227,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -41114,7 +41290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -41177,7 +41353,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CO static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -41192,7 +41368,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -41219,7 +41395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -41246,7 +41422,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -41273,7 +41449,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -41473,7 +41649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_CONST(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *var_ptr; zval *value; @@ -41886,7 +42062,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CONST_STATI static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -41952,7 +42128,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HAND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -42072,7 +42248,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_C static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; SAVE_OPLINE(); @@ -42142,7 +42318,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -42188,9 +42364,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -42337,9 +42513,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -42463,7 +42639,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -42865,7 +43041,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -42999,7 +43175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -43115,7 +43291,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -43232,7 +43408,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -43349,7 +43525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -43465,7 +43641,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *variable_ptr; @@ -43493,7 +43669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *variable_ptr; @@ -43555,11 +43731,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -43602,7 +43778,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *property; zval *container; zval variable, *variable_ptr = &variable; @@ -43636,11 +43812,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -43683,7 +43859,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_string *op1_str, *op2_str, *str; @@ -43908,26 +44084,28 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -43937,7 +44115,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -43976,7 +44154,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS } if (IS_CONST != IS_UNUSED) { - + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -44055,7 +44233,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -44106,7 +44284,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zval *offset; zend_ulong hval; @@ -44196,7 +44374,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zval *offset; @@ -44228,7 +44406,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zend_ulong hval; @@ -44308,7 +44486,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -44352,7 +44530,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST { USE_OPLINE - + zval *key, *subject; HashTable *ht; uint32_t result; @@ -44385,7 +44563,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr; zend_bool result; @@ -44450,7 +44628,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -44516,7 +44694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ @@ -44571,7 +44749,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *varname; zval *value; zval *variable_ptr; @@ -44654,7 +44832,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; @@ -44694,7 +44872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; zend_long offset; HashTable *ht; @@ -44747,7 +44925,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; zend_long offset; HashTable *ht; @@ -46351,7 +46529,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -46500,7 +46678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zend_free_op free_op2; zval *offset; @@ -47162,7 +47340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op2, free_op_data; zval *value; @@ -47278,7 +47456,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op2, free_op_data; zval *value; @@ -47395,7 +47573,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op2, free_op_data; zval *value; @@ -47512,7 +47690,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op2, free_op_data; zval *value; @@ -47662,11 +47840,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_ } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -47743,11 +47921,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_ } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -48015,26 +48193,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA zval_ptr_dtor_nogc(free_op2); } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -48044,7 +48224,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -48549,7 +48729,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -48859,7 +49039,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -48910,7 +49090,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr; zend_bool result; @@ -48975,7 +49155,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -49404,7 +49584,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_STATIC_PROP_SPEC_CV_U static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *varname; zval *retval; zend_string *name, *tmp_name; @@ -49606,7 +49786,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -49722,7 +49902,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -49839,7 +50019,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -49956,7 +50136,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -50080,7 +50260,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU /* prevents "undefined variable opline" errors */ #if 0 || (IS_CV != IS_UNUSED) zval *retval_ref, *retval_ptr; - + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; retval_ref = retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -50122,7 +50302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -50161,7 +50341,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS } if (IS_UNUSED != IS_UNUSED) { - + zval *offset = NULL; zend_string *str; zend_ulong hval; @@ -50262,7 +50442,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL zval *varname; zend_string *name, *tmp_name; HashTable *target_symbol_table; - + SAVE_OPLINE(); @@ -50296,7 +50476,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP zval *varname; zend_string *name, *tmp_name; zend_class_entry *ce; - + SAVE_OPLINE(); @@ -50413,7 +50593,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS USE_OPLINE zval *value; int result; - + zval *varname; zend_string *name, *tmp_name; HashTable *target_symbol_table; @@ -50458,7 +50638,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr; zend_bool result; @@ -50523,7 +50703,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -50589,7 +50769,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z /* Set the new yielded key */ if (IS_UNUSED != IS_UNUSED) { - + zval *key = NULL; /* Consts, temporary variables and references need copying */ @@ -50644,7 +50824,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + HashTable *ht; zval *value; zval *variable_ptr; @@ -50744,7 +50924,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; zend_long count; @@ -50779,7 +50959,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z } else { count = 1; } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count"); } while (0); ZVAL_LONG(EX_VAR(opline->result.var), count); @@ -50802,7 +50982,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDL ZEND_VM_NEXT_OPCODE(); } } else { - + zval *op1; SAVE_OPLINE(); @@ -50821,7 +51001,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1; zend_string *type; @@ -50840,7 +51020,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -50883,7 +51063,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -50926,7 +51106,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -50972,7 +51152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -50987,7 +51167,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); @@ -51023,7 +51203,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51051,7 +51231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPC static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51079,7 +51259,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPC static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -51094,7 +51274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51156,7 +51336,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -51174,7 +51354,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_bool result; @@ -51192,7 +51372,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -51266,7 +51446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -51340,7 +51520,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -51403,7 +51583,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER( static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; double d1, d2; @@ -51466,7 +51646,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -51481,7 +51661,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51508,7 +51688,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51535,7 +51715,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; op1 = EX_VAR(opline->op1.var); @@ -51562,7 +51742,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; SAVE_OPLINE(); @@ -51762,7 +51942,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *var_ptr; zval *value; @@ -52081,7 +52261,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_HAND static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -52147,7 +52327,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zval *object; zval *property; zval *zptr; @@ -52213,7 +52393,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container, *dim, *value; SAVE_OPLINE(); @@ -52283,7 +52463,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; SAVE_OPLINE(); @@ -52329,9 +52509,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -52478,9 +52658,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; - + zval *offset; void **cache_slot = NULL; @@ -52604,7 +52784,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -53006,7 +53186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -53140,7 +53320,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -53256,7 +53436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -53373,7 +53553,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -53490,7 +53670,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *object_ptr, *orig_object_ptr; zend_free_op free_op_data; zval *value; @@ -53606,7 +53786,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *variable_ptr; @@ -53634,7 +53814,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *value; zval *variable_ptr; @@ -53662,7 +53842,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *variable_ptr; zval *value_ptr; @@ -53735,11 +53915,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_D } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -53782,7 +53962,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *property; zval *container; zval variable, *variable_ptr = &variable; @@ -53816,11 +53996,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_D } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) { variable_ptr = &EG(uninitialized_zval); } else if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_RETURNS_FUNCTION) && + opline->extended_value == ZEND_RETURNS_FUNCTION && UNEXPECTED(!Z_ISREF_P(value_ptr))) { if (UNEXPECTED(!zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr OPLINE_CC EXECUTE_DATA_CC))) { + Z_INDIRECT_P(variable_ptr), value_ptr OPLINE_CC EXECUTE_DATA_CC))) { variable_ptr = &EG(uninitialized_zval); } } else { @@ -53863,7 +54043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_D static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *op1, *op2; zend_string *op1_str, *op2_str, *str; @@ -54088,26 +54268,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA } - call_info = ZEND_CALL_NESTED_FUNCTION; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ } else if (free_op1 != object) { GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); + fbc, opline->extended_value, obj); call->prev_execute_data = EX(call); EX(call) = call; @@ -54117,7 +54299,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *expr_ptr, new_expr; SAVE_OPLINE(); @@ -54156,7 +54338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H } if (IS_CV != IS_UNUSED) { - + zval *offset = EX_VAR(opline->op2.var); zend_string *str; zend_ulong hval; @@ -54232,7 +54414,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER( static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zval *offset; zend_ulong hval; @@ -54322,7 +54504,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; zval *offset; @@ -54354,7 +54536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zend_ulong hval; @@ -54434,7 +54616,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zval *container; int result; zval *offset; @@ -54478,7 +54660,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA { USE_OPLINE - + zval *key, *subject; HashTable *ht; uint32_t result; @@ -54527,7 +54709,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { /* Constants and temporary variables aren't yieldable by reference, @@ -54593,7 +54775,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ /* Set the new yielded key */ if (IS_CV != IS_UNUSED) { - + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ @@ -56503,11 +56685,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_CV_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_CONST_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL, @@ -58238,6 +58420,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_POST_DEC_STATIC_PROP_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_ADD_ARRAY_UNPACK_SPEC_LABEL, (void*)&&ZEND_JMP_FORWARD_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -59189,16 +59372,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -59220,16 +59394,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) } EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(execute_data->This); -#if 0 - if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { -#else - if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { -#endif - GC_DELREF(object); - zend_object_store_ctor_failed(object); - } - OBJ_RELEASE(object); + OBJ_RELEASE(Z_OBJ(execute_data->This)); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -59344,6 +59509,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_SEND_ARRAY_SPEC) ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_UNPACK_SPEC): + VM_TRACE(ZEND_ADD_ARRAY_UNPACK_SPEC) + ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC): VM_TRACE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -63294,6 +63463,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_CONST): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) + ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_CONST): VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -63434,6 +63607,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) + ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR): VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -63466,6 +63643,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_NEW_SPEC_UNUSED_UNUSED) ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) + ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_UNUSED): VM_TRACE(ZEND_YIELD_SPEC_UNUSED_UNUSED) ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -63622,6 +63803,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_CV): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_CV) + ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_CV): VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_CV) ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -65512,13 +65697,22 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value) { zend_execute_data *execute_data; + void *object_or_called_scope; + uint32_t call_info; if (EG(exception) != NULL) { return; } - execute_data = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)op_array, 0, zend_get_called_scope(EG(current_execute_data)), zend_get_this_object(EG(current_execute_data))); + object_or_called_scope = zend_get_this_object(EG(current_execute_data)); + if (EXPECTED(!object_or_called_scope)) { + object_or_called_scope = zend_get_called_scope(EG(current_execute_data)); + call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE; + } else { + call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE | ZEND_CALL_HAS_THIS; + } + execute_data = zend_vm_stack_push_call_frame(call_info, + (zend_function*)op_array, 0, object_or_called_scope); if (EG(current_execute_data)) { execute_data->symbol_table = zend_rebuild_symbol_table(); } else { @@ -67355,11 +67549,11 @@ void zend_vm_init(void) ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, @@ -69090,6 +69284,7 @@ void zend_vm_init(void) ZEND_POST_DEC_STATIC_PROP_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER, ZEND_JMP_FORWARD_SPEC_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -70130,9 +70325,9 @@ void zend_vm_init(void) 2705, 2706 | SPEC_RULE_OP1, 2711, - 4449, + 4450, 2712, - 4449, + 4450, 2713 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA, 2838 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2863, @@ -70140,8 +70335,8 @@ void zend_vm_init(void) 2865, 2866 | SPEC_RULE_OP1, 2871, - 4449, - 4449, + 4450, + 4450, 2872, 2873, 2874, @@ -70194,7 +70389,8 @@ void zend_vm_init(void) 3505 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3530 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3555, - 4449 + 3556, + 4450 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -70401,7 +70597,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 = 3557 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3558 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -70409,7 +70605,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 = 3582 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3583 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -70417,7 +70613,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 = 3607 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3608 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -70428,17 +70624,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 = 3632 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3633 | 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 = 3657 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3658 | 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 = 3682 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3683 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -70449,17 +70645,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 = 3707 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3708 | 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 = 3732 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3733 | 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 = 3757 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3758 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -70470,12 +70666,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 = 3782 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3783 | 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 = 3857 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3858 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -70486,12 +70682,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 = 3932 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3933 | 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 = 4007 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 4008 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -70499,12 +70695,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 = 4082 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4083 | 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 = 4157 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4158 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -70512,75 +70708,75 @@ 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 = 4232 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4233 | 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 = 4307 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4308 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_DOUBLE) { - spec = 4400 | SPEC_RULE_OP1; + spec = 4401 | 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 = 4405 | SPEC_RULE_OP1; + spec = 4406 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4382 | SPEC_RULE_RETVAL; + spec = 4383 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4384 | SPEC_RULE_RETVAL; + spec = 4385 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4386 | SPEC_RULE_RETVAL; + spec = 4387 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4388 | SPEC_RULE_RETVAL; + spec = 4389 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4390 | SPEC_RULE_RETVAL; + spec = 4391 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4392 | SPEC_RULE_RETVAL; + spec = 4393 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4394; - } else if (op1_info == MAY_BE_LONG) { spec = 4395; - } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { + } else if (op1_info == MAY_BE_LONG) { spec = 4396; + } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { + spec = 4397; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4397; - } else if (op1_info == MAY_BE_LONG) { spec = 4398; - } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { + } else if (op1_info == MAY_BE_LONG) { spec = 4399; + } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { + spec = 4400; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 3556; + spec = 3557; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 4445; + spec = 4446; } break; case ZEND_SEND_VAR_EX: if (op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4440 | SPEC_RULE_OP1; + spec = 4441 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 4447 | SPEC_RULE_RETVAL; + spec = 4448 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -70588,17 +70784,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 = 4410 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4411 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 4446; + spec = 4447; } break; case ZEND_SEND_VAR: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4435 | SPEC_RULE_OP1; + spec = 4436 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 30f0017cbdd9d..5e6e98bb24e76 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -24,13 +24,22 @@ ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex) ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array, zval *return_value) { zend_execute_data *execute_data; + void *object_or_called_scope; + uint32_t call_info; if (EG(exception) != NULL) { return; } - execute_data = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)op_array, 0, zend_get_called_scope(EG(current_execute_data)), zend_get_this_object(EG(current_execute_data))); + object_or_called_scope = zend_get_this_object(EG(current_execute_data)); + if (EXPECTED(!object_or_called_scope)) { + object_or_called_scope = zend_get_called_scope(EG(current_execute_data)); + call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE; + } else { + call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE | ZEND_CALL_HAS_THIS; + } + execute_data = zend_vm_stack_push_call_frame(call_info, + (zend_function*)op_array, 0, object_or_called_scope); if (EG(current_execute_data)) { execute_data->symbol_table = zend_rebuild_symbol_table(); } else { diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 0fd402eeab833..09395d0b29ec8 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -902,6 +902,11 @@ _(1818, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ _(1819, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ _(1820, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ + _(1821, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ + _(1822, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1823, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1824, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ + _(1825, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ _(1826, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ _(1827, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ _(1828, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ @@ -1836,495 +1841,496 @@ _(3552, ZEND_POST_DEC_STATIC_PROP_SPEC_CV_VAR) \ _(3553, ZEND_POST_DEC_STATIC_PROP_SPEC_CV_UNUSED) \ _(3555, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ - _(3556, ZEND_JMP_FORWARD_SPEC) \ - _(3562, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3563, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3556, ZEND_ADD_ARRAY_UNPACK_SPEC) \ + _(3557, ZEND_JMP_FORWARD_SPEC) \ + _(3563, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3564, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3566, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3567, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3568, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3565, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3567, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3568, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3569, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3571, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3577, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3578, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3570, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3578, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3579, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3581, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3587, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(3588, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3580, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3582, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3588, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(3589, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3591, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3592, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(3593, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3590, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3592, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3593, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(3594, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3596, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3602, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(3603, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3595, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3597, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3603, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(3604, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3606, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3612, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3613, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3605, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3607, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3613, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3614, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3616, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3617, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3618, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3615, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3617, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3618, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3619, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3621, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3627, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3628, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3620, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3628, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3629, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3631, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3633, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(3630, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3632, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(3634, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(3636, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(3637, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3638, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3635, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(3637, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(3638, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3639, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3641, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3642, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3640, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3642, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3652, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3645, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3654, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3656, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3658, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(3655, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3657, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(3659, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(3661, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(3662, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(3663, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3660, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(3662, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(3663, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(3664, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3666, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3667, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(3668, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3665, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3667, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3668, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(3669, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3671, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3677, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(3678, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3670, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3672, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3678, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(3679, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3681, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3683, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3680, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3682, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(3684, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3686, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3687, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3688, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3685, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3687, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3688, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3689, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3691, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3692, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3693, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3690, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3692, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3693, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3694, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3696, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3702, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3703, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3695, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3703, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3704, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3706, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3712, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3713, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3705, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3707, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3713, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3714, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3716, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3717, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3718, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3715, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3717, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3718, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3719, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3721, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3727, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(3728, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3720, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3728, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(3729, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3731, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(3737, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(3738, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3730, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3732, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(3738, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(3739, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3741, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3742, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(3743, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3740, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3742, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3743, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(3744, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3746, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3752, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(3753, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3745, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3747, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3753, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(3754, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3756, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3762, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3763, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3755, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3757, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3763, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3764, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3766, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3767, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3768, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3765, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3767, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3768, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3769, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3771, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3777, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3778, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3770, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3778, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(3779, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3781, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3797, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3798, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3801, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3802, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3803, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3816, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3817, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3818, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3872, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3873, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3876, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3877, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3878, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3891, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3892, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3893, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3947, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3948, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3951, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3952, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3953, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3966, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3967, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3968, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4022, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4023, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4026, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4027, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4028, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4041, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4042, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4043, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4085, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(4086, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4087, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4088, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(4089, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(4095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4096, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4097, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(4098, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4099, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4100, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4101, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4111, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4112, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(4113, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(4143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4160, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4161, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4162, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4163, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4164, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4171, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4172, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4173, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4174, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4175, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4176, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4186, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4187, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4188, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4235, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(4236, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4237, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4238, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(4239, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(4245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4246, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4247, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(4248, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(4263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(4293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(4305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4310, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4311, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4312, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4313, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4314, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(4320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(4321, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(4322, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4323, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(4368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(4369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(4370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(4380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(4381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(4382, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4383, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED) \ - _(4384, ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4385, ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED) \ - _(4386, ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4387, ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED) \ - _(4388, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4389, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED) \ - _(4390, ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4391, ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED) \ - _(4392, ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED) \ - _(4393, ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED) \ - _(4394, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV) \ - _(4395, ZEND_POST_INC_LONG_SPEC_TMPVARCV) \ - _(4396, ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV) \ - _(4397, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV) \ - _(4398, ZEND_POST_DEC_LONG_SPEC_TMPVARCV) \ - _(4399, ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV) \ - _(4400, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(4401, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3780, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3782, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3798, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3801, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3802, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3803, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3816, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3817, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3818, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3873, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3876, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3877, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3878, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3891, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3892, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3893, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3948, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3951, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3952, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3953, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3966, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3967, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3968, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4023, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4026, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4027, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4028, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4041, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4042, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4043, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4086, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(4087, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4088, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4089, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(4090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4091, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(4096, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4097, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4098, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(4099, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4100, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4101, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4106, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4111, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4112, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4113, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(4114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4121, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4127, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(4144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4161, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4162, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4163, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4164, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4166, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4171, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4172, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4173, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4174, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4175, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4176, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4181, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4186, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4187, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4188, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4196, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4202, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4236, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(4237, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4238, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4239, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(4240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4241, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(4246, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4247, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4248, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(4249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4256, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(4264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(4294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(4306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4311, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4312, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4313, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4314, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4316, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(4321, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(4322, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(4323, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4331, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(4369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(4370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(4371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(4381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(4382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(4383, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4384, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED) \ + _(4385, ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4386, ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED) \ + _(4387, ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4388, ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED) \ + _(4389, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4390, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED) \ + _(4391, ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4392, ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED) \ + _(4393, ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED) \ + _(4394, ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED) \ + _(4395, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV) \ + _(4396, ZEND_POST_INC_LONG_SPEC_TMPVARCV) \ + _(4397, ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV) \ + _(4398, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV) \ + _(4399, ZEND_POST_DEC_LONG_SPEC_TMPVARCV) \ + _(4400, ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV) \ + _(4401, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ _(4402, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(4404, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(4405, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(4406, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(4403, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(4405, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(4406, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ _(4407, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(4409, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(4411, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(4408, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(4410, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(4412, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(4414, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(4415, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(4416, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4413, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(4415, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(4416, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(4417, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(4419, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(4420, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(4421, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4418, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4420, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4421, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(4422, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(4424, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(4430, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(4431, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(4423, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4425, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(4431, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ _(4432, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(4434, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(4437, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(4439, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(4442, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR) \ - _(4444, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV) \ - _(4445, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(4446, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(4447, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(4448, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(4448+1, ZEND_NULL) + _(4433, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(4435, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(4438, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(4440, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(4443, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR) \ + _(4445, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV) \ + _(4446, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(4447, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(4448, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(4449, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(4449+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 3e564782dcaba..6e6bb770cbe90 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -22,7 +22,7 @@ #include #include -static const char *zend_vm_opcodes_names[208] = { +static const char *zend_vm_opcodes_names[209] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -231,9 +231,10 @@ static const char *zend_vm_opcodes_names[208] = { "ZEND_POST_INC_STATIC_PROP", "ZEND_POST_DEC_STATIC_PROP", "ZEND_COPY_TMP", + "ZEND_ADD_ARRAY_UNPACK", }; -static uint32_t zend_vm_opcodes_flags[208] = { +static uint32_t zend_vm_opcodes_flags[209] = { 0x00000000, 0x00000707, 0x00000707, @@ -442,6 +443,7 @@ static uint32_t zend_vm_opcodes_flags[208] = { 0x00040307, 0x00040307, 0x00000105, + 0x00000000, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 65efc4881652f..ce2e020bc7eee 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -280,7 +280,8 @@ END_EXTERN_C() #define ZEND_POST_INC_STATIC_PROP 205 #define ZEND_POST_DEC_STATIC_PROP 206 #define ZEND_COPY_TMP 207 +#define ZEND_ADD_ARRAY_UNPACK 208 -#define ZEND_VM_LAST_OPCODE 207 +#define ZEND_VM_LAST_OPCODE 208 #endif diff --git a/acinclude.m4 b/acinclude.m4 index 6e2e4ceae64b2..6987056185e05 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1278,65 +1278,6 @@ AC_DEFUN([PHP_MISSING_TIME_R_DECL],[ AC_MSG_RESULT([done]) ]) -dnl -dnl PHP_READDIR_R_TYPE -dnl -AC_DEFUN([PHP_READDIR_R_TYPE],[ - dnl HAVE_READDIR_R is also defined by libmysql - AC_CHECK_FUNC(readdir_r,ac_cv_func_readdir_r=yes,ac_cv_func_readdir=no) - if test "$ac_cv_func_readdir_r" = "yes"; then - AC_CACHE_CHECK(for type of readdir_r, ac_cv_what_readdir_r,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#define _REENTRANT -#include -#include - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -main() { - DIR *dir; - char entry[sizeof(struct dirent)+PATH_MAX]; - struct dirent *pentry = (struct dirent *) &entry; - - dir = opendir("/"); - if (!dir) - exit(1); - if (readdir_r(dir, (struct dirent *) entry, &pentry) == 0) { - close(dir); - exit(0); - } - close(dir); - exit(1); -} - ]])],[ - ac_cv_what_readdir_r=POSIX - ],[ - AC_PREPROC_IFELSE([ - AC_LANG_SOURCE([[ -#define _REENTRANT -#include -#include -int readdir_r(DIR *, struct dirent *); - ]])],[ - ac_cv_what_readdir_r=old-style - ],[ - ac_cv_what_readdir_r=none - ]) - ],[ - ac_cv_what_readdir_r=none - ]) - ]) - case $ac_cv_what_readdir_r in - POSIX) - AC_DEFINE(HAVE_POSIX_READDIR_R,1,[whether you have POSIX readdir_r]);; - old-style) - AC_DEFINE(HAVE_OLD_READDIR_R,1,[whether you have old-style readdir_r]);; - esac - fi -]) - dnl dnl PHP_STRUCT_FLOCK dnl @@ -1964,64 +1905,6 @@ AC_DEFUN([PHP_SETUP_ICU],[ fi ]) -dnl -dnl PHP_SETUP_KERBEROS(shared-add [, action-found [, action-not-found]]) -dnl -dnl Common setup macro for kerberos -dnl -AC_DEFUN([PHP_SETUP_KERBEROS],[ - found_kerberos=no - unset KERBEROS_CFLAGS - unset KERBEROS_LIBS - - dnl First try to find krb5-config - if test -z "$KRB5_CONFIG"; then - AC_PATH_PROG(KRB5_CONFIG, krb5-config, no, [$PATH:/usr/kerberos/bin:/usr/local/bin]) - fi - - dnl If krb5-config is found try using it - if test "$PHP_KERBEROS" != "no" && test -x "$KRB5_CONFIG"; then - KERBEROS_LIBS=`$KRB5_CONFIG --libs gssapi` - KERBEROS_CFLAGS=`$KRB5_CONFIG --cflags gssapi` - - if test -n "$KERBEROS_LIBS"; then - found_kerberos=yes - PHP_EVAL_LIBLINE($KERBEROS_LIBS, $1) - PHP_EVAL_INCLINE($KERBEROS_CFLAGS) - fi - fi - - dnl If still not found use old skool method - if test "$found_kerberos" = "no"; then - - if test "$PHP_KERBEROS" = "yes"; then - PHP_KERBEROS="/usr/kerberos /usr/local /usr" - fi - - for i in $PHP_KERBEROS; do - if test -f $i/$PHP_LIBDIR/libkrb5.a || test -f $i/$PHP_LIBDIR/libkrb5.$SHLIB_SUFFIX_NAME; then - PHP_KERBEROS_DIR=$i - break - fi - done - - if test "$PHP_KERBEROS_DIR"; then - found_kerberos=yes - PHP_ADD_LIBPATH($PHP_KERBEROS_DIR/$PHP_LIBDIR, $1) - PHP_ADD_LIBRARY(gssapi_krb5, 1, $1) - PHP_ADD_LIBRARY(krb5, 1, $1) - PHP_ADD_LIBRARY(k5crypto, 1, $1) - PHP_ADD_LIBRARY(com_err, 1, $1) - PHP_ADD_INCLUDE($PHP_KERBEROS_DIR/include) - fi - fi - - if test "$found_kerberos" = "yes"; then -ifelse([$2],[],:,[$2]) -ifelse([$3],[],,[else $3]) - fi -]) - dnl dnl PHP_SETUP_OPENSSL(shared-add [, action-found [, action-not-found]]) dnl @@ -2112,7 +1995,8 @@ AC_DEFUN([PHP_SETUP_ICONV], [ fi if test -f $ICONV_DIR/$PHP_LIBDIR/lib$iconv_lib_name.a || - test -f $ICONV_DIR/$PHP_LIBDIR/lib$iconv_lib_name.$SHLIB_SUFFIX_NAME + test -f $ICONV_DIR/$PHP_LIBDIR/lib$iconv_lib_name.$SHLIB_SUFFIX_NAME || + test -f $ICONV_DIR/$PHP_LIBDIR/lib$iconv_lib_name.tbd then PHP_CHECK_LIBRARY($iconv_lib_name, libiconv, [ found_iconv=yes @@ -2150,76 +2034,14 @@ dnl dnl Common setup macro for libxml dnl AC_DEFUN([PHP_SETUP_LIBXML], [ - found_libxml=no - - dnl First try to find xml2-config - AC_CACHE_CHECK([for xml2-config path], ac_cv_php_xml2_config_path, - [ - for i in $PHP_LIBXML_DIR /usr/local /usr; do - if test -x "$i/bin/xml2-config"; then - ac_cv_php_xml2_config_path="$i/bin/xml2-config" - break - fi - done - ]) + PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.7.6]) - if test -x "$ac_cv_php_xml2_config_path"; then - XML2_CONFIG="$ac_cv_php_xml2_config_path" - libxml_full_version=`$XML2_CONFIG --version` - ac_IFS=$IFS - IFS="." - set $libxml_full_version - IFS=$ac_IFS - LIBXML_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` - if test "$LIBXML_VERSION" -ge "2007006"; then - found_libxml=yes - LIBXML_LIBS=`$XML2_CONFIG --libs` - LIBXML_INCS=`$XML2_CONFIG --cflags` - else - AC_MSG_ERROR([libxml2 version 2.7.6 or greater required.]) - fi - fi - - dnl If xml2-config fails, try pkg-config - if test "$found_libxml" = "no"; then - if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - fi - - dnl If pkg-config is found try using it - if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libxml-2.0; then - if $PKG_CONFIG --atleast-version=2.6.11 libxml-2.0; then - found_libxml=yes - LIBXML_LIBS=`$PKG_CONFIG --libs libxml-2.0` - LIBXML_INCS=`$PKG_CONFIG --cflags-only-I libxml-2.0` - else - AC_MSG_ERROR([libxml2 version 2.6.11 or greater required.]) - fi - fi - fi + PHP_EVAL_INCLINE($LIBXML_CFLAGS) + PHP_EVAL_LIBLINE($LIBXML_LIBS, $1) - if test "$found_libxml" = "yes"; then - PHP_EVAL_LIBLINE($LIBXML_LIBS, $1) - PHP_EVAL_INCLINE($LIBXML_INCS) + AC_DEFINE(HAVE_LIBXML, 1, [ ]) - dnl Check that build works with given libs - AC_CACHE_CHECK(whether libxml build works, php_cv_libxml_build_works, [ - PHP_TEST_BUILD(xmlInitParser, - [ - php_cv_libxml_build_works=yes - ], [ - AC_MSG_RESULT(no) - AC_MSG_ERROR([build test failed. Please check the config.log for details.]) - ], [ - [$]$1 - ]) - ]) - if test "$php_cv_libxml_build_works" = "yes"; then - AC_DEFINE(HAVE_LIBXML, 1, [ ]) - fi - $2 -ifelse([$3],[],,[else $3]) - fi + $2 ]) dnl ------------------------------------------------------------------------- diff --git a/appveyor/build.bat b/appveyor/build.bat index 0beee511ee19e..c8005734e16eb 100644 --- a/appveyor/build.bat +++ b/appveyor/build.bat @@ -1,6 +1,6 @@ @echo off -set SDK_REMOTE=https://github.com/OSTC/php-sdk-binary-tools.git +set SDK_REMOTE=https://github.com/Microsoft/php-sdk-binary-tools.git set SDK_BRANCH=%PHP_BUILD_SDK_BRANCH% set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat diff --git a/build/build.mk b/build/build.mk index b3fa3e2285089..46cb0c3360ab8 100644 --- a/build/build.mk +++ b/build/build.mk @@ -18,22 +18,35 @@ # Makefile to generate build tools # -SUBDIRS = Zend TSRM +subdirs = Zend TSRM +stamp = buildmk.stamp +config_h_in = main/php_config.h.in +PHP_AUTOCONF = autoconf +PHP_AUTOHEADER = autoheader +PHP_AUTOCONF_FLAGS = -f -STAMP = buildmk.stamp +all: $(stamp) configure $(config_h_in) -ALWAYS = generated_lists +$(stamp): build/buildcheck.sh + @build/buildcheck.sh $@ +configure: aclocal.m4 configure.ac $(PHP_M4_FILES) + @echo rebuilding $@ + @rm -f $@ + @$(PHP_AUTOCONF) $(PHP_AUTOCONF_FLAGS) -all: $(STAMP) $(ALWAYS) - @$(MAKE) -s -f build/build2.mk +aclocal.m4: configure.ac acinclude.m4 + @echo rebuilding $@ + @cat acinclude.m4 ./build/libtool.m4 > $@ -generated_lists: - @echo config_m4_files = Zend/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \ - Zend/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@ - -$(STAMP): build/buildcheck.sh - @build/buildcheck.sh $(STAMP) +$(config_h_in): configure +# Explicitly remove target since autoheader does not seem to work correctly +# otherwise (timestamps are not updated). Also disable PACKAGE_* symbols in the +# generated php_config.h.in template. + @echo rebuilding $@ + @rm -f $@ + @$(PHP_AUTOHEADER) $(PHP_AUTOCONF_FLAGS) + @sed -e 's/^#undef PACKAGE_[^ ]*/\/\* & \*\//g' < $@ > $@.tmp && mv $@.tmp $@ snapshot: distname='$(DISTNAME)'; \ @@ -43,8 +56,8 @@ snapshot: myname=`basename \`pwd\`` ; \ cd .. && cp -rp $$myname $$distname; \ cd $$distname; \ - rm -f $(SUBDIRS) 2>/dev/null || true; \ - for i in $(SUBDIRS); do \ + rm -f $(subdirs) 2>/dev/null || true; \ + for i in $(subdirs); do \ test -d $$i || (test -d ../$$i && cp -rp ../$$i $$i); \ done; \ find . -type l -exec rm {} \; ; \ @@ -64,4 +77,4 @@ gitclean-work: fi; \ git clean -X -f -d; -.PHONY: $(ALWAYS) snapshot +.PHONY: snapshot diff --git a/build/build2.mk b/build/build2.mk deleted file mode 100644 index 79824cab8f1ec..0000000000000 --- a/build/build2.mk +++ /dev/null @@ -1,44 +0,0 @@ -# +----------------------------------------------------------------------+ -# | PHP Version 7 | -# +----------------------------------------------------------------------+ -# | Copyright (c) The PHP Group | -# +----------------------------------------------------------------------+ -# | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt | -# | If you did not receive a copy of the PHP license and are unable to | -# | obtain it through the world-wide-web, please send a note to | -# | license@php.net so we can mail you a copy immediately. | -# +----------------------------------------------------------------------+ -# | Author: Sascha Schumann | -# +----------------------------------------------------------------------+ - -include generated_lists - -config_h_in = main/php_config.h.in - -targets = configure $(config_h_in) - -PHP_AUTOCONF ?= 'autoconf' -PHP_AUTOHEADER ?= 'autoheader' - -SUPPRESS_WARNINGS ?= 2>&1 | (egrep -v '(AC_PROG_CXXCPP was called before AC_PROG_CXX|defined in acinclude.m4 but never used)'||true) - -all: $(targets) - -$(config_h_in): configure -# explicitly remove target since autoheader does not seem to work -# correctly otherwise (timestamps are not updated) - @echo rebuilding $@ - @rm -f $@ - $(PHP_AUTOHEADER) $(SUPPRESS_WARNINGS) - -aclocal.m4: configure.ac acinclude.m4 - @echo rebuilding $@ - cat acinclude.m4 ./build/libtool.m4 > $@ - -configure: aclocal.m4 configure.ac $(config_m4_files) - @echo rebuilding $@ - @rm -f $@ - $(PHP_AUTOCONF) -f $(SUPPRESS_WARNINGS) diff --git a/buildconf b/buildconf index ad9febfef50f2..6e644df4b8054 100755 --- a/buildconf +++ b/buildconf @@ -3,6 +3,8 @@ # A wrapper around Autoconf that generates files to build PHP on *nix systems. MAKE=${MAKE:-make} +PHP_AUTOCONF=${PHP_AUTOCONF:-autoconf} +PHP_AUTOHEADER=${PHP_AUTOHEADER:-autoheader} force=0 debug=0 @@ -91,10 +93,14 @@ fi echo "buildconf: Building configure files" -rm -f generated_lists - if test "$debug" = "1"; then - $MAKE -s -f build/build.mk SUPPRESS_WARNINGS="" + autoconf_flags="-f -Wall" else - $MAKE -s -f build/build.mk + autoconf_flags="-f" fi + +$MAKE -s -f build/build.mk \ + PHP_AUTOCONF="$PHP_AUTOCONF" \ + PHP_AUTOHEADER="$PHP_AUTOHEADER" \ + PHP_AUTOCONF_FLAGS="$autoconf_flags" \ + PHP_M4_FILES="$(echo TSRM/*.m4 Zend/Zend.m4 ext/*/config*.m4 sapi/*/config*.m4)" diff --git a/configure.ac b/configure.ac index 473c05192b6b8..ec3f28c768107 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,5 @@ dnl ## Process this file with autoconf to produce a configure script. -dnl include Zend specific macro definitions first -dnl ------------------------------------------------------------------------- -sinclude(Zend/acinclude.m4) - dnl Basic autoconf initialization, generation of config.nice. dnl ------------------------------------------------------------------------- @@ -717,7 +713,6 @@ fi AC_REPLACE_FUNCS(strlcat strlcpy explicit_bzero getopt) AC_FUNC_ALLOCA PHP_TIME_R_TYPE -PHP_READDIR_R_TYPE PHP_CHECK_IN_ADDR_T AC_CHECK_FUNCS(crypt_r, [ php_crypt_r="1" ], [ php_crypt_r="0" ]) diff --git a/docs/input-filter.md b/docs/input-filter.md index bca7f29ad2334..29de4380fd8cc 100644 --- a/docs/input-filter.md +++ b/docs/input-filter.md @@ -1,26 +1,23 @@ -Input Filter Support in PHP 5 ------------------------------ - -XSS (Cross Site Scripting) hacks are becoming more and more prevalent, -and can be quite difficult to prevent. Whenever you accept user data -and somehow display this data back to users, you are likely vulnerable -to XSS hacks. - -The Input Filter support in PHP 5 is aimed at providing the framework -through which a company-wide or site-wide security policy can be -enforced. It is implemented as a SAPI hook and is called from the -treat_data and post handler functions. To implement your own security -policy you will need to write a standard PHP extension. There is also -a powerful standard implementation in ext/filter that should suit most -peoples' needs. However, if you want to implement your own security -policy, read on. - -A simple implementation might look like the following. This stores the -original raw user data and adds a my_get_raw() function while the normal -$_POST, $_GET and $_COOKIE arrays are only populated with stripped -data. In this simple example all I am doing is calling strip_tags() on -the data. - +# Input filter support in PHP + +XSS (Cross Site Scripting) hacks are becoming more and more prevalent, and can +be quite difficult to prevent. Whenever you accept user data and somehow display +this data back to users, you are likely vulnerable to XSS hacks. + +The Input Filter support in PHP is aimed at providing the framework through +which a company-wide or site-wide security policy can be enforced. It is +implemented as a SAPI hook and is called from the `treat_data` and post handler +functions. To implement your own security policy you will need to write a +standard PHP extension. There is also a powerful standard implementation in +`ext/filter` that should suit most peoples' needs. However, if you want to +implement your own security policy, read on. + +A simple implementation might look like the following. This stores the original +raw user data and adds a `my_get_raw()` function while the normal `$_POST`, +`$_GET` and `$_COOKIE` arrays are only populated with stripped data. In this +simple example all I am doing is calling `strip_tags()` on the data. + +```c ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) zval *post_array; zval *get_array; @@ -180,3 +177,4 @@ PHP_FUNCTION(my_get_raw) RETVAL_FALSE; } } +``` diff --git a/docs/mailinglist-rules.md b/docs/mailinglist-rules.md index 8fafbd717dfac..8bdf9752d0477 100644 --- a/docs/mailinglist-rules.md +++ b/docs/mailinglist-rules.md @@ -1,6 +1,4 @@ -==================== - Mailinglist Rules -==================== +# Mailinglist rules This is the first file you should be reading before doing any posts on PHP mailinglists. Following these rules is considered imperative to the success of @@ -21,7 +19,6 @@ following some basic rules with regards to mailinglist usage will: d. Increase the general level of good will on planet Earth. - Having said that, here are the organizational rules: 1. Respect other people working on the project. @@ -30,9 +27,9 @@ Having said that, here are the organizational rules: your post after a good breather or a good nights sleep. 3. Make sure you pick the right mailinglist for your posting. Please review - the descriptions on the mailinglist overview page - (http://www.php.net/mailing-lists.php). When in doubt ask a friend or - someone you trust on IRC. + the descriptions on the + [mailinglist overview page](https://www.php.net/mailing-lists.php). When + in doubt ask a friend or someone you trust on IRC. 4. Make sure you know what you are talking about. PHP is a very large project that strives to be very open. The flip side is that the core developers @@ -72,7 +69,7 @@ The next few rules are more some general hints: new thread. Finally, additional hints on how to behave inside the virtual community can be -found in RFC 1855 (http://www.faqs.org/rfcs/rfc1855.html). +found in [RFC 1855](http://www.faqs.org/rfcs/rfc1855.html). Happy hacking, diff --git a/docs/output-api.md b/docs/output-api.md index 3c23c8e8de3d3..73876c4732194 100644 --- a/docs/output-api.md +++ b/docs/output-api.md @@ -1,139 +1,136 @@ -API adjustment to the old output control code: +# API adjustment to the old output control code - Everything now resides beneath the php_output namespace, - and there's an API call for every output handler op. +Everything now resides beneath the php_output namespace, and there's an API call +for every output handler op. - Checking output control layers status: - // Using OG() - php_output_get_status(); + Checking output control layers status: + // Using OG() + php_output_get_status(); - Starting the default output handler: - // php_start_ob_buffer(NULL, 0, 1); - php_output_start_default(); + Starting the default output handler: + // php_start_ob_buffer(NULL, 0, 1); + php_output_start_default(); - Starting an user handler by zval: - // php_start_ob_buffer(zhandler, chunk_size, erase); - php_output_start_user(zhandler, chunk_size, flags); + Starting an user handler by zval: + // php_start_ob_buffer(zhandler, chunk_size, erase); + php_output_start_user(zhandler, chunk_size, flags); - Starting an internal handler without context: - // php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase); - php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags); - - Starting an internal handler with context: - // not possible with old API - php_output_handler *h; - h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags); - php_output_handler_set_context(h, my_context, my_context_dtor); - php_output_handler_start(h); - - Testing whether a certain output handler has already been started: - // php_ob_handler_used("output handler name"); - php_output_handler_started(handler_name, handler_name_len); - - Flushing one output buffer: - // php_end_ob_buffer(1, 1); - php_output_flush(); - - Flushing all output buffers: - // not possible with old API - php_output_flush_all(); - - Cleaning one output buffer: - // php_ob_end_buffer(0, 1); - php_output_clean(); - - Cleaning all output buffers: - // not possible with old API - php_output_clean_all(); - - Discarding one output buffer: - // php_ob_end_buffer(0, 0); - php_output_discard(); - - Discarding all output buffers: - // php_ob_end_buffers(0); - php_output_discard_all(); - - Stopping (and dropping) one output buffer: - // php_ob_end_buffer(1, 0) - php_output_end(); - - Stopping (and dropping) all output buffers: - // php_ob_end_buffers(1, 0); - php_output_end_all(); - - Retrieving output buffers contents: - // php_ob_get_buffer(zstring); - php_output_get_contents(zstring); - - Retrieving output buffers length: - // php_ob_get_length(zlength); - php_output_get_length(zlength); - - Retrieving output buffering level: - // OG(nesting_level); - php_output_get_level(); - - Issue a warning because of an output handler conflict: - // php_ob_init_conflict("to be started handler name", "to be tested if already started handler name"); - php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len); - - Registering a conflict checking function, which will be checked prior starting the handler: - // not possible with old API, unless hardcoding into output.c - php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t); - - Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler: - // not possible with old API - php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t); - - Facilitating a context from within an output handler callable with ob_start(): - // not possible with old API - php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr); - - Disabling of the output handler by itself: - //not possible with old API - php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL); - - Marking an output handler immutable by itself because of irreversibility of its operation: - // not possible with old API - php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL); - - Restarting the output handler because of a CLEAN operation: - // not possible with old API - if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... } - - Recognizing by the output handler itself if it gets discarded: - // not possible with old API - if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... } - - -Output handler hooks - - The output handler can change its abilities at runtime. Eg. the gz handler can - remove the CLEANABLE and REMOVABLE bits when the first output has passed through it; - or handlers implemented in C to be used with ob_start() can contain a non-global - context: - PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ - pass a void*** pointer as second arg to receive the address of a pointer - pointer to the opaque field of the output handler context - PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS - pass a int* pointer as second arg to receive the flags set for the output handler - PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL - pass a int* pointer as second arg to receive the level of this output handler - (starts with 0) - PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE - the second arg is ignored; marks the output handler to be neither cleanable - nor removable - PHP_OUTPUT_HANDLER_HOOK_DISABLE - the second arg is ignored; marks the output handler as disabled - - -Open questions - - Should the userland API be adjusted and unified? - - Many bits of the manual (and very first implementation) do not comply - with the behaviour of the current (to be obsoleted) code, thus should - the manual or the behaviour be adjusted? - -END + Starting an internal handler without context: + // php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase); + php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags); + + Starting an internal handler with context: + // not possible with old API + php_output_handler *h; + h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags); + php_output_handler_set_context(h, my_context, my_context_dtor); + php_output_handler_start(h); + + Testing whether a certain output handler has already been started: + // php_ob_handler_used("output handler name"); + php_output_handler_started(handler_name, handler_name_len); + + Flushing one output buffer: + // php_end_ob_buffer(1, 1); + php_output_flush(); + + Flushing all output buffers: + // not possible with old API + php_output_flush_all(); + + Cleaning one output buffer: + // php_ob_end_buffer(0, 1); + php_output_clean(); + + Cleaning all output buffers: + // not possible with old API + php_output_clean_all(); + + Discarding one output buffer: + // php_ob_end_buffer(0, 0); + php_output_discard(); + + Discarding all output buffers: + // php_ob_end_buffers(0); + php_output_discard_all(); + + Stopping (and dropping) one output buffer: + // php_ob_end_buffer(1, 0) + php_output_end(); + + Stopping (and dropping) all output buffers: + // php_ob_end_buffers(1, 0); + php_output_end_all(); + + Retrieving output buffers contents: + // php_ob_get_buffer(zstring); + php_output_get_contents(zstring); + + Retrieving output buffers length: + // php_ob_get_length(zlength); + php_output_get_length(zlength); + + Retrieving output buffering level: + // OG(nesting_level); + php_output_get_level(); + + Issue a warning because of an output handler conflict: + // php_ob_init_conflict("to be started handler name", "to be tested if already started handler name"); + php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len); + + Registering a conflict checking function, which will be checked prior starting the handler: + // not possible with old API, unless hardcoding into output.c + php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t); + + Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler: + // not possible with old API + php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t); + + Facilitating a context from within an output handler callable with ob_start(): + // not possible with old API + php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr); + + Disabling of the output handler by itself: + //not possible with old API + php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL); + + Marking an output handler immutable by itself because of irreversibility of its operation: + // not possible with old API + php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL); + + Restarting the output handler because of a CLEAN operation: + // not possible with old API + if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... } + + Recognizing by the output handler itself if it gets discarded: + // not possible with old API + if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... } + +## Output handler hooks + +The output handler can change its abilities at runtime. Eg. the gz handler can +remove the CLEANABLE and REMOVABLE bits when the first output has passed through it; +or handlers implemented in C to be used with ob_start() can contain a non-global +context: + + PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ + pass a void*** pointer as second arg to receive the address of a pointer + pointer to the opaque field of the output handler context + PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS + pass a int* pointer as second arg to receive the flags set for the output handler + PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL + pass a int* pointer as second arg to receive the level of this output handler + (starts with 0) + PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE + the second arg is ignored; marks the output handler to be neither cleanable + nor removable + PHP_OUTPUT_HANDLER_HOOK_DISABLE + the second arg is ignored; marks the output handler as disabled + +## Open questions + +* Should the userland API be adjusted and unified? + +Many bits of the manual (and very first implementation) do not comply with the +behaviour of the current (to be obsoleted) code, thus should the manual or the +behaviour be adjusted? diff --git a/docs/parameter-parsing-api.md b/docs/parameter-parsing-api.md index f65c19a72392a..d4d24b1dbfa79 100644 --- a/docs/parameter-parsing-api.md +++ b/docs/parameter-parsing-api.md @@ -1,133 +1,140 @@ -Fast Parameter Parsing API -========================== +# Fast Parameter Parsing API -In PHP 7, a "Fast Parameter Parsing API" was introduced. See +In PHP 7, a "Fast Parameter Parsing API" was introduced. See +[RFC](https://wiki.php.net/rfc/fast_zpp). - https://wiki.php.net/rfc/fast_zpp +This API uses inlining to improve applications performance compared with the +`zend_parse_parameters()` function described below. -This API uses inlining to improve applications performance compared -with the zend_parse_parameters() function described below. +## Parameter parsing functions +Borrowing from Python's example, there is a set of functions that given the +string of type specifiers, can parse the input parameters and store the results +in the user specified variables. This avoids using `IS_*` checks and +`convert_to_*` conversions. The functions also check for the appropriate number +of parameters, and try to output meaningful error messages. -Parameter parsing functions -=========================== +## Prototypes -Borrowing from Python's example, there is a set of functions that -given the string of type specifiers, can parse the input parameters -and store the results in the user specified variables. This avoids -using IS_* checks and convert_to_* conversions. The functions also -check for the appropriate number of parameters, and try to output -meaningful error messages. - - -Prototypes ----------- +```c /* Implemented. */ int zend_parse_parameters(int num_args, char *type_spec, ...); int zend_parse_parameters_ex(int flags, int num_args, char *type_spec, ...); +``` -The zend_parse_parameters() function takes the number of parameters -passed to the extension function, the type specifier string, and the -list of pointers to variables to store the results in. The _ex() version -also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can -be used as 'flags' to specify that the function should operate quietly -and not output any error messages. +The `zend_parse_parameters()` function takes the number of parameters passed to +the extension function, the type specifier string, and the list of pointers to +variables to store the results in. The _ex() version also takes 'flags' argument +-- current only `ZEND_PARSE_PARAMS_QUIET` can be used as 'flags' to specify that +the function should operate quietly and not output any error messages. -Both functions return SUCCESS or FAILURE depending on the result. +Both functions return `SUCCESS` or `FAILURE` depending on the result. -The auto-conversions are performed as necessary. Arrays, objects, and -resources cannot be auto-converted. +The auto-conversions are performed as necessary. Arrays, objects, and resources +cannot be auto-converted. PHP 5.3 includes a new function (actually implemented as macro): +```c int zend_parse_parameters_none(); +``` -This returns SUCCESS if no argument has been passed to the function, -FAILURE otherwise. +This returns `SUCCESS` if no argument has been passed to the function, `FAILURE` +otherwise. PHP 5.5 includes a new function: +```c int zend_parse_parameter(int flags, int arg_num, zval **arg, const char *spec, ...); +``` -This function behaves like zend_parse_parameters_ex() except that instead of +This function behaves like `zend_parse_parameters_ex()` except that instead of reading the arguments from the stack, it receives a single zval to convert (passed with double indirection). The passed zval may be changed in place as part of the conversion process. -See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter - - -Type specifiers ---------------- - The following list shows the type specifier, its meaning and the parameter - types that need to be passed by address. All passed parameters are set - if the PHP parameter is non optional and untouched if optional and the - parameter is not present. The only exception is O where the zend_class_entry* - has to be provided on input and is used to verify the PHP parameter is an - instance of that class. - - a - array (zval*) - A - array or object (zval*) - b - boolean (zend_bool) - C - class (zend_class_entry*) - d - double (double) - f - function or array containing php method call info (returned as - zend_fcall_info and zend_fcall_info_cache) - h - array (returned as HashTable*) - H - array or HASH_OF(object) (returned as HashTable*) - l - long (zend_long) - L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN) - o - object of any type (zval*) - O - object of specific type given by class entry (zval*, zend_class_entry) - p - valid path (string without null bytes in the middle) and its length (char*, size_t) - P - valid path (string without null bytes in the middle) as zend_string (zend_string*) - r - resource (zval*) - s - string (with possible null bytes) and its length (char*, size_t) - S - string (with possible null bytes) as zend_string (zend_string*) - z - the actual zval (zval*) - * - variable arguments list (0 or more) - + - variable arguments list (1 or more) - - The following characters also have a meaning in the specifier string: - | - indicates that the remaining parameters are optional, they - should be initialized to default values by the extension since they - will not be touched by the parsing function if they are not - passed to it. - / - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows - ! - the parameter it follows can be of specified type or NULL. If NULL is - passed and the output for such type is a pointer, then the output - pointer is set to a native NULL pointer. - For 'b', 'l' and 'd', an extra argument of type zend_bool* must be - passed after the corresponding bool*, zend_long* or double* arguments, - respectively. A non-zero value will be written to the zend_bool if a - PHP NULL is passed. - - -Note on 64bit compatibility ---------------------------- -Please note that since version 7 PHP uses zend_long as integer type and -zend_string with size_t as length, so make sure you pass zend_longs to "l" -and size_t to strings length (i.e. for "s" you need to pass char * and size_t), -not the other way round! +See also +[Expose zend_parse_arg() as zend_parse_parameter()](https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter). + +## Type specifiers + +The following list shows the type specifier, its meaning and the parameter types +that need to be passed by address. All passed parameters are set if the PHP +parameter is non optional and untouched if optional and the parameter is not +present. The only exception is O where the zend_class_entry* has to be provided +on input and is used to verify the PHP parameter is an instance of that class. + +```txt +a - array (zval*) +A - array or object (zval*) +b - boolean (zend_bool) +C - class (zend_class_entry*) +d - double (double) +f - function or array containing php method call info (returned as + zend_fcall_info and zend_fcall_info_cache) +h - array (returned as HashTable*) +H - array or HASH_OF(object) (returned as HashTable*) +l - long (zend_long) +L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN) +o - object of any type (zval*) +O - object of specific type given by class entry (zval*, zend_class_entry) +p - valid path (string without null bytes in the middle) and its length (char*, size_t) +P - valid path (string without null bytes in the middle) as zend_string (zend_string*) +r - resource (zval*) +s - string (with possible null bytes) and its length (char*, size_t) +S - string (with possible null bytes) as zend_string (zend_string*) +z - the actual zval (zval*) +* - variable arguments list (0 or more) ++ - variable arguments list (1 or more) +``` + +The following characters also have a meaning in the specifier string: + +* `|` - indicates that the remaining parameters are optional, they should be + initialized to default values by the extension since they will not be touched + by the parsing function if they are not passed to it. +* `/` - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows +* `!` - the parameter it follows can be of specified type or NULL. If NULL is + passed and the output for such type is a pointer, then the output pointer is + set to a native NULL pointer. For 'b', 'l' and 'd', an extra argument of type + zend_bool* must be passed after the corresponding bool*, zend_long* or + double* arguments, respectively. A non-zero value will be written to the + zend_bool if a PHP NULL is passed. + +## Note on 64bit compatibility + +Please note that since version 7 PHP uses `zend_long` as integer type and +`zend_string` with `size_t` as length, so make sure you pass `zend_long`s to "l" +and `size_t` to strings length (i.e. for "s" you need to pass char `*` and +`size_t`), not the other way round! Both mistakes might cause memory corruptions and segfaults: -1) - char *str; - long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */ - zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len) -2) - int num; /* XXX THIS IS WRONG!! Use zend_long instead. */ - zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num) +* 1 + +```c +char *str; +long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */ +zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len) +``` + +* 2 + +```c +int num; /* XXX THIS IS WRONG!! Use zend_long instead. */ +zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num) +``` -If you're in doubt, use check_parameters.php script to the parameters -and their types (it can be found in ./scripts/dev/ directory of PHP sources): +If you're in doubt, use check_parameters.php script to the parameters and their +types (it can be found in `./scripts/dev/` directory of PHP sources): -# php ./scripts/dev/check_parameters.php /path/to/your/sources/ +```bash +php ./scripts/dev/check_parameters.php /path/to/your/sources/ +``` +## Examples -Examples --------- +```c /* Gets a long, a string and its length, and a zval */ zend_long l; char *s; @@ -138,7 +145,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsz", return; } - /* Gets an object of class specified by my_ce, and an optional double. */ zval *obj; double d = 0.5; @@ -148,7 +154,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|d", return; } - /* Gets an object or null, and an array. If null is passed for object, obj will be set to NULL. */ zval *obj; @@ -158,7 +163,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a", return; } - /* Gets a separated array which can also be null. */ zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/!", @@ -171,7 +175,7 @@ zend_long l1, l2, l3; char *s; /* * The function expects a pointer to a size_t in this case, not a long - * or any other type. If you specify a type which is larger + * or any other type. If you specify a type which is larger * than a 'size_t', the upper bits might not be initialized * properly, leading to random crashes on platforms like * Tru64 or Linux/Alpha. @@ -190,13 +194,11 @@ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), return; } - /* Function that accepts only varargs (0 or more) */ int i, num_varargs; zval *varargs = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &varargs, &num_varargs) == FAILURE) { return; } @@ -209,7 +211,6 @@ if (varargs) { efree(varargs); } - /* Function that accepts a string, followed by varargs (1 or more) */ char *str; @@ -243,3 +244,4 @@ for (i = 0; i < num_varargs; i++) { if (zend_parse_parameters_none() == FAILURE) { return; } +``` diff --git a/docs/self-contained-extensions.md b/docs/self-contained-extensions.md index 1aaec6d6c4a60..47f4c636baca8 100644 --- a/docs/self-contained-extensions.md +++ b/docs/self-contained-extensions.md @@ -1,84 +1,83 @@ -HOW TO CREATE A SELF-CONTAINED PHP EXTENSION +# How to create a self-contained PHP extension - A self-contained extension can be distributed independently of - the PHP source. To create such an extension, two things are - required: +A self-contained extension can be distributed independently of the PHP source. +To create such an extension, two things are required: - - Configuration file (config.m4) - - Source code for your module +* Configuration file (config.m4) +* Source code for your module - We will describe now how to create these and how to put things - together. +We will describe now how to create these and how to put things together. -PREPARING YOUR SYSTEM +## Prepairing your system - While the result will run on any system, a developer's setup needs these - tools: +While the result will run on any system, a developer's setup needs these tools: - GNU autoconf - GNU libtool - GNU m4 +* GNU autoconf +* GNU libtool +* GNU m4 - All of these are available from +All of these are available from ftp://ftp.gnu.org/pub/gnu/ -CONVERTING AN EXISTING EXTENSION +## Converting an existing extension - Just to show you how easy it is to create a self-contained - extension, we will convert an embedded extension into a - self-contained one. Install PHP and execute the following - commands. +Just to show you how easy it is to create a self-contained extension, we will +convert an embedded extension into a self-contained one. Install PHP and execute +the following commands. - $ mkdir /tmp/newext - $ cd /tmp/newext +```bash +mkdir /tmp/newext +cd /tmp/newext +``` - You now have an empty directory. We will copy the files from - the mysql extension: +You now have an empty directory. We will copy the files from the mysqli +extension: - $ cp -rp php-4.0.X/ext/mysql/* . +```bash +cp -rp php-src/ext/mysqli/* . +``` - It is time to finish the module. Run: +It is time to finish the module. Run: - $ phpize +```bash +phpize +``` - You can now ship the contents of the directory - the extension - can live completely on its own. +You can now ship the contents of the directory - the extension can live +completely on its own. - The user instructions boil down to +The user instructions boil down to - $ ./configure \ - [--with-php-config=/path/to/php-config] \ - [--with-mysql=MYSQL-DIR] - $ make install +```bash +./configure \ + [--with-php-config=/path/to/php-config] \ + [--with-mysqli=MYSQL-DIR] +make install +``` - The MySQL module will either use the embedded MySQL client - library or the MySQL installation in MYSQL-DIR. +The MySQL module will either use the embedded MySQL client library or the MySQL +installation in MYSQL-DIR. +## Defining the new extension -DEFINING THE NEW EXTENSION +Our demo extension is called "foobar". - Our demo extension is called "foobar". +It consists of two source files `foo.c` and `bar.c` (and any arbitrary amount of +header files, but that is not important here). - It consists of two source files "foo.c" and "bar.c" - (and any arbitrary amount of header files, but that is not - important here). +The demo extension does not reference any external libraries (that is important, +because the user does not need to specify anything). - The demo extension does not reference any external - libraries (that is important, because the user does not - need to specify anything). +`LTLIBRARY_SOURCES` specifies the names of the sources files. You can name an +arbitrary number of source files here. +## Creating the M4 configuration file - LTLIBRARY_SOURCES specifies the names of the sources files. You can - name an arbitrary number of source files here. +The m4 configuration can perform additional checks. For a self-contained +extension, you do not need more than a few macro calls. -CREATING THE M4 CONFIGURATION FILE - - The m4 configuration can perform additional checks. For a - self-contained extension, you do not need more than a few - macro calls. - ------------------------------------------------------------------------------- +```m4 PHP_ARG_ENABLE([foobar], [whether to enable foobar], [AS_HELP_STRING([--enable-foobar], @@ -87,81 +86,88 @@ PHP_ARG_ENABLE([foobar], if test "$PHP_FOOBAR" != "no"; then PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared) fi ------------------------------------------------------------------------------- - - PHP_ARG_ENABLE will automatically set the correct variables, so - that the extension will be enabled by PHP_NEW_EXTENSION in shared mode. +``` - The first argument of PHP_NEW_EXTENSION describes the name of the - extension. The second names the source-code files. The third passes - $ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION. +`PHP_ARG_ENABLE` will automatically set the correct variables, so that the +extension will be enabled by `PHP_NEW_EXTENSION` in shared mode. - Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not - plan to distribute your module with PHP, these facilities allow you - to integrate your module easily into the main PHP module framework. +The first argument of `PHP_NEW_EXTENSION` describes the name of the extension. +The second names the source-code files. The third passes `$ext_shared` which is +set by `PHP_ARG_ENABLE/WITH` to `PHP_NEW_EXTENSION`. -CREATING SOURCE FILES +Please use always `PHP_ARG_ENABLE` or `PHP_ARG_WITH`. Even if you do not plan to +distribute your module with PHP, these facilities allow you to integrate your +module easily into the main PHP module framework. - ext_skel can be of great help when creating the common code for all modules - in PHP for you and also writing basic function definitions and C code for - handling arguments passed to your functions. See `./ext/ext_skel.php --help` - for further information. +## Create source files - As for the rest, you are currently alone here. There are a lot of existing - modules, use a simple module as a starting point and add your own code. +`ext_skel.php` can be of great help when creating the common code for all +modules in PHP for you and also writing basic function definitions and C code +for handling arguments passed to your functions. See `./ext/ext_skel.php --help` +for further information. +As for the rest, you are currently alone here. There are a lot of existing +modules, use a simple module as a starting point and add your own code. -CREATING THE SELF-CONTAINED EXTENSION +## Creating the self-contained extension - Put config.m4 and the source files into one directory. Then, run phpize - (this is installed during make install by PHP 4.0). +Put `config.m4` and the source files into one directory. Then, run `phpize` +(this is installed during `make install` by PHP). - For example, if you configured PHP with --prefix=/php, you would run +For example, if you configured PHP with `--prefix=/php`, you would run - $ /php/bin/phpize +```bash +/php/bin/phpize +``` - This will automatically copy the necessary build files and create - configure from your config.m4. +This will automatically copy the necessary build files and create configure from +your `config.m4`. - And that's it. You now have a self-contained extension. +And that's it. You now have a self-contained extension. -INSTALLING A SELF-CONTAINED EXTENSION +## Installing a self-contained extension - An extension can be installed by running: +An extension can be installed by running: - $ ./configure \ - [--with-php-config=/path/to/php-config] - $ make install +```bash +./configure \ + [--with-php-config=/path/to/php-config] +make install +``` -ADDING SHARED MODULE SUPPORT TO A MODULE +## Adding shared module support to a module - In order to be useful, a self-contained extension must be loadable - as a shared module. I will explain now how you can add shared module - support to an existing module called foo. +In order to be useful, a self-contained extension must be loadable as a shared +module. The following will explain now how you can add shared module support to +an existing module called `foo`. - 1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will - automatically be able to use --with-foo=shared[,..] or - --enable-foo=shared[,..]. +1. In `config.m4`, use `PHP_ARG_WITH/PHP_ARG_ENABLE`. Then you will + automatically be able to use `--with-foo=shared[,..]` or + `--enable-foo=shared[,..]`. - 2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable - building the extension. +2. In `config.m4`, use `PHP_NEW_EXTENSION(foo,.., $ext_shared)` to enable + building the extension. - 3. Add the following lines to your C source file: +3. Add the following lines to your C source file: - #ifdef COMPILE_DL_FOO - ZEND_GET_MODULE(foo) - #endif +```c +#ifdef COMPILE_DL_FOO + ZEND_GET_MODULE(foo) +#endif +``` -PECL SITE CONFORMITY +## PECL site conformity - If you plan to release an extension to the PECL website, there are several - points to be regarded. +If you plan to release an extension to the PECL website, there are several +points to be regarded. - 1. Add LICENSE or COPYING to the package.xml +1. Add `LICENSE` or `COPYING` to the `package.xml` - 2. The following should be defined in one of the extension header files +2. The following should be defined in one of the extension header files - #define PHP_FOO_VERSION "1.2.3" +```c +#define PHP_FOO_VERSION "1.2.3" +``` - This macros has to be used within your foo_module_entry to indicate the - extension version. +This macros has to be used within your foo_module_entry to indicate the +extension version. diff --git a/docs/streams.md b/docs/streams.md index 6ef69c733a008..0ec3846d68bf7 100644 --- a/docs/streams.md +++ b/docs/streams.md @@ -1,29 +1,26 @@ -An Overview of the PHP Streams abstraction -========================================== +# An overview of the PHP streams abstraction WARNING: some prototypes in this file are out of date. -The information contained here is being integrated into -the PHP manual - stay tuned... -Please send comments to: Wez Furlong +## Why streams? -Why Streams? -============ You may have noticed a shed-load of issock parameters flying around the PHP -code; we don't want them - they are ugly and cumbersome and force you to -special case sockets and files every time you need to work with a "user-level" -PHP file pointer. +code; we don't want them - they are ugly and cumbersome and force you to special +case sockets and files every time you need to work with a "user-level" PHP file +pointer. + Streams take care of that and present the PHP extension coder with an ANSI stdio-alike API that looks much nicer and can be extended to support non file based data sources. -Using Streams -============= -Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a -FILE* parameter. +## Using streams + +Streams use a `php_stream*` parameter just as ANSI stdio (fread etc.) use a +`FILE*` parameter. The main functions are: +```c PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count); PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t count); @@ -37,210 +34,234 @@ PHPAPI int php_stream_flush(php_stream * stream); PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence); PHPAPI off_t php_stream_tell(php_stream * stream); PHPAPI int php_stream_lock(php_stream * stream, int mode); +``` These (should) behave in the same way as the ANSI stdio functions with similar -names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock. +names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, +flock. + +## Opening streams -Opening Streams -=============== In most cases, you should use this API: +```c PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode, int options, char **opened_path); +``` Where: - path is the file or resource to open. - mode is the stdio compatible mode eg: "wb", "rb" etc. - options is a combination of the following values: - IGNORE_PATH (default) - don't use include path to search for the file - USE_PATH - use include path to search for the file - IGNORE_URL - do not use plugin wrappers - REPORT_ERRORS - show errors in a standard format if something - goes wrong. - STREAM_MUST_SEEK - If you really need to be able to seek the stream - and don't need to be able to write to the original - file/URL, use this option to arrange for the stream - to be copied (if needed) into a stream that can - be seek()ed. - - opened_path is used to return the path of the actual file opened, - but if you used STREAM_MUST_SEEK, may not be valid. You are - responsible for efree()ing opened_path. opened_path may be (and usually - is) NULL. + +* `path` is the file or resource to open. +* `mode` is the stdio compatible mode eg: "wb", "rb" etc. +* `options` is a combination of the following values: + * `IGNORE_PATH` (default) - don't use include path to search for the file + * `USE_PATH` - use include path to search for the file + * `IGNORE_URL` - do not use plugin wrappers + * `REPORT_ERRORS` - show errors in a standard format if something goes wrong. + * `STREAM_MUST_SEEK` - If you really need to be able to seek the stream and + don't need to be able to write to the original file/URL, use this option to + arrange for the stream to be copied (if needed) into a stream that can be + seek()ed. +* `opened_path` is used to return the path of the actual file opened, but if you + used `STREAM_MUST_SEEK`, may not be valid. You are responsible for + `efree()ing` `opened_path`. +* `opened_path` may be (and usually is) `NULL`. If you need to open a specific stream, or convert standard resources into -streams there are a range of functions to do this defined in php_streams.h. -A brief list of the most commonly used functions: +streams there are a range of functions to do this defined in `php_streams.h`. A +brief list of the most commonly used functions: +```c PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode); - Convert a FILE * into a stream. + /* Convert a FILE * into a stream. */ PHPAPI php_stream *php_stream_fopen_tmpfile(void); - Open a FILE * with tmpfile() and convert into a stream. + /* Open a FILE * with tmpfile() and convert into a stream. */ PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path); - Generate a temporary file name and open it. + /* Generate a temporary file name and open it. */ +``` -There are some network enabled relatives in php_network.h: +There are some network enabled relatives in `php_network.h`: +```c PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent); - Convert a socket into a stream. + /* Convert a socket into a stream. */ PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, int timeout, int persistent); - Open a connection to a host and return a stream. + int socktype, int timeout, int persistent); + /* Open a connection to a host and return a stream. */ PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent, struct timeval *timeout); - Open a UNIX domain socket. - + /* Open a UNIX domain socket. */ +``` -Stream Utilities -================ +## Stream utilities -If you need to copy some data from one stream to another, you will be please -to know that the streams API provides a standard way to do this: +If you need to copy some data from one stream to another, you will be please to +know that the streams API provides a standard way to do this: +```c PHPAPI size_t php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen); +``` If you want to copy all remaining data from the src stream, pass -PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the -number of bytes to copy. -This function will try to use mmap where available to make the copying more -efficient. +`PHP_STREAM_COPY_ALL` as the maxlen parameter, otherwise maxlen indicates the +number of bytes to copy. This function will try to use mmap where available to +make the copying more efficient. If you want to read the contents of a stream into an allocated memory buffer, you should use: +```c PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, int persistent); +``` -This function will set buf to the address of the buffer that it allocated, -which will be maxlen bytes in length, or will be the entire length of the -data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL. -The buffer is allocated using pemalloc(); you need to call pefree() to -release the memory when you are done. -As with copy_to_stream, this function will try use mmap where it can. +This function will set buf to the address of the buffer that it allocated, which +will be maxlen bytes in length, or will be the entire length of the data +remaining on the stream if you set maxlen to `PHP_STREAM_COPY_ALL`. The buffer +is allocated using `pemalloc()`. You need to call `pefree()` to release the +memory when you are done. As with `copy_to_stream`, this function will try use +mmap where it can. -If you have an existing stream and need to be able to seek() it, you -can use this function to copy the contents into a new stream that can -be seek()ed: +If you have an existing stream and need to be able to `seek()` it, you can use +this function to copy the contents into a new stream that can be `seek()ed`: +```c PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream); +``` It returns one of the following values: -#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ -#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ -#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ -#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ -make_seekable will always set newstream to be the stream that is valid -if the function succeeds. -When you have finished, remember to close the stream. +```c +#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ +#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ +#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ +#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ +``` + +`make_seekable` will always set newstream to be the stream that is valid if the +function succeeds. When you have finished, remember to close the stream. -NOTE: If you only need to seek forward, there is no need to call this -function, as the php_stream_seek can emulate forward seeking when the -whence parameter is SEEK_CUR. +NOTE: If you only need to seek forward, there is no need to call this function, +as the `php_stream_seek` can emulate forward seeking when the whence parameter +is `SEEK_CUR`. -NOTE: Writing to the stream may not affect the original source, so it -only makes sense to use this for read-only use. +NOTE: Writing to the stream may not affect the original source, so it only makes +sense to use this for read-only use. -NOTE: If the origstream is network based, this function will block -until the whole contents have been downloaded. +NOTE: If the origstream is network based, this function will block until the +whole contents have been downloaded. -NOTE: Never call this function with an origstream that is referenced -as a resource! It will close the origstream on success, and this -can lead to a crash when the resource is later used/released. +NOTE: Never call this function with an origstream that is referenced as a +resource! It will close the origstream on success, and this can lead to a crash +when the resource is later used/released. NOTE: If you are opening a stream and need it to be seekable, use the -STREAM_MUST_SEEK option to php_stream_open_wrapper(); +`STREAM_MUST_SEEK` option to php_stream_open_wrapper(); +```c PHPAPI int php_stream_supports_lock(php_stream * stream); +``` -This function will return either 1 (success) or 0 (failure) indicating whether or -not a lock can be set on this stream. Typically you can only set locks on stdio streams. +This function will return either 1 (success) or 0 (failure) indicating whether +or not a lock can be set on this stream. Typically you can only set locks on +stdio streams. -Casting Streams -=============== -What if your extension needs to access the FILE* of a user level file pointer? -You need to "cast" the stream into a FILE*, and this is how you do it: +## Casting streams +What if your extension needs to access the `FILE*` of a user level file pointer? +You need to "cast" the stream into a `FILE*`, and this is how you do it: + +```c FILE * fp; php_stream * stream; /* already opened */ if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) { RETURN_FALSE; } +``` The prototype is: -PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int - show_err); +```c +PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int show_err); +``` + +The `show_err` parameter, if non-zero, will cause the function to display an +appropriate error message of type `E_WARNING` if the cast fails. -The show_err parameter, if non-zero, will cause the function to display an -appropriate error message of type E_WARNING if the cast fails. +`castas` can be one of the following values: -castas can be one of the following values: +```txt PHP_STREAM_AS_STDIO - a stdio FILE* PHP_STREAM_AS_FD - a generic file descriptor PHP_STREAM_AS_SOCKETD - a socket descriptor +``` -If you ask a socket stream for a FILE*, the abstraction will use fdopen to -create it for you. Be warned that doing so may cause buffered data to be lost +If you ask a socket stream for a `FILE*`, the abstraction will use fdopen to +create it for you. Be warned that doing so may cause buffered data to be lost if you mix ANSI stdio calls on the FILE* with php stream calls on the stream. If your system has the fopencookie function, php streams can synthesize a -FILE* on top of any stream, which is useful for SSL sockets, memory based +`FILE*` on top of any stream, which is useful for SSL sockets, memory based streams, data base streams etc. etc. -In situations where this is not desirable, you should query the stream -to see if it naturally supports FILE *. You can use this code snippet -for this purpose: +In situations where this is not desirable, you should query the stream to see if +it naturally supports `FILE *`. You can use this code snippet for this purpose: - if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { - /* can safely cast to FILE* with no adverse side effects */ - } +```c +if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { + /* can safely cast to FILE* with no adverse side effects */ +} +``` You can use: +```c PHPAPI int php_stream_can_cast(php_stream * stream, int castas) +``` -to find out if a stream can be cast, without actually performing the cast, so -to check if a stream is a socket you might use: +to find out if a stream can be cast, without actually performing the cast, so to +check if a stream is a socket you might use: +```c if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) { /* it can be a socket */ } +``` -Please note the difference between php_stream_is and php_stream_can_cast; -stream_is tells you if the stream is a particular type of stream, whereas -can_cast tells you if the stream can be forced into the form you request. -The former doesn't change anything, while the later *might* change some -state in the stream. +Please note the difference between `php_stream_is` and `php_stream_can_cast`; +`stream_is` tells you if the stream is a particular type of stream, whereas +`can_cast` tells you if the stream can be forced into the form you request. The +former doesn't change anything, while the later *might* change some state in the +stream. -Stream Internals -================ +## Stream internals -There are two main structures associated with a stream - the php_stream +There are two main structures associated with a stream - the `php_stream` itself, which holds some state information (and possibly a buffer) and a -php_stream_ops structure, which holds the "virtual method table" for the +`php_stream_ops` structure, which holds the "virtual method table" for the underlying implementation. -The php_streams ops struct consists of pointers to methods that implement -read, write, close, flush, seek, gets and cast operations. Of these, an -implementation need only implement write, read, close and flush. The gets -method is intended to be used for streams if there is an underlying method -that can efficiently behave as fgets. The ops struct also contains a label -for the implementation that will be used when printing error messages - the -stdio implementation has a label of "STDIO" for example. +The `php_streams` ops struct consists of pointers to methods that implement +read, write, close, flush, seek, gets and cast operations. Of these, an +implementation need only implement write, read, close and flush. The gets method +is intended to be used for streams if there is an underlying method that can +efficiently behave as fgets. The ops struct also contains a label for the +implementation that will be used when printing error messages - the stdio +implementation has a label of `STDIO` for example. -The idea is that a stream implementation defines a php_stream_ops struct, and -associates it with a php_stream using php_stream_alloc. +The idea is that a stream implementation defines a `php_stream_ops` struct, and +associates it with a `php_stream` using `php_stream_alloc`. -As an example, the php_stream_fopen() function looks like this: +As an example, the `php_stream_fopen()` function looks like this: +```c PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode) { FILE * fp = fopen(filename, mode); @@ -255,62 +276,64 @@ PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode) } return NULL; } +``` -php_stream_stdio_ops is a php_stream_ops structure that can be used to handle -FILE* based streams. +`php_stream_stdio_ops` is a `php_stream_ops` structure that can be used to +handle `FILE*` based streams. -A socket based stream would use code similar to that above to create a stream -to be passed back to fopen_wrapper (or it's yet to be implemented successor). +A socket based stream would use code similar to that above to create a stream to +be passed back to fopen_wrapper (or it's yet to be implemented successor). The prototype for php_stream_alloc is this: +```c PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract, size_t bufsize, int persistent, const char * mode) - -ops is a pointer to the implementation, -abstract holds implementation specific data that is relevant to this instance -of the stream, -bufsize is the size of the buffer to use - if 0, then buffering at the stream -level will be disabled (recommended for underlying sources that implement -their own buffering - such a FILE*), -persistent controls how the memory is to be allocated - persistently so that -it lasts across requests, or non-persistently so that it is freed at the end -of a request (it uses pemalloc), -mode is the stdio-like mode of operation - php streams places no real meaning -in the mode parameter, except that it checks for a 'w' in the string when -attempting to write (this may change). - -The mode parameter is passed on to fdopen/fopencookie when the stream is cast -into a FILE*, so it should be compatible with the mode parameter of fopen(). - -Writing your own stream implementation -====================================== - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -RULE #1: when writing your own streams: make sure you have configured PHP with ---enable-debug. -I've taken some great pains to hook into the Zend memory manager to help track -down allocation problems. It will also help you spot incorrect use of the -STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function -definitions. -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -RULE #2: Please use the stdio stream as a reference; it will help you -understand the semantics of the stream operations, and it will always -be more up to date than these docs :-) +``` + +* `ops` is a pointer to the implementation, +* `abstract` holds implementation specific data that is relevant to this + instance of the stream, +* `bufsize` is the size of the buffer to use - if 0, then buffering at the + stream +* `level` will be disabled (recommended for underlying sources that implement + their own buffering - such a `FILE*`) +* `persistent` controls how the memory is to be allocated - persistently so that + it lasts across requests, or non-persistently so that it is freed at the end + of a request (it uses pemalloc), +* `mode` is the stdio-like mode of operation - php streams places no real + meaning in the mode parameter, except that it checks for a `w` in the string + when attempting to write (this may change). + +The mode parameter is passed on to `fdopen/fopencookie` when the stream is cast +into a `FILE*`, so it should be compatible with the mode parameter of `fopen()`. + +## Writing your own stream implementation + +* **RULE #1**: when writing your own streams: make sure you have configured PHP + with `--enable-debug`. + Some great great pains have been taken to hook into the Zend memory manager to + help track down allocation problems. It will also help you spot incorrect use + of the STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for + function definitions. + +* RULE #2: Please use the stdio stream as a reference; it will help you + understand the semantics of the stream operations, and it will always be more + up to date than these docs :-) First, you need to figure out what data you need to associate with the -php_stream. For example, you might need a pointer to some memory for memory +`php_stream`. For example, you might need a pointer to some memory for memory based streams, or if you were making a stream to read data from an RDBMS like MySQL, you might want to store the connection and rowset handles. -The stream has a field called abstract that you can use to hold this data. -If you need to store more than a single field of data, define a structure to -hold it, allocate it (use pemalloc with the persistent flag set -appropriately), and use the abstract pointer to refer to it. +The stream has a field called abstract that you can use to hold this data. If +you need to store more than a single field of data, define a structure to hold +it, allocate it (use pemalloc with the persistent flag set appropriately), and +use the abstract pointer to refer to it. For structured state you might have this: +```c struct my_state { MYSQL conn; MYSQL_RES * result; @@ -327,6 +350,7 @@ state->result = mysql_use_result(&state->conn); stream = php_stream_alloc(&my_ops, state, 0, persistent, "r"); /* now stream->abstract == state */ +``` Once you have that part figured out, you can write your implementation and define the your own php_stream_ops struct (we called it my_ops in the above @@ -334,6 +358,7 @@ example). For example, for reading from this weird MySQL stream: +```c static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count) { struct my_state * state = (struct my_state*)stream->abstract; @@ -354,23 +379,27 @@ static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count) such as coping with a buffer size too small to hold the data, so I won't even go in to how to do that here */ } +``` -Implement the other operations - remember that write, read, close and flush -are all mandatory. The rest are optional. Declare your stream ops struct: +Implement the other operations - remember that write, read, close and flush are +all mandatory. The rest are optional. Declare your stream ops struct: +```c php_stream_ops my_ops = { php_mysqlop_write, php_mysqlop_read, php_mysqlop_close, php_mysqlop_flush, NULL, NULL, NULL, "Strange MySQL example" } +``` That's it! -Take a look at the STDIO implementation in streams.c for more information -about how these operations work. +Take a look at the STDIO implementation in streams.c for more information about +how these operations work. + The main thing to remember is that in your close operation you need to release -and free the resources you allocated for the abstract field. In the case of -the example above, you need to use mysql_free_result on the rowset, close the -connection and then use pefree to dispose of the struct you allocated. -You may read the stream->persistent field to determine if your struct was -allocated in persistent mode or not. +and free the resources you allocated for the abstract field. In the case of the +example above, you need to use mysql_free_result on the rowset, close the +connection and then use pefree to dispose of the struct you allocated. You may +read the stream->persistent field to determine if your struct was allocated in +persistent mode or not. diff --git a/docs/unix-build-system.md b/docs/unix-build-system.md index a184b909ba374..bdb8d4d146d5f 100644 --- a/docs/unix-build-system.md +++ b/docs/unix-build-system.md @@ -1,123 +1,121 @@ -PHP Build System V5 Overview - -- supports Makefile.ins during transition phase -- not-really-portable Makefile includes have been eliminated -- supports separate build directories without VPATH by using - explicit rules only -- does not waste disk-space/CPU-time for building temporary libraries - => especially noticeable on slower systems -- slow recursive make replaced with one global Makefile -- eases integration of proper dependencies -- adds PHP_DEFINE(what[, value]) which creates a single include-file - per what. This will allow more fine-grained dependencies. -- abandoning the "one library per directory" concept -- improved integration of the CLI -- several new targets - build-modules: builds and copies dynamic modules into modules/ - install-cli: installs the CLI only, so that the install-sapi - target does only what its name says -- finally abandoned automake -- changed some configure-time constructs to run at buildconf-time -- upgraded shtool to 1.5.4 -- removed $(moduledir) (use EXTENSION_DIR) - -The Reason For a New System - -It became more and more apparent that there is a severe need -for addressing the portability concerns and improving the chance -that your build is correct (how often have you been told to -"make clean"? When this is done, you won't need to anymore). - - -If You Build PHP on a Unix System - - -You, as a user of PHP, will notice no changes. Of course, the build -system will be faster, look better and work smarter. - - - -If You Are Developing PHP - - - - -Extension developers: - -Makefile.ins are abandoned. The files which are to be compiled -are specified in the config.m4 now using the following macro: - +# PHP build system V5 overview + +* supports Makefile.ins during transition phase +* not-really-portable Makefile includes have been eliminated +* supports separate build directories without VPATH by using explicit rules only +* does not waste disk-space/CPU-time for building temporary libraries => + especially noticeable on slower systems +* slow recursive make replaced with one global Makefile +* eases integration of proper dependencies +* adds PHP_DEFINE(what[, value]) which creates a single include-file per what. + This will allow more fine-grained dependencies. +* abandoning the "one library per directory" concept +* improved integration of the CLI +* several new targets: + * `build-modules`: builds and copies dynamic modules into `modules/` + * `install-cli`: installs the CLI only, so that the install-sapi target does + only what its name says +* finally abandoned automake +* changed some configure-time constructs to run at buildconf-time +* upgraded shtool to 1.5.4 +* removed `$(moduledir)` (use `EXTENSION_DIR`) + +## The reason for a new system + +It became more and more apparent that there is a severe need for addressing the +portability concerns and improving the chance that your build is correct (how +often have you been told to `make clean`? When this is done, you won't need to +anymore). + +## If you build PHP on a Unix system + +You, as a user of PHP, will notice no changes. Of course, the build system will +be faster, look better and work smarter. + +## If you are developing PHP + +### Extension developers + +Makefile.ins are abandoned. The files which are to be compiled are specified in +the `config.m4` now using the following macro: + +```m4 PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared) +``` -E.g. this enables the extension foo which consists of three source-code -modules, two in C and one in C++. And, depending on the user's wishes, -the extension will even be built as a dynamic module. +E.g. this enables the extension foo which consists of three source-code modules, +two in C and one in C++. And, depending on the user's wishes, the extension will +even be built as a dynamic module. The full syntax: +```m4 PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]]) +``` -Please have a look at acinclude.m4 for the gory details and meanings -of the other parameters. +Please have a look at `acinclude.m4` for the gory details and meanings of the +other parameters. And that's basically it for the extension side. -If you previously built sub-libraries for this module, add -the source-code files here as well. If you need to specify -separate include directories, do it this way: +If you previously built sub-libraries for this module, add the source-code files +here as well. If you need to specify separate include directories, do it this +way: +```m4 PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib) +``` -E.g. this builds the three files which are located relative to the -extension source directory and compiles all three files with the -special include directive (@ext_srcdir@ is automatically replaced). +E.g. this builds the three files which are located relative to the extension +source directory and compiles all three files with the special include directive +(`@ext_srcdir@` is automatically replaced). -Now, you need to tell the build system that you want to build files -in a directory called $ext_builddir/lib: +Now, you need to tell the build system that you want to build files in a +directory called `$ext_builddir/lib`: +```m4 PHP_ADD_BUILD_DIR($ext_builddir/lib) +``` -Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir -is only set by the latter. +Make sure to call this after `PHP_NEW_EXTENSION`, because `$ext_builddir` is +only set by the latter. -If you have a complex extension, you might to need add special -Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT -in your config.m4 after PHP_NEW_EXTENSION. +If you have a complex extension, you might to need add special Make rules. You +can do this by calling `PHP_ADD_MAKEFILE_FRAGMENT` in your `config.m4` after +`PHP_NEW_EXTENSION`. This will read a file in the source-dir of your extension called -Makefile.frag. In this file, $(builddir) and $(srcdir) will be -replaced by the values which are correct for your extension -and which are again determined by the PHP_NEW_EXTENSION macro. - -Make sure to prefix *all* relative paths correctly with either -$(builddir) or $(srcdir). Because the build system does not -change the working directory anymore, we must use either -absolute paths or relative ones to the top build-directory. -Correct prefixing ensures that. +`Makefile.frag`. In this file, `$(builddir)` and `$(srcdir)` will be replaced by +the values which are correct for your extension and which are again determined +by the `PHP_NEW_EXTENSION` macro. +Make sure to prefix *all* relative paths correctly with either `$(builddir)` or +`$(srcdir)`. Because the build system does not change the working directory +anymore, we must use either absolute paths or relative ones to the top +build-directory. Correct prefixing ensures that. -SAPI developers: +### SAPI developers -Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type +Instead of using `PHP_SAPI=foo/PHP_BUILD_XYZ`, you will need to type +```m4 PHP_SELECT_SAPI(name, type, sources.c) +``` -I.e. specify the source-code files as above and also pass the -information regarding how PHP is supposed to be built (shared -module, program, etc). +I.e. specify the source-code files as above and also pass the information +regarding how PHP is supposed to be built (shared module, program, etc). For example for APXS: +```m4 PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php7.c php_apache.c) +``` +## General info +The foundation for the new system is the flexible handling of sources and their +contexts. With the help of macros you can define special flags for each +source-file, where it is located, in which target context it can work, etc. -General info - -The foundation for the new system is the flexible handling of -sources and their contexts. With the help of macros you -can define special flags for each source-file, where it is -located, in which target context it can work, etc. - -Have a look at the well documented macros -PHP_ADD_SOURCES(_X) in acinclude.m4. +Have a look at the well documented macros `PHP_ADD_SOURCES(_X)` in +`acinclude.m4`. diff --git a/ext/bcmath/libbcmath/AUTHORS b/ext/bcmath/libbcmath/AUTHORS deleted file mode 100644 index f2d831cf652c2..0000000000000 --- a/ext/bcmath/libbcmath/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Phil Nelson wrote bcmath library. diff --git a/ext/bcmath/libbcmath/ChangeLog b/ext/bcmath/libbcmath/ChangeLog deleted file mode 100644 index eea6b016e2b53..0000000000000 --- a/ext/bcmath/libbcmath/ChangeLog +++ /dev/null @@ -1,9 +0,0 @@ -Wed Jun 7 09:39:02 2000 Phil Nelson - - * configure.in and many others: version number now at 0.2. - Many other changes/additions for getting a distribution - to work. - -2000-05-21 Phil Nelson - - * Initial setup of bcmath library., calling it version 0.1. diff --git a/ext/bcmath/libbcmath/FAQ b/ext/bcmath/libbcmath/FAQ deleted file mode 100644 index 423600ac76fe0..0000000000000 --- a/ext/bcmath/libbcmath/FAQ +++ /dev/null @@ -1,20 +0,0 @@ -BCMATH FAQ: - -1) Why BCMATH? - -The math routines of GNU bc become more generally useful in a -library form. By separating the BCMATH library from GNU bc, -GNU bc can be under the GPL and BCMATH can be under the LGPL. - -2) Why BCMATH when GMP exists? - -GMP has "integers" (no digits after a decimal), "rational numbers" -(stored as 2 integers) and "floats". None of these will correctly -represent a POSIX BC number. Floats are the closest, but will not -behave correctly for many computations. For example, BC numbers have -a "scale" that represent the number of digits to represent after the -decimal point. The multiplying two of these numbers requires one to -calculate an exact number of digits after the decimal point regardless -of the number of digits in the integer part. GMP floats have a -"fixed, but arbitrary" mantissa and so multiplying two floats will end -up dropping digits BC must calculate. diff --git a/ext/bcmath/libbcmath/NEWS b/ext/bcmath/libbcmath/NEWS deleted file mode 100644 index 431d7b315d17f..0000000000000 --- a/ext/bcmath/libbcmath/NEWS +++ /dev/null @@ -1,3 +0,0 @@ -NEWS for bcmath library: - - May 2000: The library is created. diff --git a/ext/bcmath/libbcmath/README b/ext/bcmath/libbcmath/README deleted file mode 100644 index cae5e5dc431d7..0000000000000 --- a/ext/bcmath/libbcmath/README +++ /dev/null @@ -1,9 +0,0 @@ -This is bcmath, a library of arbitrary precision math routines. -These routines, in a different form, are the routines that to -the arbitrary precision calculations for GNU bc and GNU dc. - -This library is provided to make these routines useful in a -larger context with less restrictions on the use of them. - -These routines do not duplicate functionality of the GNU gmp -library. gmp is similar, but the actual computation is different. diff --git a/ext/bcmath/libbcmath/README.md b/ext/bcmath/libbcmath/README.md new file mode 100644 index 0000000000000..c0bb465ae1a6b --- /dev/null +++ b/ext/bcmath/libbcmath/README.md @@ -0,0 +1,45 @@ +# The bcmath library + +This is a fork of the bcmath library initially created by Phil Nelson in May +2000. + +Bcmath is a library of arbitrary precision math routines. These routines, in a +different form, are the routines that to the arbitrary precision calculations +for GNU bc and GNU dc. + +This library is provided to make these routines useful in a larger context with +less restrictions on the use of them. + +These routines do not duplicate functionality of the GNU gmp library. The gmp +library is similar, but the actual computation is different. + +Initial library (version 0.1) has been created in 2000-05-21 and then forked and +bundled into PHP with version 0.2 released in 2000-06-07. + +## FAQ + +* Why BCMATH? + + The math routines of GNU bc become more generally useful in a library form. By + separating the BCMATH library from GNU bc, GNU bc can be under the GPL and + BCMATH can be under the LGPL. + +* Why BCMATH when GMP exists? + + GMP has "integers" (no digits after a decimal), "rational numbers" (stored as + 2 integers) and "floats". None of these will correctly represent a POSIX BC + number. Floats are the closest, but will not behave correctly for many + computations. For example, BC numbers have a "scale" that represent the number + of digits to represent after the decimal point. The multiplying two of these + numbers requires one to calculate an exact number of digits after the decimal + point regardless of the number of digits in the integer part. GMP floats have + a "fixed, but arbitrary" mantissa and so multiplying two floats will end up + dropping digits BC must calculate. + +## Credits + +Phil Nelson (philnelson@acm.org) wrote bcmath library. + +## License + +The bcmath library is released under the GNU Lesser General Public License v2.1. diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index 7eec446a3f94a..15f68367c48dd 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -78,9 +78,10 @@ static zval *saproxy_property_read(zval *object, zval *member, int type, void ** return rv; } -static void saproxy_property_write(zval *object, zval *member, zval *value, void **cache_slot) +static zval *saproxy_property_write(zval *object, zval *member, zval *value, void **cache_slot) { php_com_throw_exception(E_INVALIDARG, "safearray has no properties"); + return value; } static zval *saproxy_read_dimension(zval *object, zval *offset, int type, zval *rv) diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 index 6ebfac78c8d90..88447bd78af6d 100644 --- a/ext/curl/config.m4 +++ b/ext/curl/config.m4 @@ -80,9 +80,7 @@ int main(int argc, char *argv[]) } ]])], [ AC_MSG_RESULT([yes]) - AC_CHECK_HEADER([gcrypt.h], [ - AC_DEFINE([HAVE_CURL_GNUTLS], [1], [Have cURL with GnuTLS support]) - ]) + AC_DEFINE([HAVE_CURL_GNUTLS], [1], [Have cURL with GnuTLS support]) ], [ AC_MSG_RESULT([no]) ], [ diff --git a/ext/curl/interface.c b/ext/curl/interface.c index bbdcdbfbe7d72..d8b9fcb7ed3b7 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -59,15 +59,8 @@ "cause random crashes on SSL requests" # endif # elif defined(HAVE_CURL_GNUTLS) -# if defined(HAVE_GCRYPT_H) -# define PHP_CURL_NEED_GNUTLS_TSL -# include -# else -# warning \ - "libcurl was compiled with GnuTLS support, but configure could not find " \ - "gcrypt.h; thus no SSL crypto locking callbacks will be set, which may " \ - "cause random crashes on SSL requests" -# endif + /* Modern versions of GnuTLS use the nette backend rather than gcrypt, so there + * is nothing to do here anymore. */ # else # warning \ "libcurl was compiled with SSL support, but configure could not determine which" \ @@ -93,7 +86,9 @@ int le_curl_share_handle; #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ static MUTEX_T *php_curl_openssl_tsl = NULL; -static void php_curl_ssl_lock(int mode, int n, const char * file, int line) +/* Locking callbacks are no longer used since OpenSSL 1.1. Mark the functions as unused to + * avoid warnings due to this. */ +static ZEND_ATTRIBUTE_UNUSED void php_curl_ssl_lock(int mode, int n, const char * file, int line) { if (mode & CRYPTO_LOCK) { tsrm_mutex_lock(php_curl_openssl_tsl[n]); @@ -102,50 +97,13 @@ static void php_curl_ssl_lock(int mode, int n, const char * file, int line) } } -static unsigned long php_curl_ssl_id(void) +static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void) { return (unsigned long) tsrm_thread_id(); } #endif /* }}} */ -#ifdef PHP_CURL_NEED_GNUTLS_TSL /* {{{ */ -static int php_curl_ssl_mutex_create(void **m) -{ - if (*((MUTEX_T *) m) = tsrm_mutex_alloc()) { - return SUCCESS; - } else { - return FAILURE; - } -} - -static int php_curl_ssl_mutex_destroy(void **m) -{ - tsrm_mutex_free(*((MUTEX_T *) m)); - return SUCCESS; -} - -static int php_curl_ssl_mutex_lock(void **m) -{ - return tsrm_mutex_lock(*((MUTEX_T *) m)); -} - -static int php_curl_ssl_mutex_unlock(void **m) -{ - return tsrm_mutex_unlock(*((MUTEX_T *) m)); -} - -static struct gcry_thread_cbs php_curl_gnutls_tsl = { - GCRY_THREAD_OPTION_USER, - NULL, - php_curl_ssl_mutex_create, - php_curl_ssl_mutex_destroy, - php_curl_ssl_mutex_lock, - php_curl_ssl_mutex_unlock -}; -#endif -/* }}} */ - static void _php_curl_close_ex(php_curl *ch); static void _php_curl_close(zend_resource *rsrc); @@ -1471,9 +1429,6 @@ PHP_MINIT_FUNCTION(curl) CRYPTO_set_locking_callback(php_curl_ssl_lock); } #endif -#ifdef PHP_CURL_NEED_GNUTLS_TSL - gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl); -#endif if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { return FAILURE; @@ -1840,7 +1795,11 @@ static void curl_free_string(void **string) */ static void curl_free_post(void **post) { +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + curl_mime_free((curl_mime *)*post); +#else curl_formfree((struct HttpPost *)*post); +#endif } /* }}} */ @@ -2760,16 +2719,28 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ HashTable *postfields; zend_string *string_key; zend_ulong num_key; +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + curl_mime *mime; + curl_mimepart *part; + CURLcode form_error; +#else struct HttpPost *first = NULL; struct HttpPost *last = NULL; CURLFORMcode form_error; - +#endif postfields = HASH_OF(zvalue); if (!postfields) { php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS"); return FAILURE; } +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + mime = curl_mime_init(ch->cp); + if (mime == NULL) { + return FAILURE; + } +#endif + ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) { zend_string *postval, *tmp_postval; /* Pretend we have a string_key here */ @@ -2804,6 +2775,20 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) { filename = Z_STRVAL_P(prop); } + +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + part = curl_mime_addpart(mime); + if (part == NULL) { + zend_string_release_ex(string_key, 0); + return FAILURE; + } + if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK + || (form_error = curl_mime_filedata(part, ZSTR_VAL(postval))) != CURLE_OK + || (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK + || (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) { + error = form_error; + } +#else form_error = curl_formadd(&first, &last, CURLFORM_COPYNAME, ZSTR_VAL(string_key), CURLFORM_NAMELENGTH, ZSTR_LEN(string_key), @@ -2815,6 +2800,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ /* Not nice to convert between enums but we only have place for one error type */ error = (CURLcode)form_error; } +#endif } zend_string_release_ex(string_key, 0); @@ -2823,6 +2809,18 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ postval = zval_get_tmp_string(current, &tmp_postval); +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + part = curl_mime_addpart(mime); + if (part == NULL) { + zend_tmp_string_release(tmp_postval); + zend_string_release_ex(string_key, 0); + return FAILURE; + } + if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK + || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) { + error = form_error; + } +#else /* The arguments after _NAMELENGTH and _CONTENTSLENGTH * must be explicitly cast to long in curl_formadd * use since curl needs a long not an int. */ @@ -2837,6 +2835,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ /* Not nice to convert between enums but we only have place for one error type */ error = (CURLcode)form_error; } +#endif zend_tmp_string_release(tmp_postval); zend_string_release_ex(string_key, 0); } ZEND_HASH_FOREACH_END(); @@ -2849,8 +2848,13 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ if ((*ch->clone) == 1) { zend_llist_clean(&ch->to_free->post); } +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + zend_llist_add_element(&ch->to_free->post, &mime); + error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime); +#else zend_llist_add_element(&ch->to_free->post, &first); error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first); +#endif } else { #if LIBCURL_VERSION_NUM >= 0x071101 zend_string *tmp_str; diff --git a/ext/curl/tests/curl_version_basic_001.phpt b/ext/curl/tests/curl_version_basic_001.phpt new file mode 100644 index 0000000000000..803e9f689d8de --- /dev/null +++ b/ext/curl/tests/curl_version_basic_001.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test curl_version() basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +int(%i) +int(%i) +int(%i) +int(%i) +string(%i) "%s" +string(%i) "%s" +string(%i) "%s" +string(%i) "%s" +bool(true) diff --git a/ext/date/config.w32 b/ext/date/config.w32 index d25b52df27fdf..41a776fa568c1 100644 --- a/ext/date/config.w32 +++ b/ext/date/config.w32 @@ -2,7 +2,6 @@ EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 /DHAVE_TIMELIB_CONFIG_H=1"); ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c parse_date.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date"); -AC_DEFINE('HAVE_DATE', 1, 'Have date/time support'); ADD_FLAG('CFLAGS_DATE', "/wd4244"); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c80e318b2264f..03fdc18284a78 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4646,6 +4646,10 @@ PHP_METHOD(DatePeriod, __construct) dpobj->end = clone; } } + + if (dpobj->end == NULL && recurrences < 1) { + php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); + } /* options */ dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE); diff --git a/ext/date/php_date.h b/ext/date/php_date.h index f624a42227f64..8bb6f23ea1307 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -131,7 +131,6 @@ typedef struct _php_period_obj php_period_obj; struct _php_date_obj { timelib_time *time; - HashTable *props; zend_object std; }; @@ -149,7 +148,6 @@ struct _php_timezone_obj { timelib_sll utc_offset; /* TIMELIB_ZONETYPE_OFFSET */ timelib_abbr_info z; /* TIMELIB_ZONETYPE_ABBR */ } tzi; - HashTable *props; zend_object std; }; @@ -161,7 +159,6 @@ static inline php_timezone_obj *php_timezone_obj_from_obj(zend_object *obj) { struct _php_interval_obj { timelib_rel_time *diff; - HashTable *props; int initialized; zend_object std; }; diff --git a/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt new file mode 100644 index 0000000000000..715ea63dc94db --- /dev/null +++ b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt @@ -0,0 +1,19 @@ +--TEST-- +DatePeriod: Test wrong recurrence parameter on __construct +--FILE-- +getMessage(), "\n"; +} + +try { + new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'),-1); +} catch (Exception $exception) { + echo $exception->getMessage(), "\n"; +} +?> +--EXPECTF-- +DatePeriod::__construct(): The recurrence count '0' is invalid. Needs to be > 0 +DatePeriod::__construct(): The recurrence count '-1' is invalid. Needs to be > 0 diff --git a/ext/date/tests/date_timestamp_get.phpt b/ext/date/tests/date_timestamp_get.phpt new file mode 100644 index 0000000000000..dc9f6ab541259 --- /dev/null +++ b/ext/date/tests/date_timestamp_get.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test the basics to function date_timestamp_get(). +--CREDITS-- +Carlos Alexandre Pires de Carvalho Junior +Daiane Alves +Ednaldo Neimeg Marques +Henrique Ramos +Larissa Mourullo +Virgílio de Carvalho Pontes +Vitor Mattos +--FILE-- +getTimeStamp(); +$beginDtObj = date_create('1970-01-01T00:00:00UTC'); +$beginTimestamp = date_timestamp_get($beginDtObj); +var_dump($dateTimeTz === $beginTimestamp); +?> +--EXPECT-- +int(0) +bool(true) diff --git a/ext/dom/config.m4 b/ext/dom/config.m4 index dc4fccbc454ef..c7ebb20f81549 100644 --- a/ext/dom/config.m4 +++ b/ext/dom/config.m4 @@ -6,19 +6,10 @@ PHP_ARG_ENABLE([dom], [Disable DOM support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([[--with-libxml-dir[=DIR]]], - [DOM: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_DOM" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([DOM extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([DOM extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(DOM_SHARED_LIBADD, [ @@ -37,7 +28,5 @@ if test "$PHP_DOM" != "no"; then PHP_SUBST(DOM_SHARED_LIBADD) PHP_INSTALL_HEADERS([ext/dom/xml_common.h]) PHP_ADD_EXTENSION_DEP(dom, libxml) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) fi diff --git a/ext/ffi/README.md b/ext/ffi/README.md index e8aea5e67ea2c..8d18c2450dce8 100644 --- a/ext/ffi/README.md +++ b/ext/ffi/README.md @@ -1,6 +1,9 @@ # FFI PHP extension (Foreign Function Interface) -FFI PHP extension provides a simple way to call native functions, access native variables and create/access data structures defined in C language. The API of the extension is very simple and demonstrated by the following example and its output. +FFI PHP extension provides a simple way to call native functions, access native +variables and create/access data structures defined in C language. The API of +the extension is very simple and demonstrated by the following example and its +output. ```php printf("Hello World from %s!\n", "PHP"); @@ -36,7 +39,7 @@ var_dump($tv->tv_sec, $tv->tv_usec, $tz); ?> ``` -``` +```txt Hello World from PHP! string(135) "/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/dmitry/.local/bin:/home/dmitry/bin" int(1523617815) @@ -50,13 +53,22 @@ object(FFI\CData:)#3 (2) { } ``` -FFI::cdef() takes two arguments (both are optional). The first one is a collection of C declarations and the second is DSO library. All variables and functions defined by first arguments are bound to corresponding native symbols in DSO library and then may be accessed as FFI object methods and properties. C types of argument, return value and variables are automatically converted to/from PHP types (if possible). Otherwise, they are wrapped in a special CData proxy object and may be accessed by elements. +`FFI::cdef()` takes two arguments (both are optional). The first one is a +collection of C declarations and the second is DSO library. All variables and +functions defined by first arguments are bound to corresponding native symbols +in DSO library and then may be accessed as FFI object methods and properties. C +types of argument, return value and variables are automatically converted +to/from PHP types (if possible). Otherwise, they are wrapped in a special CData +proxy object and may be accessed by elements. -In some cases (e.g. passing C structure by pointer) we may need to create a real C data structures. This is possible using FFF::new() method. It takes a C type definition and may reuse C types and tags defined by FFI::cdef(). +In some cases (e.g. passing C structure by pointer) we may need to create a real +C data structures. This is possible using `FFF::new()` method. It takes a C type +definition and may reuse C types and tags defined by `FFI::cdef()`. -It's also possible to use FFI::new() as a static method to create arbitrary C data structures. +It's also possible to use `FFI::new()` as a static method to create arbitrary C +data structures. -``` php +```php x = 5; @@ -64,7 +76,7 @@ $p[1]->y = 10; var_dump($p); ``` -``` +```txt object(FFI\CData:[2])#1 (2) { [0]=> object(FFI\CData:)#2 (2) { @@ -83,132 +95,169 @@ object(FFI\CData:[2])#1 (2) { } ``` -### API Reference +## API reference -##### function FFI::cdef([string $cdef = "" [, string $lib = null]]): FFI +### function FFI::cdef([string $cdef = "" [, string $lib = null]]): FFI -##### Call Native Functions +#### Call native functions -All functions defined in FFI::cdef() may be called as methods of the created FFI object. +All functions defined in `FFI::cdef()` may be called as methods of the created +FFI object. ```php $libc = FFI::cdef("const char * getenv(const char *);", "libc.so.6"); var_dump($libc->getenv("PATH")); ``` -##### Read/Write Values of Native Variables +#### Read/write values of native variables -All functions defined in FFI::cdef() may be accessed as properties of the created FFI object. +All functions defined in `FFI::cdef()` may be accessed as properties of the +created FFI object. ```php $libc = FFI::cdef("extern int errno;", "libc.so.6"); var_dump($libc->errno); ``` -##### function FFI::type(string $type): FFI\CType - -This function creates and returns a **FFI\CType** object, representng type of the given C type declaration string. +### function FFI::type(string $type): FFI\CType -FFI::type() may be called statically and use only predefined types, or as a method of previously created FFI object. In last case the first argument may reuse all type and tag names defined in FFI::cdef(). +This function creates and returns a `FFI\CType` object, representng type of +the given C type declaration string. +`FFI::type()` may be called statically and use only predefined types, or as a +method of previously created FFI object. In last case the first argument may +reuse all type and tag names defined in `FFI::cdef()`. -##### function FFI::typeof(FFI\CData $type): FFI\CType +### function FFI::typeof(FFI\CData $type): FFI\CType -This function returns a **FFI\CType** object, representing the type of the given **FFI\CData** object. +This function returns a `FFI\CType` object, representing the type of the given +`FFI\CData` object. -##### static function FFI::arrayType(FFI\CType $type, array $dims): FFI\CType +### static function FFI::arrayType(FFI\CType $type, array $dims): FFI\CType -Constructs a new C array type with elements of $type and dimensions specified by $dims. +Constructs a new C array type with elements of $type and dimensions specified by +$dims. -##### function FFI::new(mixed $type [, bool $own = true [, bool $persistent = false]]): FFI\CData +### function FFI::new(mixed $type [, bool $own = true [, bool $persistent = false]]): FFI\CData -This function may be used to create a native data structure. The first argument is a C type definition. It may be a **string** or **FFI\CType** object. The following example creates two dimensional array of integers. +This function may be used to create a native data structure. The first argument +is a C type definition. It may be a `string` or `FFI\CType` object. The +following example creates two dimensional array of integers. ```php $p = FFI::new("int[2][2]"); var_dump($p, FFI::sizeof($p)); ``` -FFI::new() may be called statically and use only predefined types, or as a method of previously created FFI object. In last case the first argument may reuse all type and tag names defined in FFI::cdef(). +`FFI::new()` may be called statically and use only predefined types, or as a +method of previously created FFI object. In last case the first argument may +reuse all type and tag names defined in `FFI::cdef()`. -By default **FFI::new()** creates "owned" native data structures, that live together with corresponding PHP object, reusing PHP reference-counting and GC. However, in some cases it may be necessary to manually control the life time of the data structure. In this case, the PHP ownership on the corresponding data, may be manually changed, using **false** as the second optianal argument. Later, not-owned CData should be manually deallocated using **FFI::free()**. +By default `FFI::new()` creates "owned" native data structures, that live +together with corresponding PHP object, reusing PHP reference-counting and GC. +However, in some cases it may be necessary to manually control the life time of +the data structure. In this case, the PHP ownership on the corresponding data, +may be manually changed, using `false` as the second optianal argument. Later, +not-owned CData should be manually deallocated using `FFI::free()`. -Using the optional $persistent argument it's possible to allocate C objects in persistent memory, through malloc(), otherwise memory is allocated in PHP request heap, through emalloc(). +Using the optional $persistent argument it's possible to allocate C objects in +persistent memory, through `malloc()`, otherwise memory is allocated in PHP +request heap, through `emalloc()`. -##### static function FFI::free(FFI\CData $cdata): void +### static function FFI::free(FFI\CData $cdata): void -manually removes previously created "not-owned" data structure. +Manually removes previously created "not-owned" data structure. -##### Read/Write Elements of Native Arrays +#### Read/write elements of native arrays -Elements of native array may be accessed in the same way as elements of PHP arrays. Of course, native arrays support only integer indexes. It's not possible to check element existence using isset() or empty() and remove element using unset(). Native arrays work fine with "foreach" statement. +Elements of native array may be accessed in the same way as elements of PHP +arrays. Of course, native arrays support only integer indexes. It's not possible +to check element existence using `isset()` or `empty()` and remove element using +`unset()`. Native arrays work fine with "foreach" statement. ```php $p = FFI::new("int[2]"); $p[0] = 1; $p[1] = 2; foreach ($p as $key => $val) { - echo "$key => $val\n"; + echo "$key => $val\n"; } ``` -##### Read/Write Fields of Native "struct" or "union" +#### Read/write fields of native "struct" or "union" -Fields of native struct/union may be accessed in the same way as properties of PHP objects. It's not possible to check filed existence using isset() or empty(), remove them using unset(), and iterate using "foreach" statement. +Fields of native struct/union may be accessed in the same way as properties of +PHP objects. It's not possible to check filed existence using `isset()` or +`empty()`, remove them using `unset()`, and iterate using "foreach" statement. ```php $pp = FFI::new("struct {int x,y;}[2]"); foreach($pp as $n => &$p) { - $p->x = $p->y = $n; + $p->x = $p->y = $n; } var_dump($pp); ``` -##### Pointer arithmetic +#### Pointer arithmetic -CData pointer values may be incremented/decremented by a number. The result is a pointer of the same type moved on given offset. +CData pointer values may be incremented/decremented by a number. The result is a +pointer of the same type moved on given offset. -Two pointers to the same type may be subtracted and return difference (similar to C). +Two pointers to the same type may be subtracted and return difference (similar +to C). -##### static function FFI::sizeof(mixed $cdata_or_ctype): int +### static function FFI::sizeof(mixed $cdata_or_ctype): int -returns size of C data type of the given **FFI\CData** or **FFI\CType**. +Returns size of C data type of the given `FFI\CData` or `FFI\CType`. -##### static function FFI::alignof(mixed $cdata_or_ctype): int +### static function FFI::alignof(mixed $cdata_or_ctype): int -returns size of C data type of the given **FFI\CData** or **FFI\CType**. +Returns size of C data type of the given `FFI\CData` or `FFI\CType`. -##### static function FFI::memcpy(FFI\CData $dst, mixed $src, int $size): void +### static function FFI::memcpy(FFI\CData $dst, mixed $src, int $size): void -copies $size bytes from memory area $src to memory area $dst. $src may be any native data structure (**FFI\CData**) or PHP **string**. +Copies $size bytes from memory area $src to memory area $dst. $src may be any +native data structure (`FFI\CData`) or PHP `string`. -##### static function FFI::memcmp(mixed $src1, mixed $src2, int $size): int +### static function FFI::memcmp(mixed $src1, mixed $src2, int $size): int -compares $size bytes from memory area $src1 and $dst2. $src1 and $src2 may be any native data structures (**FFI\CData**) or PHP **string**s. +Compares $size bytes from memory area `$src1` and `$dst2`. `$src1` and `$src2` +may be any native data structures (`FFI\CData`) or PHP `string`s. -##### static function FFI::memset(FFI\CData $dst, int $c, int $size): void +### static function FFI::memset(FFI\CData $dst, int $c, int $size): void -fills the $size bytes of the memory area pointed to by $dst with the constant byte $c +Fills the $size bytes of the memory area pointed to by `$dst` with the constant +byte `$c`. -##### static function FFI::string(FFI\CData $src [, int $size]): string +### static function FFI::string(FFI\CData $src [, int $size]): string -creates a PHP string from $size bytes of memory area pointed by $src. If size is omitted, $src must be zero terminated array of C chars. +Creates a PHP string from `$size` bytes of memory area pointed by `$src`. If +size is omitted, $src must be zero terminated array of C chars. -##### function FFI::cast(mixed $type, FFI\CData $cdata): FFI\CData +### function FFI::cast(mixed $type, FFI\CData $cdata): FFI\CData -Casts given $cdata to another C type, specified by C declaration **string** or **FFI\CType** object. +Casts given $cdata to another C type, specified by C declaration `string` or +`FFI\CType` object. -This function may be called statically and use only predefined types, or as a method of previously created FFI object. In last case the first argument may reuse all type and tag names defined in FFI::cdef(). +This function may be called statically and use only predefined types, or as a +method of previously created FFI object. In last case the first argument may +reuse all type and tag names defined in `FFI::cdef()`. -##### static function addr(FFI\CData $cdata): FFI\CData; +### static function addr(FFI\CData $cdata): FFI\CData -Returns C pointer to the given C data structure. The pointer is not "owned" and won't be free. Anyway, this is a potentially unsafe operation, because the life-time of the returned pointer may be longer than life-time of the source object, and this may cause dangling pointer dereference (like in regular C). +Returns C pointer to the given C data structure. The pointer is not "owned" and +won't be free. Anyway, this is a potentially unsafe operation, because the +life-time of the returned pointer may be longer than life-time of the source +object, and this may cause dangling pointer dereference (like in regular C). -##### static function load(string $filename): FFI; +### static function load(string $filename): FFI -Instead of embedding of a long C definition into PHP string, and creating FFI through FFI::cdef(), it's possible to separate it into a C header file. Note, that C preprocessor directives (e.g. #define or #ifdef) are not supported. And only a couple of special macros may be used especially for FFI. +Instead of embedding of a long C definition into PHP string, and creating FFI +through `FFI::cdef()`, it's possible to separate it into a C header file. Note, +that C preprocessor directives (e.g. `#define` or `#ifdef`) are not supported. +And only a couple of special macros may be used especially for FFI. -``` C +```c #define FFI_LIB "libc.so.6" int printf(const char *format, ...); @@ -216,41 +265,54 @@ int printf(const char *format, ...); Here, FFI_LIB specifies, that the given library should be loaded. -``` php +```php $ffi = FFI::load(__DIR__ . "/printf.h"); $ffi->printf("Hello world!\n"); - ``` -##### static function scope(string $name): FFI; +### static function scope(string $name): FFI -FFI definition parsing and shared library loading may take significant time. It's not useful to do it on each HTTP request in WEB environment. However, it's possible to pre-load FFI definitions and libraries at php startup, and instantiate FFI objects when necessary. Header files may be extended with **FFI_SCOPE** define (default pre-loading scope is "C"). This name is going to be used as **FFI::scope()** argument. It's possible to pre-load few files into a single scope. +FFI definition parsing and shared library loading may take significant time. +It's not useful to do it on each HTTP request in WEB environment. However, it's +possible to pre-load FFI definitions and libraries at php startup, and +instantiate FFI objects when necessary. Header files may be extended with +`FFI_SCOPE` define (default pre-loading scope is "C"). This name is going to +be used as `FFI::scope()` argument. It's possible to pre-load few files into a +single scope. -``` C +```c #define FFI_LIB "libc.so.6" #define FFI_SCOPE "libc" int printf(const char *format, ...); ``` -These files are loaded through the same **FFI::load()** load function, executed from file loaded by **opcache.preload** php.ini directive. +These files are loaded through the same `FFI::load()` load function, executed +from file loaded by `opcache.preload` php.ini directive. -``` ini +```ini ffi.preload=/etc/php/ffi/printf.h ``` -Finally, **FFI::scope()** instantiate an **FFI** object, that implements all C definition from the given scope. +Finally, `FFI::scope()` instantiates an `FFI` object, that implements all C +definitions from the given scope. -``` php +```php $ffi = FFI::scope("libc"); $ffi->printf("Hello world!\n"); ``` -##### Owned and Not-Owned CData +## Owned and not-owned CData -FFI extension uses two kind of native C data structures. "Owned" pointers are created using **FFI::new([, true])**, **clone**ed. Owned data is deallocated together with last PHP variable, that reference it. This mechanism reuses PHP reference-counting and garbage-collector. +FFI extension uses two kind of native C data structures. "Owned" pointers are +created using `FFI::new([, true])`, `clone`d. Owned data is deallocated +together with last PHP variable, that reference it. This mechanism reuses PHP +reference-counting and garbage-collector. -Elements of C arrays and structures, as well as most data structures returned by C functions are "not-owned". They work just as regular C pointers. They may leak memory, if not freed manually using **FFI::free()**, or may become dangling pointers and lead to PHP crashes. +Elements of C arrays and structures, as well as most data structures returned by +C functions are "not-owned". They work just as regular C pointers. They may leak +memory, if not freed manually using `FFI::free()`, or may become dangling +pointers and lead to PHP crashes. The following example demonstrates the problem. @@ -261,7 +323,8 @@ unset($p1); // $p1 is deallocated ($p2 became dangling pointer) var_dump($p2); // crash because dereferencing of dangling pointer ``` -It's possible to change ownership, to avoid this crash, but this would require manual memory management and may lead to memory leaks +It's possible to change ownership, to avoid this crash, but this would require +manual memory management and may lead to memory leaks. ```php $p1 = FFI::new("int[2][2]", false); // $p1 is not-owned pointer @@ -270,36 +333,50 @@ unset($p1); // $p1 CData is keep alive (memory leak) var_dump($p2); // works fine, except of memory leak ``` -##### PHP Callbacks +## PHP callbacks -It's possible to assign PHP function to native function variable (or pass it as a function argument). This seems to work, but this functionality is not supported on all libffi platforms, it is not efficient and leaks resources by the end of request. +It's possible to assign PHP function to native function variable (or pass it as +a function argument). This seems to work, but this functionality is not +supported on all libffi platforms, it is not efficient and leaks resources by +the end of request. -##### FFI API restriction +## FFI API restriction -With FFI users may do almost anything, like in C, and therefor may crash PHP in thousand ways. It's possible to completely disable or enable all FFI functions using ffi.enable=0/1 configuration directives, or limit FFI usage to preloaded scripts using ffi.enable=preload (this is the default setting). In case FFI is not completely disabled, it's also enabled for CLI scripts. Finally, the restriction affects only FFI functions their selves, but not the overloaded method of created FFI or CData objects. +With FFI users may do almost anything, like in C, and therefor may crash PHP in +thousand ways. It's possible to completely disable or enable all FFI functions +using `ffi.enable=0/1` configuration directives, or limit FFI usage to preloaded +scripts using `ffi.enable=preload` (this is the default setting). In case FFI is +not completely disabled, it's also enabled for CLI scripts. Finally, the +restriction affects only FFI functions their selves, but not the overloaded +method of created FFI or CData objects. -### Status +## Status -In current state, access to FFI data structures is significantly (about 2 times) slower, than access to PHP arrays and objects. It make no sense to use them for speed, but may make sense to reduce memory consumption. +In current state, access to FFI data structures is significantly (about 2 times) +slower, than access to PHP arrays and objects. It makes no sense to use them for +speed, but may make sense to reduce memory consumption. -FFI functionality may be included into PHP-8 core, to provide better interpretation performance and integrate with JIT, providing almost C performance (similar to LuaJIT) +FFI functionality may be included into PHP-8 core, to provide better +interpretation performance and integrate with JIT, providing almost C +performance (similar to LuaJIT). -### Requirement +## Requirement -- [libffi-3.*](http://sourceware.org/libffi/) +* [libffi-3.*](https://sourceware.org/libffi/) -### Install +## Installation -``` bash +```bash ./configure ... --with-ffi make sudo make install ``` -### Real Usage +## Real usage -FFI extension was used to implement [PHP TensorFlow binding](https://github.com/dstogov/php-tensorflow) +FFI extension was used to implement +[PHP TensorFlow binding](https://github.com/dstogov/php-tensorflow). -### FFI Parser +## FFI parser FFI C parser is generated using [LLK](https://github.com/dstogov/llk). diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index e124995c500c2..c47128e01acb5 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -5004,18 +5004,12 @@ static void zend_ffi_finalize_type(zend_ffi_dcl *dcl) /* {{{ */ dcl->type = (zend_ffi_type*)&zend_ffi_type_uint64; } break; -#ifdef _WIN32 - case ZEND_FFI_DCL_LONG_LONG: -#endif case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG: case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_SIGNED: case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_INT: case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_INT: dcl->type = (zend_ffi_type*)&zend_ffi_type_sint64; break; -#ifdef _WIN32 - case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_UNSIGNED: -#endif case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_UNSIGNED: case ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_INT: dcl->type = (zend_ffi_type*)&zend_ffi_type_uint64; @@ -6144,7 +6138,7 @@ void zend_ffi_add_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t na if (sizeof(long) == 8) { dcl->flags |= ZEND_FFI_DCL_LONG; } else { - dcl->flags |= ZEND_FFI_DCL_LONG_LONG; + dcl->flags |= ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_LONG_LONG; } break; } diff --git a/ext/fileinfo/generate_patch.sh b/ext/fileinfo/generate_patch.sh new file mode 100755 index 0000000000000..b7e9a38045f35 --- /dev/null +++ b/ext/fileinfo/generate_patch.sh @@ -0,0 +1,7 @@ +VERSION=5.33 +if [[ ! -d libmagic.orig ]]; then + mkdir libmagic.orig + wget -O - ftp://ftp.astron.com/pub/file/file-$VERSION.tar.gz \ + | tar -xz --strip-components=2 -C libmagic.orig file-$VERSION/src +fi +diff -u libmagic.orig libmagic | grep -v '^Only in' > libmagic.patch diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index 06b3aefc38f82..522bbcc71b8de 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c --- libmagic.orig/apprentice.c 2018-03-11 01:46:42.000000000 +0100 -+++ libmagic/apprentice.c 2018-11-05 00:16:58.812821826 +0100 ++++ libmagic/apprentice.c 2019-04-15 10:57:47.115181746 +0200 @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; @@ -96,7 +96,18 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c const char *, int); private struct mlist *mlist_alloc(void); private void mlist_free(struct mlist *); -@@ -170,38 +179,7 @@ +@@ -136,10 +145,7 @@ + private uint32_t swap4(uint32_t); + private uint64_t swap8(uint64_t); + private char *mkdbname(struct magic_set *, const char *, int); +-private struct magic_map *apprentice_buf(struct magic_set *, struct magic *, +- size_t); + private struct magic_map *apprentice_map(struct magic_set *, const char *); +-private int check_buffer(struct magic_set *, struct magic_map *, const char *); + private void apprentice_unmap(struct magic_map *); + private int apprentice_compile(struct magic_set *, struct magic_map *, + const char *); +@@ -170,38 +176,7 @@ { NULL, 0, NULL } }; @@ -136,7 +147,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c struct type_tbl_s { const char name[16]; -@@ -409,7 +387,7 @@ +@@ -409,7 +384,7 @@ struct mlist *ml; mlp->map = NULL; @@ -145,7 +156,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c return -1; ml->map = idx == 0 ? map : NULL; -@@ -430,10 +408,8 @@ +@@ -430,10 +405,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action) { struct magic_map *map; @@ -156,7 +167,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (magicsize != FILE_MAGICSIZE) { file_error(ms, 0, "magic element size %lu != %lu", -@@ -449,14 +425,15 @@ +@@ -449,14 +422,15 @@ return apprentice_compile(ms, map, fn); } @@ -176,7 +187,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (map == NULL) return -1; } -@@ -478,9 +455,6 @@ +@@ -478,9 +452,6 @@ } } return 0; @@ -186,7 +197,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } protected void -@@ -491,10 +465,16 @@ +@@ -491,10 +462,16 @@ return; for (i = 0; i < MAGIC_SETS; i++) mlist_free(ms->mlist[i]); @@ -207,7 +218,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } protected struct magic_set * -@@ -503,7 +483,7 @@ +@@ -503,7 +480,7 @@ struct magic_set *ms; size_t i, len; @@ -216,7 +227,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c sizeof(struct magic_set)))) == NULL) return NULL; -@@ -515,7 +495,7 @@ +@@ -515,7 +492,7 @@ ms->o.buf = ms->o.pbuf = NULL; len = (ms->c.len = 10) * sizeof(*ms->c.li); @@ -225,7 +236,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c goto free; ms->event_flags = 0; -@@ -533,48 +513,35 @@ +@@ -533,48 +510,35 @@ ms->bytes_max = FILE_BYTES_MAX; return ms; free: @@ -287,7 +298,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c return NULL; } mlist->next = mlist->prev = mlist; -@@ -593,60 +560,12 @@ +@@ -593,60 +557,12 @@ for (ml = mlist->next; (next = ml->next) != NULL; ml = next) { if (ml->map) apprentice_unmap(CAST(struct magic_map *, ml->map)); @@ -349,7 +360,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c /* const char *fn: list of magic files and directories */ protected int file_apprentice(struct magic_set *ms, const char *fn, int action) -@@ -655,14 +574,31 @@ +@@ -655,14 +571,31 @@ int fileerr, errs = -1; size_t i; @@ -383,7 +394,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c file_oomem(ms, strlen(fn)); return -1; } -@@ -675,7 +611,7 @@ +@@ -675,7 +608,7 @@ mlist_free(ms->mlist[i]); ms->mlist[i] = NULL; } @@ -392,7 +403,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c return -1; } } -@@ -692,7 +628,7 @@ +@@ -692,7 +625,7 @@ fn = p; } @@ -401,7 +412,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (errs == -1) { for (i = 0; i < MAGIC_SETS; i++) { -@@ -974,7 +910,7 @@ +@@ -974,7 +907,7 @@ return val; } @@ -410,7 +421,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c * Sort callback for sorting entries by "strength" (basically length) */ private int -@@ -992,7 +928,7 @@ +@@ -992,7 +925,7 @@ return 1; } @@ -419,7 +430,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c * Shows sorted patterns list in the order which is used for the matching */ private void -@@ -1088,7 +1024,7 @@ +@@ -1088,7 +1021,7 @@ mstart->flag |= BINTEST; if (mstart->str_flags & STRING_TEXTTEST) mstart->flag |= TEXTTEST; @@ -428,7 +439,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (mstart->flag & (TEXTTEST|BINTEST)) break; -@@ -1120,7 +1056,7 @@ +@@ -1120,7 +1053,7 @@ mset[i].max += ALLOC_INCR; if ((mp = CAST(struct magic_entry *, @@ -437,7 +448,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c NULL) { file_oomem(ms, sizeof(*mp) * mset[i].max); return -1; -@@ -1141,13 +1077,19 @@ +@@ -1141,13 +1074,19 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs, struct magic_entry_set *mset) { @@ -461,7 +472,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (errno != ENOENT) file_error(ms, errno, "cannot read magic file `%s'", fn); -@@ -1157,8 +1099,7 @@ +@@ -1157,8 +1096,7 @@ memset(&me, 0, sizeof(me)); /* read and parse this file */ @@ -471,7 +482,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (len == 0) /* null line, garbage, etc */ continue; if (line[len - 1] == '\n') { -@@ -1216,8 +1157,8 @@ +@@ -1216,8 +1154,8 @@ } if (me.mp) (void)addentry(ms, &me, mset); @@ -482,7 +493,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } /* -@@ -1280,7 +1221,7 @@ +@@ -1280,7 +1218,7 @@ file_magwarn(ms, "level 0 \"default\" did not sort last"); } @@ -491,7 +502,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } } } -@@ -1296,7 +1237,7 @@ +@@ -1296,7 +1234,7 @@ mentrycount += me[i].cont_count; slen = sizeof(**ma) * mentrycount; @@ -500,7 +511,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c file_oomem(ms, slen); return -1; } -@@ -1318,8 +1259,8 @@ +@@ -1318,8 +1256,8 @@ if (me == NULL) return; for (i = 0; i < nme; i++) @@ -511,7 +522,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } private struct magic_map * -@@ -1328,18 +1269,19 @@ +@@ -1328,18 +1266,19 @@ int errs = 0; uint32_t i, j; size_t files = 0, maxfiles = 0; @@ -536,7 +547,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c { file_oomem(ms, sizeof(*map)); return NULL; -@@ -1351,24 +1293,26 @@ +@@ -1351,24 +1290,26 @@ (void)fprintf(stderr, "%s\n", usg_hdr); /* load directory or file */ @@ -573,7 +584,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c continue; } if (files >= maxfiles) { -@@ -1376,23 +1320,22 @@ +@@ -1376,23 +1317,22 @@ maxfiles = (maxfiles + 1) * 2; mlen = maxfiles * sizeof(*filearr); if ((filearr = CAST(char **, @@ -603,7 +614,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } else load_1(ms, action, fn, &errs, mset); if (errs) -@@ -1833,7 +1776,7 @@ +@@ -1833,7 +1773,7 @@ */ while (*l == '>') { ++l; /* step over */ @@ -612,7 +623,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } #ifdef ENABLE_CONDITIONALS if (cont_level == 0 || cont_level > last_cont_level) -@@ -1859,7 +1802,7 @@ +@@ -1859,7 +1799,7 @@ if (me->cont_count == me->max_count) { struct magic *nm; size_t cnt = me->max_count + ALLOC_CHUNK; @@ -621,7 +632,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c sizeof(*nm) * cnt))) == NULL) { file_oomem(ms, sizeof(*nm) * cnt); return -1; -@@ -1874,7 +1817,7 @@ +@@ -1874,7 +1814,7 @@ static const size_t len = sizeof(*m) * ALLOC_CHUNK; if (me->mp != NULL) return 1; @@ -630,7 +641,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c file_oomem(ms, len); return -1; } -@@ -1916,17 +1859,6 @@ +@@ -1916,17 +1856,6 @@ file_magwarn(ms, "offset `%s' invalid", l); return -1; } @@ -648,7 +659,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c l = t; if (m->flag & INDIR) { -@@ -2012,7 +1944,7 @@ +@@ -2012,7 +1941,7 @@ } l = t; } @@ -657,7 +668,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, -@@ -2037,7 +1969,7 @@ +@@ -2037,7 +1966,7 @@ /* * Try it as a keyword type prefixed by "u"; match what * follows the "u". If that fails, try it as an SUS @@ -666,7 +677,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c */ m->type = get_type(type_tbl, l + 1, &l); if (m->type == FILE_INVALID) { -@@ -2077,7 +2009,7 @@ +@@ -2077,7 +2006,7 @@ /* Not found - try it as a special keyword. */ m->type = get_type(special_tbl, l, &l); } @@ -675,7 +686,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (m->type == FILE_INVALID) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "type `%s' invalid", l); -@@ -2089,7 +2021,7 @@ +@@ -2089,7 +2018,7 @@ m->mask_op = 0; if (*l == '~') { @@ -684,7 +695,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c m->mask_op |= FILE_OPINVERSE; else if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "'~' invalid for string types"); -@@ -2098,7 +2030,7 @@ +@@ -2098,7 +2027,7 @@ m->str_range = 0; m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0; if ((op = get_op(*l)) != -1) { @@ -693,7 +704,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c int r; if (op != FILE_OPDIVIDE) { -@@ -2124,7 +2056,7 @@ +@@ -2124,7 +2053,7 @@ * anything if mask = 0 (unless you have a better idea) */ EATAB; @@ -702,7 +713,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c switch (*l) { case '>': case '<': -@@ -2156,7 +2088,7 @@ +@@ -2156,7 +2085,7 @@ break; default: m->reln = '='; /* the default relation */ @@ -711,7 +722,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c isspace((unsigned char)l[1])) || !l[1])) { m->reln = *l; ++l; -@@ -2171,7 +2103,7 @@ +@@ -2171,7 +2100,7 @@ /* * TODO finish this macro and start using it! @@ -720,7 +731,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c * magwarn("offset too big"); } */ -@@ -2203,11 +2135,6 @@ +@@ -2203,11 +2132,6 @@ if (check_format(ms, m) == -1) return -1; } @@ -732,7 +743,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c m->mimetype[0] = '\0'; /* initialise MIME type to none */ return 0; } -@@ -2279,7 +2206,7 @@ +@@ -2279,7 +2203,7 @@ private int parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, @@ -741,7 +752,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c { size_t i; const char *l = line; -@@ -2291,7 +2218,7 @@ +@@ -2291,7 +2215,7 @@ file_magwarn(ms, "Current entry already has a %s type " "`%.*s', new type `%s'", name, (int)len, buf, l); return -1; @@ -750,7 +761,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (*m->desc == '\0') { file_magwarn(ms, "Current entry does not yet have a " -@@ -2361,7 +2288,7 @@ +@@ -2361,7 +2285,7 @@ struct magic *m = &me->mp[0]; return parse_extra(ms, me, line, @@ -759,7 +770,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1); } -@@ -2428,7 +2355,7 @@ +@@ -2428,7 +2352,7 @@ if (*ptr++ != 'l') goto invalid; } @@ -768,7 +779,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c switch (*ptr++) { #ifdef STRICT_FORMAT /* "long" formats are int formats for us */ /* so don't accept the 'l' modifier */ -@@ -2446,7 +2373,7 @@ +@@ -2446,7 +2370,7 @@ default: goto invalid; } @@ -777,7 +788,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c /* * Don't accept h and hh modifiers. They make writing * magic entries more complicated, for very little benefit -@@ -2502,7 +2429,7 @@ +@@ -2502,7 +2426,7 @@ default: goto invalid; } @@ -786,7 +797,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c case FILE_FMT_FLOAT: case FILE_FMT_DOUBLE: if (*ptr == '-') -@@ -2521,11 +2448,11 @@ +@@ -2521,11 +2445,11 @@ case 'g': case 'G': return 0; @@ -800,7 +811,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c case FILE_FMT_STR: if (*ptr == '-') -@@ -2537,14 +2464,14 @@ +@@ -2537,14 +2461,14 @@ while (isdigit((unsigned char )*ptr)) ptr++; } @@ -817,7 +828,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c default: /* internal error */ abort(); -@@ -2555,7 +2482,7 @@ +@@ -2555,7 +2479,7 @@ *estr = "too long"; return -1; } @@ -826,7 +837,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c /* * Check that the optional printf format in description matches * the type of the magic. -@@ -2578,7 +2505,7 @@ +@@ -2578,7 +2502,7 @@ if (m->type >= file_nformats) { file_magwarn(ms, "Internal error inconsistency between " @@ -835,7 +846,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c return -1; } if (file_formats[m->type] == FILE_FMT_NONE) { -@@ -2598,7 +2525,7 @@ +@@ -2598,7 +2522,7 @@ file_names[m->type], m->desc); return -1; } @@ -844,7 +855,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c for (; *ptr; ptr++) { if (*ptr == '%') { file_magwarn(ms, -@@ -2611,9 +2538,9 @@ +@@ -2611,9 +2535,9 @@ return 0; } @@ -857,7 +868,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c * just after the number read. Return 0 for success, non-zero for failure. */ private int -@@ -2640,14 +2567,19 @@ +@@ -2640,14 +2564,19 @@ return -1; } if (m->type == FILE_REGEX) { @@ -884,7 +895,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c } return 0; default: -@@ -2770,7 +2702,7 @@ +@@ -2770,7 +2699,7 @@ default: if (warn) { if (isprint((unsigned char)c)) { @@ -893,7 +904,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c * ``relations'' */ if (strchr("<>&^=!", c) == NULL && (m->type != FILE_REGEX || -@@ -2975,7 +2907,7 @@ +@@ -2975,7 +2904,7 @@ { const char *l = *p; @@ -902,7 +913,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c l++; switch (LOWCASE(*l)) { -@@ -3001,7 +2933,7 @@ +@@ -2993,6 +2922,7 @@ + *p = l; + } + ++#if 0 + /* + * handle a buffer containing a compiled file. + */ +@@ -3001,7 +2931,7 @@ { struct magic_map *map; @@ -911,14 +930,22 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c file_oomem(ms, sizeof(*map)); return NULL; } -@@ -3022,79 +2954,145 @@ +@@ -3014,6 +2944,7 @@ + } + return map; + } ++#endif + + /* + * handle a compiled file. +@@ -3022,81 +2953,148 @@ private struct magic_map * apprentice_map(struct magic_set *ms, const char *fn) { - int fd; - struct stat st; + uint32_t *ptr; -+ uint32_t version, entries, nentries; ++ uint32_t version, entries = 0, nentries; + int needsbyteswap; char *dbname = NULL; struct magic_map *map; @@ -926,11 +953,11 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c + size_t i; + php_stream *stream = NULL; + php_stream_statbuf st; -+ -+ - fd = -1; - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { ++ ++ + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) { file_oomem(ms, sizeof(*map)); - goto error; @@ -1093,7 +1120,10 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c + return NULL; } ++#if 0 private int + check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) + { @@ -3120,7 +3118,7 @@ version = ptr[1]; if (version != VERSIONNO) { @@ -1103,7 +1133,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c VERSIONNO, dbname, version); return -1; } -@@ -3161,7 +3159,6 @@ +@@ -3152,6 +3150,7 @@ + byteswap(map->magic[i], map->nmagic[i]); + return 0; + } ++#endif + + /* + * handle an mmaped file. +@@ -3161,7 +3160,6 @@ { static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS; static const size_t m = sizeof(**map->magic); @@ -1111,7 +1149,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c size_t len; char *dbname; int rv = -1; -@@ -3170,14 +3167,17 @@ +@@ -3170,14 +3168,17 @@ struct magic m; uint32_t h[2 + MAGIC_SETS]; } hdr; @@ -1132,7 +1170,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c file_error(ms, errno, "cannot open `%s'", dbname); goto out; } -@@ -3186,26 +3186,25 @@ +@@ -3186,26 +3187,25 @@ hdr.h[1] = VERSIONNO; memcpy(hdr.h + 2, map->nmagic, nm); @@ -1167,7 +1205,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c return rv; } -@@ -3239,16 +3238,18 @@ +@@ -3239,16 +3239,18 @@ q++; /* Compatibility with old code that looked in .mime */ if (ms->flags & MAGIC_MIME) { @@ -1192,7 +1230,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c /* Compatibility with old code that looked in .mime */ if (strstr(fn, ".mime") != NULL) -@@ -3274,8 +3275,8 @@ +@@ -3274,8 +3276,8 @@ swap2(uint16_t sv) { uint16_t rv; @@ -1203,7 +1241,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c d[0] = s[1]; d[1] = s[0]; return rv; -@@ -3288,8 +3289,8 @@ +@@ -3288,8 +3290,8 @@ swap4(uint32_t sv) { uint32_t rv; @@ -1214,7 +1252,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; -@@ -3304,8 +3305,8 @@ +@@ -3304,8 +3306,8 @@ swap8(uint64_t sv) { uint64_t rv; @@ -1225,7 +1263,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c #if 0 d[0] = s[3]; d[1] = s[2]; -@@ -3338,7 +3339,7 @@ +@@ -3338,7 +3340,7 @@ m->offset = swap4((int32_t)m->offset); m->in_offset = swap4((uint32_t)m->in_offset); m->lineno = swap4((uint32_t)m->lineno); @@ -1234,7 +1272,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c m->str_range = swap4(m->str_range); m->str_flags = swap4(m->str_flags); } -@@ -3348,7 +3349,7 @@ +@@ -3348,7 +3350,7 @@ } } @@ -1245,7 +1283,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c switch (m->str_flags & PSTRING_LEN) { diff -u libmagic.orig/apptype.c libmagic/apptype.c --- libmagic.orig/apptype.c 2011-09-07 23:57:15.000000000 +0200 -+++ libmagic/apptype.c 2018-08-10 11:46:29.210671445 +0200 ++++ libmagic/apptype.c 2019-03-08 09:31:16.392796494 +0100 @@ -1,15 +1,15 @@ /* * Adapted from: apptype.c, Written by Eberhard Mattes and put into the @@ -1280,7 +1318,7 @@ diff -u libmagic.orig/apptype.c libmagic/apptype.c #include "file.h" diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c --- libmagic.orig/ascmagic.c 2017-11-02 21:25:39.000000000 +0100 -+++ libmagic/ascmagic.c 2018-08-10 11:46:29.210671445 +0200 ++++ libmagic/ascmagic.c 2019-03-08 09:31:16.392796494 +0100 @@ -90,7 +90,7 @@ rv = file_ascmagic_with_encoding(ms, &bb, ubuf, ulen, code, type, text); @@ -1311,7 +1349,7 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c } diff -u libmagic.orig/buffer.c libmagic/buffer.c --- libmagic.orig/buffer.c 2018-03-11 01:46:42.000000000 +0100 -+++ libmagic/buffer.c 2018-08-10 11:46:29.210671445 +0200 ++++ libmagic/buffer.c 2019-03-08 09:31:16.392796494 +0100 @@ -31,7 +31,11 @@ #endif /* lint */ @@ -1362,7 +1400,7 @@ diff -u libmagic.orig/buffer.c libmagic/buffer.c diff -u libmagic.orig/cdf.c libmagic/cdf.c --- libmagic.orig/cdf.c 2018-03-11 01:46:42.000000000 +0100 -+++ libmagic/cdf.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/cdf.c 2019-04-12 12:02:54.279893504 +0200 @@ -43,7 +43,17 @@ #include #endif @@ -1431,7 +1469,19 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c scn->sst_tab = NULL; return -1; } -@@ -336,12 +318,13 @@ +@@ -311,9 +293,11 @@ + static size_t + cdf_check_stream(const cdf_stream_t *sst, const cdf_header_t *h) + { ++#ifndef NDEBUG + size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? + CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); + assert(ss == sst->sst_ss); ++#endif + return sst->sst_ss; + } + +@@ -336,12 +320,13 @@ } static ssize_t @@ -1447,7 +1497,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c if (info->i_buf != NULL && info->i_len >= siz) { (void)memcpy(buf, &info->i_buf[off], len); -@@ -351,7 +334,10 @@ +@@ -351,7 +336,10 @@ if (info->i_fd == -1) goto out; @@ -1459,7 +1509,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c return -1; return (ssize_t)len; -@@ -366,7 +352,7 @@ +@@ -366,7 +354,7 @@ char buf[512]; (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); @@ -1468,15 +1518,29 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c return -1; cdf_unpack_header(h, buf); cdf_swap_header(h); -@@ -400,7 +386,7 @@ - size_t ss = CDF_SEC_SIZE(h); +@@ -397,19 +385,17 @@ + cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, + const cdf_header_t *h, cdf_secid_t id) + { +- size_t ss = CDF_SEC_SIZE(h); size_t pos = CDF_SEC_POS(h, id); - assert(ss == len); +- assert(ss == len); - return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len); ++ assert(CDF_SEC_SIZE(h) == len); + return cdf_read(info, (zend_off_t)pos, ((char *)buf) + offs, len); } ssize_t + cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, + size_t len, const cdf_header_t *h, cdf_secid_t id) + { +- size_t ss = CDF_SHORT_SEC_SIZE(h); + size_t pos = CDF_SHORT_SEC_POS(h, id); +- assert(ss == len); ++ assert(CDF_SHORT_SEC_SIZE(h) == len); + if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { + DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" + SIZE_T_FORMAT "u\n", @@ -501,14 +487,14 @@ } out: @@ -1620,7 +1684,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c #endif diff -u libmagic.orig/cdf.h libmagic/cdf.h --- libmagic.orig/cdf.h 2017-03-09 17:57:17.000000000 +0100 -+++ libmagic/cdf.h 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/cdf.h 2019-03-08 09:31:16.392796494 +0100 @@ -35,10 +35,10 @@ #ifndef _H_CDF_ #define _H_CDF_ @@ -1646,7 +1710,7 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c --- libmagic.orig/cdf_time.c 2017-03-29 17:57:48.000000000 +0200 -+++ libmagic/cdf_time.c 2019-03-08 21:00:46.636733574 +0100 ++++ libmagic/cdf_time.c 2019-03-22 11:57:57.251021738 +0100 @@ -23,6 +23,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. @@ -1693,7 +1757,7 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n", diff -u libmagic.orig/compress.c libmagic/compress.c --- libmagic.orig/compress.c 2017-11-02 21:25:39.000000000 +0100 -+++ libmagic/compress.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/compress.c 2019-04-12 10:04:15.721646341 +0200 @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; @@ -1746,7 +1810,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #include #endif #ifdef HAVE_SYS_WAIT_H -@@ -62,51 +60,12 @@ +@@ -62,56 +60,18 @@ #if defined(HAVE_SYS_TIME_H) #include #endif @@ -1800,7 +1864,20 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #define gzip_flags "-cd" #define lrzip_flags "-do" -@@ -169,7 +128,7 @@ + #define lzip_flags gzip_flags + ++#ifdef PHP_FILEINFO_UNCOMPRESS + static const char *gzip_args[] = { + "gzip", gzip_flags, NULL + }; +@@ -163,13 +123,14 @@ + { RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */ + #endif + }; ++#endif + + #define OKDATA 0 + #define NODATA 1 #define ERRDATA 2 private ssize_t swrite(int, const void *, size_t); @@ -1809,7 +1886,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c private size_t ncompr = sizeof(compr) / sizeof(compr[0]); private int uncompressbuf(int, size_t, size_t, const unsigned char *, unsigned char **, size_t *); -@@ -179,12 +138,12 @@ +@@ -179,12 +140,12 @@ private int uncompressgzipped(const unsigned char *, unsigned char **, size_t, size_t *); #endif @@ -1825,7 +1902,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c { unsigned char *newbuf = NULL; size_t i, nsz; -@@ -192,9 +151,6 @@ +@@ -192,9 +153,6 @@ file_pushbuf_t *pb; int urv, prv, rv = 0; int mime = ms->flags & MAGIC_MIME; @@ -1835,7 +1912,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #ifdef HAVE_SIGNAL_H sig_t osigpipe; #endif -@@ -226,7 +182,7 @@ +@@ -226,7 +184,7 @@ switch (urv) { case OKDATA: case ERRDATA: @@ -1844,7 +1921,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c ms->flags &= ~MAGIC_COMPRESS; if (urv == ERRDATA) prv = file_printf(ms, "%s ERROR: %s", -@@ -253,10 +209,10 @@ +@@ -253,10 +211,10 @@ goto error; if ((rbuf = file_pop_buffer(ms, pb)) != NULL) { if (file_printf(ms, "%s", rbuf) == -1) { @@ -1857,7 +1934,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c } if (!mime && file_printf(ms, ")") == -1) goto error; -@@ -277,7 +233,8 @@ +@@ -277,7 +235,8 @@ #ifdef HAVE_SIGNAL_H (void)signal(SIGPIPE, osigpipe); #endif @@ -1867,7 +1944,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c ms->flags |= MAGIC_COMPRESS; DPRINTF("Zmagic returns %d\n", rv); return rv; -@@ -312,7 +269,7 @@ +@@ -312,7 +271,7 @@ * `safe' read for sockets and pipes. */ protected ssize_t @@ -1876,7 +1953,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c { ssize_t rv; #ifdef FIONREAD -@@ -360,7 +317,7 @@ +@@ -360,7 +319,7 @@ nocheck: do @@ -1885,7 +1962,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c case -1: if (errno == EINTR) continue; -@@ -437,13 +394,14 @@ +@@ -437,13 +396,14 @@ return -1; } (void)close(tfd); @@ -1902,7 +1979,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #ifdef BUILTIN_DECOMPRESS #define FHCRC (1 << 1) -@@ -494,7 +452,7 @@ +@@ -494,7 +454,7 @@ int rc; z_stream z; @@ -1911,7 +1988,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c return makeerror(newch, n, "No buffer, %s", strerror(errno)); z.next_in = CCAST(Bytef *, old); -@@ -518,7 +476,7 @@ +@@ -518,7 +478,7 @@ rc = inflateEnd(&z); if (rc != Z_OK) goto err; @@ -1920,7 +1997,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c /* let's keep the nul-terminate tradition */ (*newch)[*n] = '\0'; -@@ -586,7 +544,7 @@ +@@ -586,7 +546,7 @@ int status; closefd(fdp[STDIN_FILENO], 0); @@ -1929,7 +2006,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c * fork again, to avoid blocking because both * pipes filled */ -@@ -689,13 +647,13 @@ +@@ -689,13 +649,13 @@ fdp[STDIN_FILENO][0] = fd; (void) lseek(fd, (off_t)0, SEEK_SET); } @@ -1945,7 +2022,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c compr[method].argv[0], strerror(errno)); exit(1); /*NOTREACHED*/ -@@ -711,7 +669,7 @@ +@@ -711,7 +671,7 @@ if (fd == -1) writechild(fdp, old, *n); @@ -1954,7 +2031,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c if (*newch == NULL) { rv = makeerror(newch, n, "No buffer, %s", strerror(errno)); -@@ -730,7 +688,7 @@ +@@ -730,7 +690,7 @@ r = filter_error(*newch, r); break; } @@ -1963,7 +2040,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c if (r == 0) rv = makeerror(newch, n, "Read failed, %s", strerror(errno)); -@@ -738,27 +696,5 @@ +@@ -738,27 +698,5 @@ rv = makeerror(newch, n, "No data"); goto err; } @@ -1994,7 +2071,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c +#endif /* if PHP_FILEINFO_UNCOMPRESS */ diff -u libmagic.orig/der.c libmagic/der.c --- libmagic.orig/der.c 2017-02-10 19:14:01.000000000 +0100 -+++ libmagic/der.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/der.c 2019-03-08 09:31:16.392796494 +0100 @@ -51,7 +51,9 @@ #include "magic.h" #include "der.h" @@ -2051,7 +2128,7 @@ diff -u libmagic.orig/der.c libmagic/der.c der_tag(buf, sizeof(buf), tag), len); diff -u libmagic.orig/elfclass.h libmagic/elfclass.h --- libmagic.orig/elfclass.h 2014-12-17 00:18:40.000000000 +0100 -+++ libmagic/elfclass.h 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/elfclass.h 2019-03-08 09:31:16.392796494 +0100 @@ -1,7 +1,7 @@ /* * Copyright (c) Christos Zoulas 2008. @@ -2099,7 +2176,7 @@ diff -u libmagic.orig/elfclass.h libmagic/elfclass.h (int)elf_getu16(swap, elfhdr.e_shstrndx), diff -u libmagic.orig/encoding.c libmagic/encoding.c --- libmagic.orig/encoding.c 2017-11-02 21:25:39.000000000 +0100 -+++ libmagic/encoding.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/encoding.c 2019-03-08 09:31:16.392796494 +0100 @@ -88,12 +88,12 @@ *code_mime = "binary"; @@ -2129,7 +2206,7 @@ diff -u libmagic.orig/encoding.c libmagic/encoding.c } diff -u libmagic.orig/file.h libmagic/file.h --- libmagic.orig/file.h 2018-03-11 01:46:42.000000000 +0100 -+++ libmagic/file.h 2018-11-05 21:31:59.339653700 +0100 ++++ libmagic/file.h 2019-03-08 09:31:16.392796494 +0100 @@ -27,21 +27,15 @@ */ /* @@ -2416,7 +2493,7 @@ diff -u libmagic.orig/file.h libmagic/file.h #endif diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c --- libmagic.orig/fsmagic.c 2017-05-24 21:17:50.000000000 +0200 -+++ libmagic/fsmagic.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/fsmagic.c 2019-03-08 09:31:16.392796494 +0100 @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; @@ -2777,7 +2854,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c case S_IFSOCK: diff -u libmagic.orig/funcs.c libmagic/funcs.c --- libmagic.orig/funcs.c 2017-11-02 21:25:39.000000000 +0100 -+++ libmagic/funcs.c 2018-11-05 21:31:59.339653700 +0100 ++++ libmagic/funcs.c 2019-03-25 16:13:59.574598917 +0100 @@ -31,7 +31,6 @@ #endif /* lint */ @@ -2786,7 +2863,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c #include #include #include -@@ -42,78 +41,77 @@ +@@ -42,78 +41,76 @@ #if defined(HAVE_WCTYPE_H) #include #endif @@ -3161,7 +3238,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c diff -u libmagic.orig/magic.c libmagic/magic.c --- libmagic.orig/magic.c 2017-08-28 15:39:18.000000000 +0200 -+++ libmagic/magic.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/magic.c 2019-04-12 10:04:15.721646341 +0200 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -3198,18 +3275,17 @@ diff -u libmagic.orig/magic.c libmagic/magic.c #if defined(HAVE_UTIMES) # include -@@ -71,194 +71,23 @@ +@@ -71,194 +71,21 @@ #endif #endif +-private void close_and_restore(const struct magic_set *, const char *, int, +- const struct stat *); +#ifdef PHP_WIN32 +# undef S_IFLNK +# undef S_IFIFO +#endif + - private void close_and_restore(const struct magic_set *, const char *, int, -- const struct stat *); -+ const zend_stat_t *); private int unreadable_info(struct magic_set *, mode_t, const char *); +#if 0 private const char* get_default_magic(void); @@ -3401,7 +3477,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public struct magic_set * magic_open(int flags) { -@@ -304,20 +133,6 @@ +@@ -304,20 +131,6 @@ return file_apprentice(ms, magicfile, FILE_LOAD); } @@ -3422,8 +3498,11 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public int magic_compile(struct magic_set *ms, const char *magicfile) { -@@ -344,7 +159,7 @@ +@@ -342,9 +155,10 @@ + return file_apprentice(ms, magicfile, FILE_LIST); + } ++#if 0 private void close_and_restore(const struct magic_set *ms, const char *name, int fd, - const struct stat *sb) @@ -3431,9 +3510,11 @@ diff -u libmagic.orig/magic.c libmagic/magic.c { if (fd == STDIN_FILENO || name == NULL) return; -@@ -375,7 +190,6 @@ +@@ -374,8 +188,8 @@ + #endif } } ++#endif -#ifndef COMPILE_ONLY @@ -3636,20 +3717,9 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public const char * magic_error(struct magic_set *ms) -diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2018-11-13 21:40:06.272616270 +0100 -+++ libmagic/magic.h 2018-08-10 11:46:29.214671395 +0200 -@@ -122,6 +122,7 @@ - - const char *magic_getpath(const char *, int); - const char *magic_file(magic_t, const char *); -+const char *magic_stream(magic_t, php_stream *); - const char *magic_descriptor(magic_t, int); - const char *magic_buffer(magic_t, const void *, size_t); - diff -u libmagic.orig/print.c libmagic/print.c --- libmagic.orig/print.c 2017-02-10 19:14:01.000000000 +0100 -+++ libmagic/print.c 2019-03-08 21:00:46.636733574 +0100 ++++ libmagic/print.c 2019-03-22 11:57:57.251021738 +0100 @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; @@ -3732,7 +3802,7 @@ diff -u libmagic.orig/print.c libmagic/print.c goto out; diff -u libmagic.orig/readcdf.c libmagic/readcdf.c --- libmagic.orig/readcdf.c 2017-11-02 21:25:39.000000000 +0100 -+++ libmagic/readcdf.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/readcdf.c 2019-03-08 09:31:16.396796480 +0100 @@ -31,7 +31,11 @@ #include @@ -3869,7 +3939,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c if (NOTMIME(ms)) { diff -u libmagic.orig/softmagic.c libmagic/softmagic.c --- libmagic.orig/softmagic.c 2018-04-15 20:49:15.000000000 +0200 -+++ libmagic/softmagic.c 2018-11-11 21:42:27.860274508 +0100 ++++ libmagic/softmagic.c 2019-03-25 16:13:59.574598917 +0100 @@ -43,6 +43,10 @@ #include #include "der.h" @@ -3920,7 +3990,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c - file_regex_t rx; - int rc, rv = -1; + pcre2_code *pce; -+ uint32_t re_options, capture_count; ++ uint32_t capture_count; + int rv = -1; + zend_string *pattern; @@ -3932,14 +4002,14 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c - file_regerror(&rx, rc, ms); + (void)setlocale(LC_CTYPE, "C"); + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0); -+ if ((pce = pcre_get_compiled_regex(pattern, &capture_count, &re_options)) == NULL) { ++ if ((pce = pcre_get_compiled_regex(pattern, &capture_count)) == NULL) { + rv = -1; } else { - rc = file_regexec(&rx, fmt, 0, 0, 0); - rv = !rc; + pcre2_match_data *match_data = php_pcre_create_match_data(capture_count, pce); + if (match_data) { -+ rv = pcre2_match(pce, (PCRE2_SPTR)fmt, strlen(fmt), 0, re_options, match_data, php_pcre_mctx()) > 0; ++ rv = pcre2_match(pce, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0; + php_pcre_free_match_data(match_data); + } } @@ -4228,7 +4298,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c case FILE_INDIRECT: diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c --- libmagic.orig/strcasestr.c 2014-05-13 18:48:12.000000000 +0200 -+++ libmagic/strcasestr.c 2018-08-10 11:46:29.214671395 +0200 ++++ libmagic/strcasestr.c 2019-03-08 09:31:16.396796480 +0100 @@ -39,6 +39,8 @@ #include "file.h" diff --git a/ext/fileinfo/libmagic/apprentice.c b/ext/fileinfo/libmagic/apprentice.c index 94e4302d619e0..b9bb65898c78a 100644 --- a/ext/fileinfo/libmagic/apprentice.c +++ b/ext/fileinfo/libmagic/apprentice.c @@ -145,10 +145,7 @@ private uint16_t swap2(uint16_t); private uint32_t swap4(uint32_t); private uint64_t swap8(uint64_t); private char *mkdbname(struct magic_set *, const char *, int); -private struct magic_map *apprentice_buf(struct magic_set *, struct magic *, - size_t); private struct magic_map *apprentice_map(struct magic_set *, const char *); -private int check_buffer(struct magic_set *, struct magic_map *, const char *); private void apprentice_unmap(struct magic_map *); private int apprentice_compile(struct magic_set *, struct magic_map *, const char *); @@ -2925,6 +2922,7 @@ eatsize(const char **p) *p = l; } +#if 0 /* * handle a buffer containing a compiled file. */ @@ -2946,6 +2944,7 @@ apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len) } return map; } +#endif /* * handle a compiled file. @@ -2955,7 +2954,7 @@ private struct magic_map * apprentice_map(struct magic_set *ms, const char *fn) { uint32_t *ptr; - uint32_t version, entries, nentries; + uint32_t version, entries = 0, nentries; int needsbyteswap; char *dbname = NULL; struct magic_map *map; @@ -3095,6 +3094,7 @@ apprentice_map(struct magic_set *ms, const char *fn) return NULL; } +#if 0 private int check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) { @@ -3150,6 +3150,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) byteswap(map->magic[i], map->nmagic[i]); return 0; } +#endif /* * handle an mmaped file. diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c index 050bf637bf020..ac70e5bac1840 100644 --- a/ext/fileinfo/libmagic/cdf.c +++ b/ext/fileinfo/libmagic/cdf.c @@ -293,9 +293,11 @@ cdf_zero_stream(cdf_stream_t *scn) static size_t cdf_check_stream(const cdf_stream_t *sst, const cdf_header_t *h) { +#ifndef NDEBUG size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); assert(ss == sst->sst_ss); +#endif return sst->sst_ss; } @@ -383,9 +385,8 @@ ssize_t cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { - size_t ss = CDF_SEC_SIZE(h); size_t pos = CDF_SEC_POS(h, id); - assert(ss == len); + assert(CDF_SEC_SIZE(h) == len); return cdf_read(info, (zend_off_t)pos, ((char *)buf) + offs, len); } @@ -393,9 +394,8 @@ ssize_t cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { - size_t ss = CDF_SHORT_SEC_SIZE(h); size_t pos = CDF_SHORT_SEC_POS(h, id); - assert(ss == len); + assert(CDF_SHORT_SEC_SIZE(h) == len); if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", diff --git a/ext/fileinfo/libmagic/compress.c b/ext/fileinfo/libmagic/compress.c index 024b569ac2f33..a66cf806bc653 100644 --- a/ext/fileinfo/libmagic/compress.c +++ b/ext/fileinfo/libmagic/compress.c @@ -71,6 +71,7 @@ typedef void (*sig_t)(int); #define lrzip_flags "-do" #define lzip_flags gzip_flags +#ifdef PHP_FILEINFO_UNCOMPRESS static const char *gzip_args[] = { "gzip", gzip_flags, NULL }; @@ -122,6 +123,7 @@ private const struct { { RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */ #endif }; +#endif #define OKDATA 0 #define NODATA 1 diff --git a/ext/fileinfo/libmagic/magic.c b/ext/fileinfo/libmagic/magic.c index 51570c2a3751f..1cff11a5c0f7a 100644 --- a/ext/fileinfo/libmagic/magic.c +++ b/ext/fileinfo/libmagic/magic.c @@ -76,8 +76,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $") # undef S_IFIFO #endif -private void close_and_restore(const struct magic_set *, const char *, int, - const zend_stat_t *); private int unreadable_info(struct magic_set *, mode_t, const char *); #if 0 private const char* get_default_magic(void); @@ -157,6 +155,7 @@ magic_list(struct magic_set *ms, const char *magicfile) return file_apprentice(ms, magicfile, FILE_LIST); } +#if 0 private void close_and_restore(const struct magic_set *ms, const char *name, int fd, const zend_stat_t *sb) @@ -189,6 +188,7 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd, #endif } } +#endif /* diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 0196ef207d24d..b1343976b668c 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1391,20 +1391,71 @@ ftp_getresp(ftpbuf_t *ftp) } /* }}} */ -/* {{{ my_send - */ -int -my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) -{ - zend_long size, sent; - int n; +int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) { #ifdef HAVE_FTP_SSL int err; zend_bool retry = 0; SSL *handle = NULL; php_socket_t fd; + size_t sent; + + if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) { + handle = ftp->ssl_handle; + fd = ftp->fd; + } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) { + handle = ftp->data->ssl_handle; + fd = ftp->data->fd; + } else { + return send(s, buf, size, 0); + } + + do { + sent = SSL_write(handle, buf, size); + err = SSL_get_error(handle, sent); + + switch (err) { + case SSL_ERROR_NONE: + retry = 0; + break; + + case SSL_ERROR_ZERO_RETURN: + retry = 0; + SSL_shutdown(handle); + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_CONNECT: { + php_pollfd p; + int i; + + p.fd = fd; + p.events = POLLOUT; + p.revents = 0; + + i = php_poll2(&p, 1, 300); + + retry = i > 0; + } + break; + + default: + php_error_docref(NULL, E_WARNING, "SSL write failed"); + return -1; + } + } while (retry); + return sent; +#else + return send(s, buf, size, 0); #endif +} +/* {{{ my_send + */ +int +my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) +{ + zend_long size, sent; + int n; size = len; while (size) { @@ -1423,56 +1474,7 @@ my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) return -1; } -#ifdef HAVE_FTP_SSL - if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) { - handle = ftp->ssl_handle; - fd = ftp->fd; - } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) { - handle = ftp->data->ssl_handle; - fd = ftp->data->fd; - } - - if (handle) { - do { - sent = SSL_write(handle, buf, size); - err = SSL_get_error(handle, sent); - - switch (err) { - case SSL_ERROR_NONE: - retry = 0; - break; - - case SSL_ERROR_ZERO_RETURN: - retry = 0; - SSL_shutdown(handle); - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_CONNECT: { - php_pollfd p; - int i; - - p.fd = fd; - p.events = POLLOUT; - p.revents = 0; - - i = php_poll2(&p, 1, 300); - - retry = i > 0; - } - break; - - default: - php_error_docref(NULL, E_WARNING, "SSL write failed"); - return -1; - } - } while (retry); - } else { -#endif - sent = send(s, buf, size, 0); -#ifdef HAVE_FTP_SSL - } -#endif + sent = single_send(ftp, s, buf, size); if (sent == -1) { return -1; } diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 3e3b359666d6a..2013e8ef4280b 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1593,7 +1593,7 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e int i, pti; int lx = 0, ly = 0; int fx = 0, fy = 0; - int startx, starty, endx, endy; + int startx = -1, starty = -1, endx = -1, endy = -1; if ((s % 360) == (e % 360)) { s = 0; e = 360; @@ -1990,7 +1990,8 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc) if (x>x2+1) { FILL_PUSH(y, x2+1, x-1, -dy); } -skip: for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++); +skip: + for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++); l = x; } while (x<=x2); @@ -2062,7 +2063,8 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) if (x>x2+1) { FILL_PUSH(y, x2+1, x-1, -dy); } -skip: for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++); +skip: + for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++); l = x; } while (x<=x2); } diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index f78e7f3fb0fce..ee987e8199f2a 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -467,7 +467,7 @@ LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, i if (sd->sp > sd->stack) return *--sd->sp; - while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { + while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { if (code == sd->clear_code) { for (i = 0; i < sd->clear_code; ++i) { sd->table[0][i] = 0; diff --git a/ext/gd/libgd/gd_wbmp.c b/ext/gd/libgd/gd_wbmp.c index fd9edad2cafa8..13dc9e38d6186 100644 --- a/ext/gd/libgd/gd_wbmp.c +++ b/ext/gd/libgd/gd_wbmp.c @@ -127,8 +127,11 @@ static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) gd_error("Could not save WBMP"); return 1; } + /* des submitted this bugfix: gdFree the memory. */ freewbmp(wbmp); + + return 0; } /* gdImageCreateFromWBMPCtx diff --git a/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt b/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt new file mode 100644 index 0000000000000..09113bcda7904 --- /dev/null +++ b/ext/gd/tests/imagecolorclosesthwb_basic_001.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test imagecolorclosesthwb() basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) +int(0) +int(1) +int(0) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 0b55945f41276..862f23c29e667 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -828,13 +828,12 @@ static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg) /* {{{ */ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int check_b_zero) { mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result; - int use_ui = 0; gmp_temp_t temp_a, temp_b; FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) { - use_ui = 1; + gmpnum_b = NULL; temp_b.is_used = 0; } else { FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); @@ -842,7 +841,7 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval * if (check_b_zero) { int b_is_zero = 0; - if (use_ui) { + if (!gmpnum_b) { b_is_zero = (Z_LVAL_P(b_arg) == 0); } else { b_is_zero = !mpz_cmp_ui(gmpnum_b, 0); @@ -858,7 +857,7 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval * INIT_GMP_RETVAL(gmpnum_result); - if (use_ui) { + if (!gmpnum_b) { gmp_ui_op(gmpnum_result, gmpnum_a, (gmp_ulong) Z_LVAL_P(b_arg)); } else { gmp_op(gmpnum_result, gmpnum_a, gmpnum_b); @@ -875,15 +874,13 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval * static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int check_b_zero) { mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result1, gmpnum_result2; - int use_ui = 0; gmp_temp_t temp_a, temp_b; zval result1, result2; FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) { - /* use _ui function */ - use_ui = 1; + gmpnum_b = NULL; temp_b.is_used = 0; } else { FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); @@ -891,7 +888,7 @@ static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval if (check_b_zero) { int b_is_zero = 0; - if (use_ui) { + if (!gmpnum_b) { b_is_zero = (Z_LVAL_P(b_arg) == 0); } else { b_is_zero = !mpz_cmp_ui(gmpnum_b, 0); @@ -912,7 +909,7 @@ static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval add_next_index_zval(return_value, &result1); add_next_index_zval(return_value, &result2); - if (use_ui) { + if (!gmpnum_b) { gmp_ui_op(gmpnum_result1, gmpnum_result2, gmpnum_a, (gmp_ulong) Z_LVAL_P(b_arg)); } else { gmp_op(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b); diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 0e85a5c3b3663..7e8852cc47019 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -55,7 +55,7 @@ #include "ext/standard/quot_print.h" #define _php_iconv_memequal(a, b, c) \ - ((c) == sizeof(zend_ulong) ? *((zend_ulong *)(a)) == *((zend_ulong *)(b)) : ((c) == sizeof(unsigned int) ? *((unsigned int *)(a)) == *((unsigned int *)(b)) : memcmp(a, b, c) == 0)) + (memcmp(a, b, c) == 0) /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_strlen, 0, 0, 1) @@ -338,37 +338,25 @@ PHP_MINFO_FUNCTION(miconv) } /* }}} */ -static char *get_internal_encoding(void) { +static const char *get_internal_encoding(void) { if (ICONVG(internal_encoding) && ICONVG(internal_encoding)[0]) { return ICONVG(internal_encoding); - } else if (PG(internal_encoding) && PG(internal_encoding)[0]) { - return PG(internal_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); } - return ""; + return php_get_internal_encoding(); } -static char *get_input_encoding(void) { +static const char *get_input_encoding(void) { if (ICONVG(input_encoding) && ICONVG(input_encoding)[0]) { return ICONVG(input_encoding); - } else if (PG(input_encoding) && PG(input_encoding)[0]) { - return PG(input_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); } - return ""; + return php_get_input_encoding(); } -static char *get_output_encoding(void) { +static const char *get_output_encoding(void) { if (ICONVG(output_encoding) && ICONVG(output_encoding)[0]) { return ICONVG(output_encoding); - } else if (PG(output_encoding) && PG(output_encoding)[0]) { - return PG(output_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); } - return ""; + return php_get_output_encoding(); } @@ -2064,7 +2052,7 @@ static void _php_iconv_show_error(php_iconv_err_t err, const char *out_charset, Returns the character count of str */ PHP_FUNCTION(iconv_strlen) { - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0; zend_string *str; @@ -2096,7 +2084,7 @@ PHP_FUNCTION(iconv_strlen) Returns specified part of a string */ PHP_FUNCTION(iconv_substr) { - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0; zend_string *str; zend_long offset, length = 0; @@ -2135,7 +2123,7 @@ PHP_FUNCTION(iconv_substr) Finds position of first occurrence of needle within part of haystack beginning with offset */ PHP_FUNCTION(iconv_strpos) { - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0, haystk_len; zend_string *haystk; zend_string *ndl; @@ -2190,7 +2178,7 @@ PHP_FUNCTION(iconv_strpos) Finds position of last occurrence of needle within part of haystack beginning with offset */ PHP_FUNCTION(iconv_strrpos) { - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0; zend_string *haystk; zend_string *ndl; @@ -2331,7 +2319,7 @@ PHP_FUNCTION(iconv_mime_encode) PHP_FUNCTION(iconv_mime_decode) { zend_string *encoded_str; - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0; zend_long mode = 0; @@ -2371,7 +2359,7 @@ PHP_FUNCTION(iconv_mime_decode) PHP_FUNCTION(iconv_mime_decode_headers) { zend_string *encoded_str; - char *charset = get_internal_encoding(); + const char *charset = get_internal_encoding(); size_t charset_len = 0; zend_long mode = 0; char *enc_str_tmp; diff --git a/ext/iconv/tests/iconv004.phpt b/ext/iconv/tests/iconv004.phpt index 6c8606536d74a..cf8c65bd3a411 100644 --- a/ext/iconv/tests/iconv004.phpt +++ b/ext/iconv/tests/iconv004.phpt @@ -3,9 +3,9 @@ iconv_mime_encode() sanity cheeck. --SKIPIF-- --INI-- -iconv.input_encoding = ISO-8859-1 -iconv.internal_encoding = ISO-8859-1 -iconv.output_encoding = ISO-8859-1 +input_encoding = ISO-8859-1 +internal_encoding = ISO-8859-1 +output_encoding = ISO-8859-1 --FILE-- --INI-- error_reporting=E_ALL & ~E_DEPRECATED -iconv.input_encoding=ISO-8859-1 +input_encoding=ISO-8859-1 iconv.internal_encoding=ISO-8859-1 iconv.output_encoding=ISO-8859-1 --FILE-- diff --git a/ext/iconv/tests/iconv_substr_basic.phpt b/ext/iconv/tests/iconv_substr_basic.phpt index 582529d54d185..58b98407e6a75 100644 --- a/ext/iconv/tests/iconv_substr_basic.phpt +++ b/ext/iconv/tests/iconv_substr_basic.phpt @@ -6,9 +6,9 @@ extension_loaded('iconv') or die('skip'); function_exists('iconv_substr') or die("skip iconv_substr() is not available in this build"); ?> --INI-- -iconv.input_encoding=ISO-8859-1 -iconv.internal_encoding=ISO-8859-1 -iconv.output_encoding=ISO-8859-1 +input_encoding=ISO-8859-1 +internal_encoding=ISO-8859-1 +output_encoding=ISO-8859-1 --FILE-- +--EXPECT-- +object(IntlDateFormatter)#1 (0) { +} diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index f191fb8345e7f..2245752b86a2e 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -260,7 +260,9 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, add_assoc_long(&value, "target", target); add_assoc_long(&value, "count", count); add_assoc_long(&value, "errcode", errcode); - add_assoc_stringl(&value, "context", context->bv_val, context->bv_len); + if ( context && (context->bv_len >= 0) ) { + add_assoc_stringl(&value, "context", context->bv_val, context->bv_len); + } add_assoc_zval(array, "value", &value); } else { add_assoc_null(array, "value"); diff --git a/ext/libxml/config0.m4 b/ext/libxml/config0.m4 index 28fd85dc3c97b..98d5134f36d93 100644 --- a/ext/libxml/config0.m4 +++ b/ext/libxml/config0.m4 @@ -1,20 +1,11 @@ dnl config.m4 for extension libxml -PHP_ARG_ENABLE([libxml], - [whether to enable LIBXML support], - [AS_HELP_STRING([--disable-libxml], - [Disable LIBXML support])], +PHP_ARG_WITH([libxml], + [whether to build with LIBXML support], + [AS_HELP_STRING([--without-libxml], + [Build without LIBXML support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([[--with-libxml-dir[=DIR]]], - [LIBXML: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_LIBXML" != "no"; then dnl This extension can not be build as shared @@ -24,7 +15,5 @@ if test "$PHP_LIBXML" != "no"; then AC_DEFINE(HAVE_LIBXML,1,[ ]) PHP_NEW_EXTENSION(libxml, [libxml.c], $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_INSTALL_HEADERS([ext/libxml/php_libxml.h]) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) fi diff --git a/ext/mbstring/libmbfl/config.h.in b/ext/mbstring/libmbfl/config.h.in index fba649b0c43cc..0dcad471d4cd1 100644 --- a/ext/mbstring/libmbfl/config.h.in +++ b/ext/mbstring/libmbfl/config.h.in @@ -42,30 +42,6 @@ */ #undef LT_OBJDIR -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Version number of package */ -#undef VERSION - /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c index f8ae8fc6f7cde..d68a6cc38d340 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c @@ -35,8 +35,6 @@ #include "mbfilter_euc_jp_2004.h" #include "mbfilter_sjis_2004.h" -#include "unicode_table_jis2004.h" - extern int mbfl_filt_ident_eucjp(int c, mbfl_identify_filter *filter); extern const unsigned char mblen_table_eucjp[]; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c index 9077d5708bfbd..b3c5f60f698e3 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c @@ -35,7 +35,6 @@ #include "mbfilter_iso2022jp_2004.h" #include "mbfilter_sjis_2004.h" -#include "unicode_table_jis2004.h" #include "unicode_table_jis.h" extern int mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c index dd37bbabba610..da25160b4d0d7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c @@ -39,8 +39,6 @@ extern const unsigned char mblen_table_sjis[]; -static int mbfl_filt_ident_sjis2004(int c, mbfl_identify_filter *filter); - extern int mbfl_filt_ident_sjis(int c, mbfl_identify_filter *filter); extern int mbfl_bisec_srch(int w, const unsigned short *tbl, int n); extern int mbfl_bisec_srch2(int w, const unsigned short tbl[], int n); diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index 2a6a9b23bb965..c57e2b6be1b95 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -58,11 +58,6 @@ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data) const mbfl_encoding *detected; php_mb_encoding_handler_info_t info; - if (arg != PARSE_STRING) { - char *value = MBSTRG(internal_encoding_name); - _php_mb_ini_mbstring_internal_encoding_set(value, value ? strlen(value): 0); - } - if (!MBSTRG(encoding_translation)) { php_default_treat_data(arg, str, destArray); return; diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index d8248aac5d7cb..69d5fa91017c1 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -63,7 +63,7 @@ #if ONIGURUMA_VERSION_INT < 60800 typedef void OnigMatchParam; #define onig_new_match_param() (NULL) -#define onig_initialize_match_param(x) +#define onig_initialize_match_param(x) (void)(x) #define onig_set_match_stack_limit_size_of_match_param(x, y) #define onig_free_match_param(x) #define onig_search_with_param(reg, str, end, start, range, region, option, mp) \ @@ -615,34 +615,6 @@ ZEND_TSRMLS_CACHE_DEFINE() ZEND_GET_MODULE(mbstring) #endif -static char *get_internal_encoding(void) { - if (PG(internal_encoding) && PG(internal_encoding)[0]) { - return PG(internal_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); - } - return ""; -} - -static char *get_input_encoding(void) { - if (PG(input_encoding) && PG(input_encoding)[0]) { - return PG(input_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); - } - return ""; -} - -static char *get_output_encoding(void) { - if (PG(output_encoding) && PG(output_encoding)[0]) { - return PG(output_encoding); - } else if (SG(default_charset)) { - return SG(default_charset); - } - return ""; -} - - /* {{{ allocators */ static void *_php_mb_allocators_malloc(size_t sz) { @@ -1289,77 +1261,70 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) } /* }}} */ -/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */ -static PHP_INI_MH(OnUpdate_mbstring_http_input) -{ +static int _php_mb_ini_mbstring_http_input_set(const char *new_value, size_t new_value_length) { const mbfl_encoding **list; size_t size; - - if (!new_value || !ZSTR_VAL(new_value)) { - if (MBSTRG(http_input_list)) { - pefree(MBSTRG(http_input_list), 1); - } - if (SUCCESS == php_mb_parse_encoding_list(get_input_encoding(), strlen(get_input_encoding())+1, &list, &size, 1)) { - MBSTRG(http_input_list) = list; - MBSTRG(http_input_list_size) = size; - return SUCCESS; - } - MBSTRG(http_input_list) = NULL; - MBSTRG(http_input_list_size) = 0; - return SUCCESS; - } - - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, 1)) { + if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) { return FAILURE; } - if (MBSTRG(http_input_list)) { pefree(MBSTRG(http_input_list), 1); } MBSTRG(http_input_list) = list; MBSTRG(http_input_list_size) = size; + return SUCCESS; +} +/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */ +static PHP_INI_MH(OnUpdate_mbstring_http_input) +{ if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) { php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_input is deprecated"); } - return SUCCESS; + if (!new_value || !ZSTR_VAL(new_value)) { + const char *encoding = php_get_input_encoding(); + MBSTRG(http_input_set) = 0; + _php_mb_ini_mbstring_http_input_set(encoding, strlen(encoding)); + return SUCCESS; + } + + MBSTRG(http_input_set) = 1; + return _php_mb_ini_mbstring_http_input_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); } /* }}} */ -/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */ -static PHP_INI_MH(OnUpdate_mbstring_http_output) -{ - const mbfl_encoding *encoding; - - if (new_value == NULL || ZSTR_LEN(new_value) == 0) { - encoding = mbfl_name2encoding(get_output_encoding()); - if (!encoding) { - MBSTRG(http_output_encoding) = &mbfl_encoding_pass; - MBSTRG(current_http_output_encoding) = &mbfl_encoding_pass; - return SUCCESS; - } - } else { - encoding = mbfl_name2encoding(ZSTR_VAL(new_value)); - if (!encoding) { - MBSTRG(http_output_encoding) = &mbfl_encoding_pass; - MBSTRG(current_http_output_encoding) = &mbfl_encoding_pass; - return FAILURE; - } +static int _php_mb_ini_mbstring_http_output_set(const char *new_value) { + const mbfl_encoding *encoding = mbfl_name2encoding(new_value); + if (!encoding) { + return FAILURE; } + MBSTRG(http_output_encoding) = encoding; MBSTRG(current_http_output_encoding) = encoding; + return SUCCESS; +} +/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */ +static PHP_INI_MH(OnUpdate_mbstring_http_output) +{ if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) { php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_output is deprecated"); } - return SUCCESS; + if (new_value == NULL || ZSTR_LEN(new_value) == 0) { + MBSTRG(http_output_set) = 0; + _php_mb_ini_mbstring_http_output_set(php_get_output_encoding()); + return SUCCESS; + } + + MBSTRG(http_output_set) = 1; + return _php_mb_ini_mbstring_http_output_set(ZSTR_VAL(new_value)); } /* }}} */ /* {{{ static _php_mb_ini_mbstring_internal_encoding_set */ -int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, size_t new_value_length) +static int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, size_t new_value_length) { const mbfl_encoding *encoding; @@ -1395,20 +1360,13 @@ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) return FAILURE; } - if (stage & (PHP_INI_STAGE_STARTUP | PHP_INI_STAGE_SHUTDOWN | PHP_INI_STAGE_RUNTIME)) { - if (new_value && ZSTR_LEN(new_value)) { - return _php_mb_ini_mbstring_internal_encoding_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); - } else { - return _php_mb_ini_mbstring_internal_encoding_set(get_internal_encoding(), strlen(get_internal_encoding())+1); - } + if (new_value && ZSTR_LEN(new_value)) { + MBSTRG(internal_encoding_set) = 1; + return _php_mb_ini_mbstring_internal_encoding_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); } else { - /* the corresponding mbstring globals needs to be set according to the - * ini value in the later stage because it never falls back to the - * default value if 1. no value for mbstring.internal_encoding is given, - * 2. mbstring.language directive is processed in per-dir or runtime - * context and 3. call to the handler for mbstring.language is done - * after mbstring.internal_encoding is handled. */ - return SUCCESS; + const char *encoding = php_get_internal_encoding(); + MBSTRG(internal_encoding_set) = 0; + return _php_mb_ini_mbstring_internal_encoding_set(encoding, strlen(encoding)); } } /* }}} */ @@ -1532,6 +1490,24 @@ PHP_INI_BEGIN() PHP_INI_END() /* }}} */ +static void mbstring_internal_encoding_changed_hook() { + /* One of the internal_encoding / input_encoding / output_encoding ini settings changed. */ + if (!MBSTRG(internal_encoding_set)) { + const char *encoding = php_get_internal_encoding(); + _php_mb_ini_mbstring_internal_encoding_set(encoding, strlen(encoding)); + } + + if (!MBSTRG(http_output_set)) { + const char *encoding = php_get_output_encoding(); + _php_mb_ini_mbstring_http_output_set(encoding); + } + + if (!MBSTRG(http_input_set)) { + const char *encoding = php_get_input_encoding(); + _php_mb_ini_mbstring_http_input_set(encoding, strlen(encoding)); + } +} + /* {{{ module global initialize handler */ static PHP_GINIT_FUNCTION(mbstring) { @@ -1572,6 +1548,9 @@ ZEND_TSRMLS_CACHE_UPDATE(); #endif mbstring_globals->last_used_encoding_name = NULL; mbstring_globals->last_used_encoding = NULL; + mbstring_globals->internal_encoding_set = 0; + mbstring_globals->http_output_set = 0; + mbstring_globals->http_input_set = 0; } /* }}} */ @@ -1603,6 +1582,11 @@ ZEND_TSRMLS_CACHE_UPDATE(); REGISTER_INI_ENTRIES(); + /* We assume that we're the only user of the hook. */ + ZEND_ASSERT(php_internal_encoding_changed == NULL); + php_internal_encoding_changed = mbstring_internal_encoding_changed_hook; + mbstring_internal_encoding_changed_hook(); + /* This is a global handler. Should not be set in a per-request handler. */ sapi_register_treat_data(mbstr_treat_data); @@ -1706,6 +1690,8 @@ PHP_MSHUTDOWN_FUNCTION(mbstring) PHP_MSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU); #endif + php_internal_encoding_changed = NULL; + return SUCCESS; } /* }}} */ @@ -1763,6 +1749,10 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) MBSTRG(last_used_encoding_name) = NULL; } + MBSTRG(internal_encoding_set) = 0; + MBSTRG(http_output_set) = 0; + MBSTRG(http_input_set) = 0; + #if HAVE_MBREGEX PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU); #endif @@ -1846,6 +1836,7 @@ PHP_FUNCTION(mb_internal_encoding) RETURN_FALSE; } else { MBSTRG(current_internal_encoding) = encoding; + MBSTRG(internal_encoding_set) = 1; RETURN_TRUE; } } @@ -1969,6 +1960,7 @@ PHP_FUNCTION(mb_http_output) php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", name); RETURN_FALSE; } else { + MBSTRG(http_output_set) = 1; MBSTRG(current_http_output_encoding) = encoding; RETURN_TRUE; } @@ -3076,7 +3068,7 @@ PHP_FUNCTION(mb_strimwidth) { char *str, *trimmarker = NULL; zend_string *encoding = NULL; - zend_long from, width, swidth; + zend_long from, width, swidth = 0; size_t str_len, trimmarker_len; mbfl_string string, result, marker, *ret; @@ -3249,7 +3241,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons { HashTable *output, *chash; zend_long idx; - zend_string *key, *key_tmp; + zend_string *key; zval *entry, entry_tmp; size_t ckey_len, cval_len; char *ckey, *cval; @@ -3269,7 +3261,8 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons /* convert key */ if (key) { ckey = php_mb_convert_encoding(ZSTR_VAL(key), ZSTR_LEN(key), _to_encoding, _from_encodings, &ckey_len); - key_tmp = zend_string_init(ckey, ckey_len, 0); + key = zend_string_init(ckey, ckey_len, 0); + efree(ckey); } /* convert value */ ZEND_ASSERT(entry); @@ -3297,13 +3290,14 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons case IS_OBJECT: default: if (key) { - efree(key_tmp); + zend_string_release(key); } php_error_docref(NULL, E_WARNING, "Object is not supported"); continue; } if (key) { - zend_hash_add(output, key_tmp, &entry_tmp); + zend_hash_add(output, key, &entry_tmp); + zend_string_release(key); } else { zend_hash_index_add(output, idx, &entry_tmp); } diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index cd882c1c03cc7..5a713e549693c 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -130,9 +130,6 @@ MBSTRING_API size_t php_mb_mbchar_bytes(const char *s); MBSTRING_API size_t php_mb_stripos(int mode, const char *old_haystack, size_t old_haystack_len, const char *old_needle, size_t old_needle_len, zend_long offset, zend_string *from_encoding); MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const char *enc); -/* internal use only */ -int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, size_t new_value_length); - ZEND_BEGIN_MODULE_GLOBALS(mbstring) char *internal_encoding_name; const mbfl_encoding *internal_encoding; @@ -169,6 +166,10 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring) #endif zend_string *last_used_encoding_name; const mbfl_encoding *last_used_encoding; + /* Whether an explicit internal_encoding / http_output / http_input encoding was set. */ + zend_bool internal_encoding_set; + zend_bool http_output_set; + zend_bool http_input_set; ZEND_END_MODULE_GLOBALS(mbstring) #define MB_OVERLOAD_MAIL 1 diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 12ee4cf47c08b..83cd25d89da59 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -37,7 +37,7 @@ #if ONIGURUMA_VERSION_INT < 60800 typedef void OnigMatchParam; #define onig_new_match_param() (NULL) -#define onig_initialize_match_param(x) +#define onig_initialize_match_param(x) (void)(x) #define onig_set_match_stack_limit_size_of_match_param(x, y) #define onig_free_match_param(x) #define onig_search_with_param(reg, str, end, start, range, region, option, mp) \ diff --git a/ext/mbstring/php_unicode.c b/ext/mbstring/php_unicode.c index 69fdfc0706c69..664f760fc363c 100644 --- a/ext/mbstring/php_unicode.c +++ b/ext/mbstring/php_unicode.c @@ -371,9 +371,7 @@ static int convert_case_filter(int c, void *void_data) } break; } - default: - assert(0); - break; + EMPTY_SWITCH_DEFAULT_CASE() } for (i = 0; i < len; i++) { diff --git a/ext/mbstring/tests/bug45239.phpt b/ext/mbstring/tests/bug45239.phpt index 8d8ef4831ea8d..d67aedc4134de 100644 --- a/ext/mbstring/tests/bug45239.phpt +++ b/ext/mbstring/tests/bug45239.phpt @@ -2,8 +2,8 @@ Bug #45239 (encoding detector hangs with mbstring.strict_detection enabled) --INI-- mbstring.strict_detection=1 -mbstring.http_input=UTF-8 -mbstring.internal_encoding=UTF-8 +input_encoding=UTF-8 +internal_encoding=UTF-8 --SKIPIF-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- --INI-- mbstring.func_overload = 7 -mbstring.internal_encoding = utf-8 --FILE-- +--EXPECTF-- +string(10) "ISO-8859-1" +int(2) + +Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d +string(5) "UTF-8" +int(1) +string(5) "UTF-8" +int(1) + +Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d +string(10) "ISO-8859-2" +int(2) +string(5) "UTF-8" +int(1) +string(5) "UTF-8" +int(1) + +Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d +string(10) "ISO-8859-3" +int(2) diff --git a/ext/mbstring/tests/mb_convert_encoding_leak.phpt b/ext/mbstring/tests/mb_convert_encoding_leak.phpt new file mode 100644 index 0000000000000..4e626b089493a --- /dev/null +++ b/ext/mbstring/tests/mb_convert_encoding_leak.phpt @@ -0,0 +1,16 @@ +--TEST-- +mb_convert_encoding() shouldn't leak keys +--FILE-- + "bar"]; +mb_convert_encoding($array, 'UTF-8', 'UTF-8'); +var_dump($array); + +?> +--EXPECT-- +array(1) { + ["foox"]=> + string(3) "bar" +} diff --git a/ext/mbstring/tests/mb_internal_encoding_basic2.phpt b/ext/mbstring/tests/mb_internal_encoding_basic2.phpt index 8090b47be58f6..99b92027e9058 100644 --- a/ext/mbstring/tests/mb_internal_encoding_basic2.phpt +++ b/ext/mbstring/tests/mb_internal_encoding_basic2.phpt @@ -47,7 +47,7 @@ string(10) "ISO-8859-1" string(0) "" string(0) "" string(0) "" -string(5) "UTF-8" +string(10) "ISO-8859-1" bool(true) string(5) "UTF-8" Done diff --git a/ext/mbstring/tests/mb_output_handler_pattern-01.phpt b/ext/mbstring/tests/mb_output_handler_pattern-01.phpt index 62825b6efb988..d80b6daf5e232 100644 --- a/ext/mbstring/tests/mb_output_handler_pattern-01.phpt +++ b/ext/mbstring/tests/mb_output_handler_pattern-01.phpt @@ -2,8 +2,6 @@ mb_output_handler() and mbstring.http_output_conv_mimetypes (1) --SKIPIF-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- --INI-- -mbstring.internal_encoding=UTF-8 mbstring.http_output_conv_mimetypes=html --FILE-- --INI-- -mbstring.internal_encoding=UTF-8 mbstring.http_output_conv_mimetypes=html --FILE-- --INI-- -mbstring.internal_encoding=UTF-8 mbstring.http_output_conv_mimetypes=html --FILE-- --INI-- -mbstring.internal_encoding=UTF-8 mbstring.http_output_conv_mimetypes=html --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- --INI-- output_handler=mb_output_handler -mbstring.internal_encoding=Shift_JIS -mbstring.http_output=EUC-JP +internal_encoding=Shift_JIS +output_encoding=EUC-JP --FILE-- ---INI-- -mbstring.internal_encoding=UTF-8 --FILE-- --INI-- -mbstring.internal_encoding=ISO-8859-1 +internal_encoding=ISO-8859-1 --FILE-- --INI-- -error_reporting=E_ALL & ~E_DEPRECATED zend.multibyte=On zend.script_encoding=ISO-8859-1 -mbstring.internal_encoding=EUC-JP +internal_encoding=EUC-JP --FILE-- --INI-- -error_reporting=E_ALL & ~E_DEPRECATED zend.multibyte=On zend.script_encoding=cp1251 -mbstring.internal_encoding=UTF-8 +internal_encoding=UTF-8 --FILE-- payload_decoder_factory, COM_STMT_EXECUTE, payload.s, payload.l, FALSE, + ret = send_command(conn->payload_decoder_factory, COM_STMT_EXECUTE, + (const unsigned char *) payload.s, payload.l, FALSE, &conn->state, conn->error_info, conn->upsert_status, diff --git a/ext/opcache/Optimizer/escape_analysis.c b/ext/opcache/Optimizer/escape_analysis.c index e350cf734d3e2..1607c696f7af6 100644 --- a/ext/opcache/Optimizer/escape_analysis.c +++ b/ext/opcache/Optimizer/escape_analysis.c @@ -535,7 +535,6 @@ int zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, if (ssa_vars[root].escape_state == ESCAPE_STATE_GLOBAL_ESCAPE) { num_non_escaped--; if (num_non_escaped == 0) { - i = ssa_vars_count; changed = 0; } else { changed = 1; diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 95f5f43772a6c..a0390a944325f 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -24,6 +24,7 @@ * - perform compile-time evaluation of constant binary and unary operations * - convert CAST(IS_BOOL,x) into BOOL(x) * - pre-evaluate constant function calls + * - eliminate FETCH $GLOBALS followed by FETCH_DIM/UNSET_DIM/ISSET_ISEMPTY_DIM */ #include "php.h" @@ -514,6 +515,49 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) zend_optimizer_collect_constant(ctx, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline)); } break; +// case ZEND_FETCH_R: + case ZEND_FETCH_W: +// case ZEND_FETCH_RW: + case ZEND_FETCH_IS: +// case ZEND_FETCH_FUNC_ARG: + case ZEND_FETCH_UNSET: + /* convert FETCH $GLOBALS (global), FETCH_DIM $x into FETCH $x (global) */ + if ((opline->extended_value & ZEND_FETCH_GLOBAL) != 0 && + opline->op1_type == IS_CONST && + Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING && + zend_string_equals_literal(Z_STR(ZEND_OP1_LITERAL(opline)), "GLOBALS") && + ((opline + 1)->opcode == opline->opcode + 1 || + ((opline + 1)->opcode == ZEND_UNSET_DIM && + opline->opcode == ZEND_FETCH_UNSET) || + ((opline + 1)->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ && + opline->opcode == ZEND_FETCH_IS)) && + (opline + 1)->op1_type == opline->result_type && + (opline + 1)->op1.var == opline->result.var && + ((opline + 1)->op2_type != IS_CONST || + Z_TYPE(ZEND_OP2_LITERAL(opline + 1)) < IS_ARRAY)) { + + if ((opline + 1)->opcode == ZEND_UNSET_DIM) { + (opline + 1)->opcode = ZEND_UNSET_VAR; + (opline + 1)->extended_value = ZEND_FETCH_GLOBAL; + } else if ((opline + 1)->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ) { + (opline + 1)->opcode = ZEND_ISSET_ISEMPTY_VAR; + (opline + 1)->extended_value |= ZEND_FETCH_GLOBAL; + } else { + (opline + 1)->opcode = opline->opcode; + (opline + 1)->extended_value = ZEND_FETCH_GLOBAL; + } + (opline + 1)->op1_type = (opline + 1)->op2_type; + (opline + 1)->op1 = (opline + 1)->op2; + if ((opline + 1)->op1_type == IS_CONST && + Z_TYPE(ZEND_OP1_LITERAL(opline + 1)) != IS_STRING) { + + convert_to_string(&ZEND_OP1_LITERAL(opline + 1)); + zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline + 1))); + } + SET_UNUSED(opline->op2); + MAKE_NOP(opline); + } + break; case ZEND_RETURN: case ZEND_RETURN_BY_REF: diff --git a/ext/opcache/Optimizer/scdf.c b/ext/opcache/Optimizer/scdf.c index 96687e44f49fd..1c7cbc7e55e10 100644 --- a/ext/opcache/Optimizer/scdf.c +++ b/ext/opcache/Optimizer/scdf.c @@ -158,7 +158,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { /* Zero length blocks don't have a last instruction that would normally do this */ scdf_mark_edge_feasible(scdf, i, block->successors[0]); } else { - zend_op *opline; + zend_op *opline = NULL; int j, end = block->start + block->len; for (j = block->start; j < end; j++) { opline = &scdf->op_array->opcodes[j]; @@ -170,6 +170,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { if (block->successors_count == 1) { scdf_mark_edge_feasible(scdf, i, block->successors[0]); } else if (block->successors_count > 1) { + ZEND_ASSERT(opline && "Should have opline in non-empty block"); if (opline->opcode == ZEND_OP_DATA) { opline--; j--; diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index 3bc0650ab476b..01c907cfea611 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -1027,6 +1027,9 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons case ZEND_LIVE_ROPE: fprintf(stderr, "(rope)\n"); break; + case ZEND_LIVE_NEW: + fprintf(stderr, "(new)\n"); + break; } } } @@ -1083,6 +1086,9 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons case ZEND_LIVE_ROPE: fprintf(stderr, "(rope)\n"); break; + case ZEND_LIVE_NEW: + fprintf(stderr, "(new)\n"); + break; } } } diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index ef6e40e2f3e4f..d54b4bbb4bfd1 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -931,82 +931,6 @@ static const func_info_t func_infos[] = { F1("preg_grep", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ARRAY_OF_ANY), F0("preg_last_error", MAY_BE_NULL | MAY_BE_LONG), - /* ext/ereg */ - F0("ereg", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("ereg_replace", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("eregi", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("eregi_replace", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("split", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), - F1("spliti", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), - F1("sql_regcase", MAY_BE_NULL | MAY_BE_STRING), - - /* ext/mysql */ - F1("mysql_connect", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_pconnect", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F0("mysql_close", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_select_db", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_create_db", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_drop_db", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("mysql_query", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_RESOURCE), - F1("mysql_unbuffered_query", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_RESOURCE), - F1("mysql_db_query", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_RESOURCE), - F1("mysql_list_dbs", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_list_tables", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_list_fields", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_list_processes", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_error", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_errno", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F0("mysql_affected_rows", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F0("mysql_insert_id", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_num_rows", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F0("mysql_num_fields", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_fetch_row", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ANY), - F1("mysql_fetch_array", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY), - F1("mysql_fetch_assoc", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY), - F1("mysql_fetch_object", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT), - F0("mysql_data_seek", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("mysql_fetch_lengths", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_LONG), - F1("mysql_fetch_field", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT), - F0("mysql_field_seek", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_free_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("mysql_field_name", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_field_table", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_field_len", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_field_type", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_field_flags", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_escape_string", MAY_BE_NULL | MAY_BE_STRING), - F1("mysql_real_escape_string", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_stat", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_thread_id", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_client_encoding", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_ping", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("mysql_get_client_info", MAY_BE_NULL | MAY_BE_STRING), - F1("mysql_get_host_info", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_get_proto_info", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_get_server_info", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_info", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_set_charset", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("mysql", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_fieldname", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_fieldtable", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_fieldlen", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_fieldtype", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_fieldflags", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F0("mysql_selectdb", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_createdb", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_dropdb", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_freeresult", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F0("mysql_numfields", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F0("mysql_numrows", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_LONG), - F1("mysql_listdbs", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_listtables", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_listfields", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("mysql_db_name", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_dbname", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_tablename", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - F1("mysql_table_name", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), - /* ext/mysqli */ F1("mysqli_connect", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT), F0("mysqli_close", MAY_BE_NULL | MAY_BE_TRUE), diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index 9fe7793771ac1..337ac1e96de09 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -533,7 +533,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, int i, j; zend_op *opline, *end; int *tmp = NULL; - ALLOCA_FLAG(use_heap); + ALLOCA_FLAG(use_heap = 0); // FIXME: Can we optimize this copying out in some cases? if (blocks[n].next_child >= 0) { diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 0bdee2bfe03b0..44f91cab7f7f8 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -305,7 +305,9 @@ static inline int accel_restart_is_active(void) static inline int accel_activate_add(void) { #ifdef ZEND_WIN32 + SHM_UNPROTECT(); INCREMENT(mem_usage); + SHM_PROTECT(); #else struct flock mem_usage_lock; @@ -327,8 +329,10 @@ static inline void accel_deactivate_sub(void) { #ifdef ZEND_WIN32 if (ZCG(counted)) { + SHM_UNPROTECT(); DECREMENT(mem_usage); ZCG(counted) = 0; + SHM_PROTECT(); } #else struct flock mem_usage_unlock; @@ -573,10 +577,7 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int /* empty string */ zend_empty_string = new_interned_string(zend_empty_string); for (j = 0; j < 256; j++) { - char s[2]; - s[0] = j; - s[1] = 0; - zend_one_char_string[j] = new_interned_string(zend_string_init(s, 1, 0)); + zend_one_char_string[j] = new_interned_string(ZSTR_CHAR(j)); } for (j = 0; j < ZEND_STR_LAST_KNOWN; j++) { zend_known_strings[j] = new_interned_string(zend_known_strings[j]); diff --git a/ext/opcache/tests/bug68644.phpt b/ext/opcache/tests/bug68644.phpt index b82615ac4abb8..1a967facafb0e 100644 --- a/ext/opcache/tests/bug68644.phpt +++ b/ext/opcache/tests/bug68644.phpt @@ -4,7 +4,6 @@ Bug #68644 strlen incorrect : mbstring + func_overload=2 + UTF-8 + Opcache opcache.enable=1 opcache.enable_cli=1 mbstring.func_overload=2 -mbstring.internal_encoding=UTF-8 --SKIPIF-- --FILE-- diff --git a/ext/opcache/tests/opt/dce_006.phpt b/ext/opcache/tests/opt/dce_006.phpt index b53a73e9905c2..c84805247a2a1 100644 --- a/ext/opcache/tests/opt/dce_006.phpt +++ b/ext/opcache/tests/opt/dce_006.phpt @@ -33,6 +33,8 @@ L3 (6): CV1($a) = QM_ASSIGN V2 L4 (7): ASSIGN_OBJ CV1($a) string("foo") L5 (7): OP_DATA CV0($x) L6 (8): RETURN null +LIVE RANGES: + 2: L2 - L3 (new) A::__destruct: ; (lines=1, args=0, vars=0, tmps=0) ; (after optimizer) diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index 782b734c5bf51..9cd48ed26aa38 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -861,7 +861,21 @@ static char *zend_file_cache_get_bin_file_path(zend_string *script_path) filename[len] = '\\'; memcpy(filename + len + 1, ZCG(system_id), 32); - if (ZSTR_LEN(script_path) >= 2 && ':' == ZSTR_VAL(script_path)[1]) { + + if (ZSTR_LEN(script_path) >= 7 && ':' == ZSTR_VAL(script_path)[4] && '/' == ZSTR_VAL(script_path)[5] && '/' == ZSTR_VAL(script_path)[6]) { + /* phar:// or file:// */ + *(filename + len + 33) = '\\'; + memcpy(filename + len + 34, ZSTR_VAL(script_path), 4); + if (ZSTR_LEN(script_path) - 7 >= 2 && ':' == ZSTR_VAL(script_path)[8]) { + *(filename + len + 38) = '\\'; + *(filename + len + 39) = ZSTR_VAL(script_path)[7]; + memcpy(filename + len + 40, ZSTR_VAL(script_path) + 9, ZSTR_LEN(script_path) - 9); + memcpy(filename + len + 40 + ZSTR_LEN(script_path) - 9, SUFFIX, sizeof(SUFFIX)); + } else { + memcpy(filename + len + 38, ZSTR_VAL(script_path) + 7, ZSTR_LEN(script_path) - 7); + memcpy(filename + len + 38 + ZSTR_LEN(script_path) - 7, SUFFIX, sizeof(SUFFIX)); + } + } else if (ZSTR_LEN(script_path) >= 2 && ':' == ZSTR_VAL(script_path)[1]) { /* local fs */ *(filename + len + 33) = '\\'; *(filename + len + 34) = ZSTR_VAL(script_path)[0]; diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 177cbcc46fffe..e4e44c35be02a 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -594,6 +594,25 @@ void zend_accel_shared_protect(int mode) for (i = 0; i < ZSMMG(shared_segments_count); i++) { mprotect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->size, mode); } +#elif defined(ZEND_WIN32) + int i; + + if (!smm_shared_globals) { + return; + } + + if (mode) { + mode = PAGE_READONLY; + } else { + mode = PAGE_READWRITE; + } + + for (i = 0; i < ZSMMG(shared_segments_count); i++) { + DWORD oldProtect; + if (!VirtualProtect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->size, mode, &oldProtect)) { + zend_accel_error(ACCEL_LOG_ERROR, "Failed to protect memory"); + } + } #endif } diff --git a/ext/openssl/config0.m4 b/ext/openssl/config0.m4 index df90e05ba3aa4..b77bd5508b737 100644 --- a/ext/openssl/config0.m4 +++ b/ext/openssl/config0.m4 @@ -7,7 +7,7 @@ PHP_ARG_WITH([openssl], PHP_ARG_WITH([kerberos], [for Kerberos support], - [AS_HELP_STRING([[--with-kerberos[=DIR]]], + [AS_HELP_STRING([--with-kerberos], [OPENSSL: Include Kerberos support])], [no], [no]) @@ -24,7 +24,10 @@ if test "$PHP_OPENSSL" != "no"; then PHP_SUBST(OPENSSL_SHARED_LIBADD) if test "$PHP_KERBEROS" != "no"; then - PHP_SETUP_KERBEROS(OPENSSL_SHARED_LIBADD) + PKG_CHECK_MODULES([KERBEROS], [krb5-gssapi krb5]) + + PHP_EVAL_INCLINE($KERBEROS_CFLAGS) + PHP_EVAL_LIBLINE($KERBEROS_LIBS, OPENSSL_SHARED_LIBADD) fi AC_CHECK_FUNCS([RAND_egd]) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 787058f8dacbd..9ada33a3568b0 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1873,7 +1873,7 @@ static int php_openssl_enable_crypto(php_stream *stream, { int n; int retry = 1; - int cert_captured; + int cert_captured = 0; X509 *peer_cert; if (cparam->inputs.activate && !sslsock->ssl_active) { diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 2ae174b479308..c15f785a4ebb0 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -25,35 +25,37 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then AC_DEFINE(HAVE_PCRE, 1, [ ]) if test "$PHP_PCRE_JIT" != "no"; then - AC_MSG_CHECKING([for JIT support in PCRE2]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include - #include - int main(void) { - uint32_t have_jit; - pcre2_config_8(PCRE2_CONFIG_JIT, &have_jit); - return !have_jit; - } - ]])], [ - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_PCRE_JIT_SUPPORT, 1, []) - ], - [ - AC_MSG_RESULT([no]) - ], - [ - AC_CANONICAL_HOST - case $host_cpu in - arm*|i[34567]86|x86_64|mips*|powerpc*|sparc) - AC_MSG_RESULT([yes]) + AC_CACHE_CHECK([for JIT support in PCRE2], ac_cv_have_pcre2_jit, [ + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include + #include + int main(void) { + uint32_t have_jit; + pcre2_config_8(PCRE2_CONFIG_JIT, &have_jit); + return !have_jit; + } + ]])], [ + ac_cv_have_pcre2_jit=yes + ], + [ + ac_cv_have_pcre2_jit=no + ], + [ + AC_CANONICAL_HOST + case $host_cpu in + arm*|i[34567]86|x86_64|mips*|powerpc*|sparc) + ac_cv_have_pcre2_jit=yes + ;; + *) + ac_cv_have_pcre2_jit=no + ;; + esac + ]) + ]) + if test $ac_cv_have_pcre2_jit = yes; then AC_DEFINE(HAVE_PCRE_JIT_SUPPORT, 1, []) - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac - ]) + fi fi PHP_NEW_EXTENSION(pcre, php_pcre.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) diff --git a/ext/pcre/pcre2lib/config.h b/ext/pcre/pcre2lib/config.h index 439c895e4d509..78648977431f8 100644 --- a/ext/pcre/pcre2lib/config.h +++ b/ext/pcre/pcre2lib/config.h @@ -7,11 +7,6 @@ # include #endif -#undef PACKAGE_NAME -#undef PACKAGE_VERSION -#undef PACKAGE_TARNAME -#undef PACKAGE_STRING - #define SUPPORT_UNICODE 1 #define SUPPORT_PCRE2_8 1 diff --git a/ext/pcre/upgrade-pcre.php b/ext/pcre/upgrade-pcre.php index 3b642dfacc19d..831989253fc7f 100755 --- a/ext/pcre/upgrade-pcre.php +++ b/ext/pcre/upgrade-pcre.php @@ -109,11 +109,6 @@ function recurse($path) # include #endif -#undef PACKAGE_NAME -#undef PACKAGE_VERSION -#undef PACKAGE_TARNAME -#undef PACKAGE_STRING - #define SUPPORT_UCP #define SUPPORT_UTF8 diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 6e0f22cd6e683..25dd33bfdf811 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -819,7 +819,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_ { int flags, idx, old_arg_count = 0; zend_class_entry *ce = NULL, *old_ce = NULL; - zval grp_val, *pgrp, retval, old_ctor_args; + zval grp_val, *pgrp, retval, old_ctor_args = {0}; int colno; if (how == PDO_FETCH_USE_DEFAULT) { @@ -1370,7 +1370,7 @@ static PHP_METHOD(PDOStatement, fetchAll) { zend_long how = PDO_FETCH_USE_DEFAULT; zval data, *return_all; - zval *arg2; + zval *arg2 = NULL; zend_class_entry *old_ce; zval old_ctor_args, *ctor_args = NULL; int error = 0, flags, old_arg_count; diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index a27c1e85e74b2..8d60fe420b0b0 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -29,11 +29,6 @@ #include "php_pdo_pgsql_int.h" #ifdef HAVE_PG_CONFIG_H -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION #include #endif diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index e61e82c642527..e8b748a36f198 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -31,12 +31,6 @@ #include "pdo/php_pdo_driver.h" #include "pdo/php_pdo_error.h" #include "ext/standard/file.h" - -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION #include "pg_config.h" /* needed for PG_VERSION */ #include "php_pdo_pgsql.h" #include "php_pdo_pgsql_int.h" diff --git a/ext/pdo_pgsql/tests/bug_33876.phpt b/ext/pdo_pgsql/tests/bug_33876.phpt index bce84fa9bf0ca..dc213f6abb90c 100644 --- a/ext/pdo_pgsql/tests/bug_33876.phpt +++ b/ext/pdo_pgsql/tests/bug_33876.phpt @@ -88,7 +88,7 @@ if (!$res->execute(array(false))) { } else { print_r($res->fetchAll(PDO::FETCH_ASSOC)); } ---EXPECT-- +--EXPECTF-- Array ( [0] => Array @@ -117,7 +117,7 @@ Array ( [0] => 22P02 [1] => 7 - [2] => ERROR: invalid input syntax for type boolean: "" + [2] => %s: %sboolean%s ) EMUL Array @@ -148,5 +148,5 @@ Array ( [0] => 22P02 [1] => 7 - [2] => ERROR: invalid input syntax for type boolean: "" + [2] => %s: %sboolean%s ) diff --git a/ext/pdo_pgsql/tests/copy_from.phpt b/ext/pdo_pgsql/tests/copy_from.phpt index 7491e1836b35a..55a9df72aa4f9 100644 --- a/ext/pdo_pgsql/tests/copy_from.phpt +++ b/ext/pdo_pgsql/tests/copy_from.phpt @@ -259,7 +259,7 @@ array(6) { NULL } Testing pgsqlCopyFromArray() with error -Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %s "test_error" %s +Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyFromFile() with default parameters bool(true) array(6) { @@ -393,6 +393,6 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with error -Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %s "test_error" %s +Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyFromFile() with non existing file Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file diff --git a/ext/pdo_pgsql/tests/copy_to.phpt b/ext/pdo_pgsql/tests/copy_to.phpt index c790fa5729c60..3df882c93cb64 100644 --- a/ext/pdo_pgsql/tests/copy_to.phpt +++ b/ext/pdo_pgsql/tests/copy_to.phpt @@ -116,7 +116,7 @@ array(3) { " } Testing pgsqlCopyToArray() with error -Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %s "test_error" %s +Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyToFile() with default parameters bool(true) 0 test insert 0 \N @@ -133,6 +133,6 @@ bool(true) 1;NULL 2;NULL Testing pgsqlCopyToFile() with error -Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %s "test_error" %s +Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyToFile() to unwritable file Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file for writing diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 03669de0884ca..1be592a319ab5 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -38,12 +38,6 @@ #ifdef PHP_WIN32 # include "win32/time.h" #endif - -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION #include "php_pgsql.h" #include "php_globals.h" #include "zend_exceptions.h" @@ -88,7 +82,7 @@ #define PQ_SETNONBLOCKING(pg_link, flag) 0 #endif -#define CHECK_DEFAULT_LINK(x) if ((x) == NULL) { php_error_docref(NULL, E_WARNING, "No PostgreSQL link opened yet"); } +#define CHECK_DEFAULT_LINK(x) if ((x) == NULL) { php_error_docref(NULL, E_WARNING, "No PostgreSQL link opened yet"); RETURN_FALSE; } #define FETCH_DEFAULT_LINK() PGG(default_link) #ifndef HAVE_PQFREEMEM @@ -936,12 +930,20 @@ static void _close_pgsql_link(zend_resource *rsrc) { PGconn *link = (PGconn *)rsrc->ptr; PGresult *res; + zval *hash; while ((res = PQgetResult(link))) { PQclear(res); } PQfinish(link); PGG(num_links)--; + + /* Remove connection hash for this link */ + hash = zend_hash_index_find(&PGG(hashes), (uintptr_t) link); + if (hash) { + zend_hash_index_del(&PGG(hashes), (uintptr_t) link); + zend_hash_del(&EG(regular_list), Z_STR_P(hash)); + } } /* }}} */ @@ -1095,6 +1097,7 @@ static PHP_GINIT_FUNCTION(pgsql) memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initialize notice message hash at MINIT only */ zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&pgsql_globals->hashes, 0, NULL, ZVAL_PTR_DTOR, 1, 0); } /* }}} */ @@ -1229,6 +1232,7 @@ PHP_MSHUTDOWN_FUNCTION(pgsql) { UNREGISTER_INI_ENTRIES(); zend_hash_destroy(&PGG(notices)); + zend_hash_destroy(&PGG(hashes)); return SUCCESS; } @@ -1250,6 +1254,7 @@ PHP_RSHUTDOWN_FUNCTION(pgsql) { /* clean up notice messages */ zend_hash_clean(&PGG(notices)); + zend_hash_clean(&PGG(hashes)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions); return SUCCESS; @@ -1440,14 +1445,11 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } link = (zend_resource *)index_ptr->ptr; - if (link->ptr && (link->type == le_link || link->type == le_plink)) { - php_pgsql_set_default_link(link); - GC_ADDREF(link); - RETVAL_RES(link); - goto cleanup; - } else { - zend_hash_del(&EG(regular_list), str.s); - } + ZEND_ASSERT(link->ptr && (link->type == le_link || link->type == le_plink)); + php_pgsql_set_default_link(link); + GC_ADDREF(link); + RETVAL_RES(link); + goto cleanup; } if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) { php_error_docref(NULL, E_WARNING, "Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links)); @@ -1491,6 +1493,16 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) new_index_ptr.ptr = (void *) Z_RES_P(return_value); new_index_ptr.type = le_index_ptr; zend_hash_update_mem(&EG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zend_resource)); + + /* Keep track of link => hash mapping, so we can remove the hash entry from regular_list + * when the connection is closed. This uses the address of the connection rather than the + * zend_resource, because the resource destructor is passed a stack copy of the resource + * structure. */ + { + zval tmp; + ZVAL_STR_COPY(&tmp, str.s); + zend_hash_index_update(&PGG(hashes), (uintptr_t) pgsql, &tmp); + } PGG(num_links)++; } /* set notice processor */ @@ -1566,13 +1578,15 @@ PHP_FUNCTION(pg_close) return; } - if (pgsql_link) { - link = Z_RES_P(pgsql_link); - } else { - link = FETCH_DEFAULT_LINK(); + if (!pgsql_link) { + link = PGG(default_link); CHECK_DEFAULT_LINK(link); + zend_list_delete(link); + PGG(default_link) = NULL; + RETURN_TRUE; } + link = Z_RES_P(pgsql_link); if (zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink) == NULL) { RETURN_FALSE; } @@ -6550,38 +6564,32 @@ static int do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link, static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */ { - char *table_copy, *escaped, *tmp; - const char *token; - size_t len; + size_t table_len = strlen(table); - /* schame.table should be "schame"."table" */ - table_copy = estrdup(table); - token = php_strtok_r(table_copy, ".", &tmp); - if (token == NULL) { - token = table; - } - len = strlen(token); - if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) { - smart_str_appendl(querystr, token, len); + /* schema.table should be "schema"."table" */ + const char *dot = memchr(table, '.', table_len); + size_t len = dot ? dot - table : table_len; + if (_php_pgsql_detect_identifier_escape(table, len) == SUCCESS) { + smart_str_appendl(querystr, table, len); } else { - escaped = PGSQLescapeIdentifier(pg_link, token, len); + char *escaped = PGSQLescapeIdentifier(pg_link, table, len); smart_str_appends(querystr, escaped); PGSQLfree(escaped); } - if (tmp && *tmp) { - len = strlen(tmp); + if (dot) { + const char *after_dot = dot + 1; + len = table_len - len - 1; /* "schema"."table" format */ - if (_php_pgsql_detect_identifier_escape(tmp, len) == SUCCESS) { + if (_php_pgsql_detect_identifier_escape(after_dot, len) == SUCCESS) { smart_str_appendc(querystr, '.'); - smart_str_appendl(querystr, tmp, len); + smart_str_appendl(querystr, after_dot, len); } else { - escaped = PGSQLescapeIdentifier(pg_link, tmp, len); + char *escaped = PGSQLescapeIdentifier(pg_link, after_dot, len); smart_str_appendc(querystr, '.'); smart_str_appends(querystr, escaped); PGSQLfree(escaped); } } - efree(table_copy); } /* }}} */ diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 71d6bd3de2575..0294ea10a9808 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -34,9 +34,8 @@ extern zend_module_entry pgsql_module_entry; #undef SOCKET_SIZE_TYPE #include +#include #ifdef PHP_WIN32 -#define INV_WRITE 0x00020000 -#define INV_READ 0x00040000 #undef PHP_PGSQL_API #ifdef PGSQL_EXPORTS #define PHP_PGSQL_API __declspec(dllexport) @@ -44,7 +43,6 @@ extern zend_module_entry pgsql_module_entry; #define PHP_PGSQL_API __declspec(dllimport) #endif #else -#include # if defined(__GNUC__) && __GNUC__ >= 4 # define PHP_PGSQL_API __attribute__ ((visibility("default"))) # else @@ -317,6 +315,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) int ignore_notices,log_notices; HashTable notices; /* notice message for each connection */ zend_resource *default_link; /* default link when connection is omitted */ + HashTable hashes; /* hashes for each connection */ ZEND_END_MODULE_GLOBALS(pgsql) ZEND_EXTERN_MODULE_GLOBALS(pgsql) diff --git a/ext/pgsql/tests/29nb_async_connect.phpt b/ext/pgsql/tests/29nb_async_connect.phpt index fc3868a26db76..a9b17ebc3a195 100644 --- a/ext/pgsql/tests/29nb_async_connect.phpt +++ b/ext/pgsql/tests/29nb_async_connect.phpt @@ -23,18 +23,20 @@ if (!$db = pg_connect($conn_str, PGSQL_CONNECT_ASYNC)) { while (TRUE) { switch ($status = pg_connect_poll($db)) { case PGSQL_POLLING_READING: - if (nb_is_readable($db_socket)) { break 2; } + nb_is_readable($db_socket); break; case PGSQL_POLLING_WRITING: - if (nb_is_writable($db_socket)) { break 2; } + nb_is_writable($db_socket); break; case PGSQL_POLLING_FAILED: die("async connection failed"); case PGSQL_POLLING_OK: break 2; + default: + die("unknown poll status"); } } -assert(pg_connection_status($db) === PGSQL_CONNECTION_MADE); +assert(pg_connection_status($db) === PGSQL_CONNECTION_OK); echo "OK"; pg_close($db); diff --git a/ext/pgsql/tests/close_default_link.phpt b/ext/pgsql/tests/close_default_link.phpt new file mode 100644 index 0000000000000..c73aa5460bb6d --- /dev/null +++ b/ext/pgsql/tests/close_default_link.phpt @@ -0,0 +1,15 @@ +--TEST-- +pg_close() default link after connection variable has been dropped +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/pgsql/tests/connect_after_close.phpt b/ext/pgsql/tests/connect_after_close.phpt new file mode 100644 index 0000000000000..65f954570b08e --- /dev/null +++ b/ext/pgsql/tests/connect_after_close.phpt @@ -0,0 +1,19 @@ +--TEST-- +Reopen connection after it was closed +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/phar/tests/024-opcache-win32.phpt b/ext/phar/tests/024-opcache-win32.phpt new file mode 100644 index 0000000000000..81eedd9668ef4 --- /dev/null +++ b/ext/phar/tests/024-opcache-win32.phpt @@ -0,0 +1,61 @@ +--TEST-- +Phar: phar:// include with Opcache +--SKIPIF-- + + + + +--INI-- +phar.require_hash=0 +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache={PWD}/024-file_cache +opcache.memory_consumption=64 +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=4000 +opcache.jit_buffer_size=6M +opcache.revalidate_freq=60 +opcache.fast_shutdown=1 +--FILE-- +"; + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; + +include 'files/phar_test.inc'; + +include $pname . '/a.php'; +include $pname . '/b.php'; +include $pname . '/b/c.php'; + +$cache_dir = ini_get("opcache.file_cache"); +if (is_dir($cache_dir)) { + $it = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($cache_dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($it as $fi) { + $fn = ($fi->isDir() ? 'rmdir' : 'unlink'); + $fn($fi->getRealPath()); + } + + rmdir($cache_dir); +} + +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +This is a +This is b +This is b/c +===DONE=== diff --git a/ext/phar/tests/phar_buildfromdirectory2-win.phpt b/ext/phar/tests/phar_buildfromdirectory2-win.phpt index 49361bceb07a3..fd552302ae5e6 100644 --- a/ext/phar/tests/phar_buildfromdirectory2-win.phpt +++ b/ext/phar/tests/phar_buildfromdirectory2-win.phpt @@ -26,5 +26,5 @@ __HALT_COMPILER(); ?> --EXPECTF-- %s(24) "UnexpectedValueException" -RecursiveDirectoryIterator::__construct(1,1): The system cannot find the file specified. (code: 2) +RecursiveDirectoryIterator::__construct(1,1): %s (code: 2) ===DONE=== diff --git a/ext/phar/tests/phar_gobyebye-win32.phpt b/ext/phar/tests/phar_gobyebye-win32.phpt index 55884917bd35c..ff7b685aac9b5 100644 --- a/ext/phar/tests/phar_gobyebye-win32.phpt +++ b/ext/phar/tests/phar_gobyebye-win32.phpt @@ -42,7 +42,7 @@ bool(false) bool(false) bool(false) -Warning: opendir(foo/hi,foo/hi): The system cannot find the path specified. (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d +Warning: opendir(foo/hi,foo/hi): %s (code: 3) in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d Warning: opendir(foo/hi): failed to open dir: No such file or directory in phar://%sphar_gobyebye-win32.phar.php/foo/hi on line %d ===DONE=== diff --git a/ext/posix/tests/posix_getpwnam_basic_01.phpt b/ext/posix/tests/posix_getpwnam_basic_01.phpt index 23604b6ff0e7d..e45b6fa95dfdd 100644 --- a/ext/posix/tests/posix_getpwnam_basic_01.phpt +++ b/ext/posix/tests/posix_getpwnam_basic_01.phpt @@ -12,9 +12,6 @@ User Group: PHPSP #phptestfestbrasil $uid = posix_geteuid(); $user = posix_getpwuid($uid); $username = $user['name']; - if (posix_getlogin() == false) { - $username = false; - } $info = posix_getpwnam($username); print_r($info); var_dump($username == $info['name']); diff --git a/ext/readline/php_readline.h b/ext/readline/php_readline.h index bcd61bcc88bf4..8d55228a7fa02 100644 --- a/ext/readline/php_readline.h +++ b/ext/readline/php_readline.h @@ -20,11 +20,6 @@ #define PHP_READLINE_H #if HAVE_LIBREADLINE || HAVE_LIBEDIT -#ifndef PHP_WIN32 -#ifdef ZTS -#warning Readline module will *NEVER* be thread-safe -#endif -#endif extern zend_module_entry readline_module_entry; #define phpext_readline_ptr &readline_module_entry diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index 1629ed012eafa..956386c532ec3 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -210,7 +210,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{ int brace_count = 0; size_t i; php_code_type code_type = body; - char *heredoc_tag; + char *heredoc_tag = NULL; size_t heredoc_len; for (i = 0; i < len; ++i) { @@ -282,6 +282,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{ if (i + 2 < len && code[i+1] == '<' && code[i+2] == '<') { i += 2; code_type = heredoc_start; + heredoc_tag = NULL; heredoc_len = 0; } break; @@ -333,10 +334,15 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{ break; case '\r': case '\n': - code_type = heredoc; + if (heredoc_tag) { + code_type = heredoc; + } else { + /* Malformed heredoc without label */ + code_type = body; + } break; default: - if (!heredoc_len) { + if (!heredoc_tag) { heredoc_tag = code+i; } heredoc_len++; @@ -344,6 +350,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{ } break; case heredoc: + ZEND_ASSERT(heredoc_tag); if (code[i - (heredoc_len + 1)] == '\n' && !strncmp(code + i - heredoc_len, heredoc_tag, heredoc_len) && code[i] == '\n') { code_type = body; } else if (code[i - (heredoc_len + 2)] == '\n' && !strncmp(code + i - heredoc_len - 1, heredoc_tag, heredoc_len) && code[i-1] == ';' && code[i] == '\n') { @@ -514,13 +521,12 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ retval = cli_completion_generator_ini(text, textlen, &cli_completion_state); } else { char *lc_text, *class_name_end; - size_t class_name_len; - zend_string *class_name; + zend_string *class_name = NULL; zend_class_entry *ce = NULL; class_name_end = strstr(text, "::"); if (class_name_end) { - class_name_len = class_name_end - text; + size_t class_name_len = class_name_end - text; class_name = zend_string_alloc(class_name_len, 0); zend_str_tolower_copy(ZSTR_VAL(class_name), text, class_name_len); if ((ce = zend_lookup_class(class_name)) == NULL) { @@ -554,11 +560,11 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ break; } efree(lc_text); - if (class_name_end) { + if (class_name) { zend_string_release_ex(class_name, 0); } if (ce && retval) { - size_t len = class_name_len + 2 + strlen(retval) + 1; + size_t len = ZSTR_LEN(ce->name) + 2 + strlen(retval) + 1; char *tmp = malloc(len); snprintf(tmp, len, "%s::%s", ZSTR_VAL(ce->name), retval); diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4 index daab409c32cc9..96535b7a0729d 100644 --- a/ext/reflection/config.m4 +++ b/ext/reflection/config.m4 @@ -1,4 +1,3 @@ dnl config.m4 for extension reflection -AC_DEFINE(HAVE_REFLECTION, 1, [Whether Reflection is enabled]) PHP_NEW_EXTENSION(reflection, php_reflection.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32 index 508696d033f56..7f000b02ab638 100644 --- a/ext/reflection/config.w32 +++ b/ext/reflection/config.w32 @@ -1,5 +1,4 @@ // vim:ft=javascript EXTENSION("reflection", "php_reflection.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -AC_DEFINE('HAVE_REFLECTION', 1, 'Reflection support enabled'); PHP_REFLECTION="yes"; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 5f8faa39b7ee6..3fbe78d382671 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4682,6 +4682,10 @@ ZEND_METHOD(reflection_class, newInstance) for (i = 0; i < num_args; i++) { zval_ptr_dtor(¶ms[i]); } + + if (EG(exception)) { + zend_object_store_ctor_failed(Z_OBJ_P(return_value)); + } if (ret == FAILURE) { php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name)); zval_ptr_dtor(return_value); @@ -4782,6 +4786,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs) } efree(params); } + + if (EG(exception)) { + zend_object_store_ctor_failed(Z_OBJ_P(return_value)); + } if (ret == FAILURE) { zval_ptr_dtor(&retval); php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name)); diff --git a/ext/reflection/tests/bug77882.phpt b/ext/reflection/tests/bug77882.phpt new file mode 100644 index 0000000000000..ff1d212861360 --- /dev/null +++ b/ext/reflection/tests/bug77882.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #77882: Different behavior: always calls destructor +--FILE-- +newInstance(); +} catch (Exception $e) { + echo "Exception\n"; +} +try { + $ref = new ReflectionClass('Test'); + $obj = $ref->newInstanceArgs([]); +} catch (Exception $e) { + echo "Exception\n"; +} + +?> +--EXPECT-- +Exception +Exception +Exception diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 552d990fe39f9..cb8138e60abd7 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -284,8 +284,7 @@ static int ps_files_write(ps_files *data, zend_string *key, zend_string *val) static int ps_files_cleanup_dir(const char *dirname, zend_long maxlifetime) { DIR *dir; - char dentry[sizeof(struct dirent) + MAXPATHLEN]; - struct dirent *entry = (struct dirent *) &dentry; + struct dirent *entry; zend_stat_t sbuf; char buf[MAXPATHLEN]; time_t now; @@ -312,7 +311,7 @@ static int ps_files_cleanup_dir(const char *dirname, zend_long maxlifetime) memcpy(buf, dirname, dirname_len); buf[dirname_len] = PHP_DIR_SEPARATOR; - while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) { + while ((entry = readdir(dir))) { /* does the file start with our prefix? */ if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) { size_t entry_len = strlen(entry->d_name); diff --git a/ext/session/session.c b/ext/session/session.c index f8f375d8881da..bf3ddee0d58ef 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -750,7 +750,7 @@ static PHP_INI_MH(OnUpdateSidBits) /* {{{ */ return SUCCESS; } - php_error_docref(NULL, E_WARNING, "session.configuration 'session.sid_bits' must be between 4 and 6."); + php_error_docref(NULL, E_WARNING, "session.configuration 'session.sid_bits_per_character' must be between 4 and 6."); return FAILURE; } /* }}} */ diff --git a/ext/simplexml/config.m4 b/ext/simplexml/config.m4 index a79d6af5e74ad..e591cb90dce33 100644 --- a/ext/simplexml/config.m4 +++ b/ext/simplexml/config.m4 @@ -6,19 +6,10 @@ PHP_ARG_ENABLE([simplexml], [Disable SimpleXML support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [SimpleXML: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_SIMPLEXML" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([SimpleXML extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([SimpleXML extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(SIMPLEXML_SHARED_LIBADD, [ @@ -26,8 +17,6 @@ if test "$PHP_SIMPLEXML" != "no"; then PHP_NEW_EXTENSION(simplexml, simplexml.c sxe.c, $ext_shared) PHP_INSTALL_HEADERS([ext/simplexml/php_simplexml.h ext/simplexml/php_simplexml_exports.h]) PHP_SUBST(SIMPLEXML_SHARED_LIBADD) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) PHP_ADD_EXTENSION_DEP(simplexml, libxml) PHP_ADD_EXTENSION_DEP(simplexml, spl, true) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index b7eaf90de60a3..e8ba1f505a0bc 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1016,6 +1016,7 @@ static int sxe_prop_is_empty(zval *object) /* {{{ */ zval iter_data; int test; int is_empty; + int use_iter = 0; sxe = Z_SXEOBJ_P(object); @@ -1052,6 +1053,7 @@ static int sxe_prop_is_empty(zval *object) /* {{{ */ ZVAL_COPY_VALUE(&iter_data, &sxe->iter.data); ZVAL_UNDEF(&sxe->iter.data); node = php_sxe_reset_iterator(sxe, 0); + use_iter = 1; } } @@ -1080,7 +1082,7 @@ static int sxe_prop_is_empty(zval *object) /* {{{ */ is_empty = 0; break; next_iter: - if (!Z_ISUNDEF(iter_data)) { + if (use_iter) { node = php_sxe_iterator_fetch(sxe, node->next, 0); } else { node = node->next; @@ -1088,7 +1090,7 @@ static int sxe_prop_is_empty(zval *object) /* {{{ */ } } - if (!Z_ISUNDEF(iter_data)) { + if (use_iter) { if (!Z_ISUNDEF(sxe->iter.data)) { zval_ptr_dtor(&sxe->iter.data); } diff --git a/ext/soap/config.m4 b/ext/soap/config.m4 index 8ca7eb3156466..833af7b7ac3fc 100644 --- a/ext/soap/config.m4 +++ b/ext/soap/config.m4 @@ -5,26 +5,15 @@ PHP_ARG_ENABLE([soap], [AS_HELP_STRING([--enable-soap], [Enable SOAP support])]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [SOAP: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_SOAP" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([SOAP extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([SOAP extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(SOAP_SHARED_LIBADD, [ AC_DEFINE(HAVE_SOAP,1,[ ]) PHP_NEW_EXTENSION(soap, soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_SUBST(SOAP_SHARED_LIBADD) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) fi diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index bb0f93a69afd0..33793704ad1ab 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -458,7 +458,7 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP { char buf[MAX_LENGTH_OF_LONG + 1]; char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, zend_hash_num_elements(sdl->types)); - char *str = emalloc(sizeof("anonymous") + buf + sizeof(buf) - 1 - res); + char *str = emalloc(sizeof("anonymous")-1 + (buf + sizeof(buf) - res)); memcpy(str, "anonymous", sizeof("anonymous")-1); memcpy(str + sizeof("anonymous")-1, res, buf + sizeof(buf) - res); @@ -555,7 +555,7 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp { char buf[MAX_LENGTH_OF_LONG + 1]; char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, zend_hash_num_elements(sdl->types)); - char *str = emalloc(sizeof("anonymous") + buf + sizeof(buf) - 1 - res); + char *str = emalloc(sizeof("anonymous")-1 + (buf + sizeof(buf) - res)); memcpy(str, "anonymous", sizeof("anonymous")-1); memcpy(str + sizeof("anonymous")-1, res, buf + sizeof(buf) - res); @@ -1799,6 +1799,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl smart_str_free(&key); } else{ soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes"); + return FALSE; /* the above call is noreturn, but not marked as such */ } /* type = QName */ @@ -1927,7 +1928,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl { char buf[MAX_LENGTH_OF_LONG + 1]; char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, zend_hash_num_elements(sdl->types)); - char *str = emalloc(sizeof("anonymous") + buf + sizeof(buf) - 1 - res); + char *str = emalloc(sizeof("anonymous")-1 + (buf + sizeof(buf) - res)); memcpy(str, "anonymous", sizeof("anonymous")-1); memcpy(str + sizeof("anonymous")-1, res, buf + sizeof(buf) - res); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index c224d24759f06..73ee89ea93838 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -51,7 +51,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level); static void clear_soap_fault(zval *obj); static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name); static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail); -static void soap_server_fault(char* code, char* string, char *actor, zval* details, char *name); +static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *actor, zval* details, char *name); static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr); static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int); @@ -2079,7 +2079,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade } /* }}} */ -static void soap_server_fault(char* code, char* string, char *actor, zval* details, char* name) /* {{{ */ +static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *actor, zval* details, char* name) /* {{{ */ { zval ret; @@ -2597,6 +2597,7 @@ static void do_soap_call(zend_execute_data *execute_data, int old_features; HashTable *old_typemap, *typemap = NULL; smart_str action = {0}; + int bailout = 0; SOAP_CLIENT_BEGIN_CODE(); @@ -2763,7 +2764,7 @@ static void do_soap_call(zend_execute_data *execute_data, } } zend_catch { - _bailout = 1; + bailout = 1; } zend_end_try(); if (SOAP_GLOBAL(encoding) != NULL) { @@ -2775,12 +2776,11 @@ static void do_soap_call(zend_execute_data *execute_data, SOAP_GLOBAL(class_map) = old_class_map; SOAP_GLOBAL(encoding) = old_encoding; SOAP_GLOBAL(sdl) = old_sdl; - if (_bailout) { + if (bailout) { smart_str_free(&action); if (request) { xmlFreeDoc(request); } - _bailout = 0; zend_bailout(); } SOAP_CLIENT_END_CODE(); @@ -3400,37 +3400,43 @@ static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_ } /* }}} */ -static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers) /* {{{ */ -{ - char* envelope_ns = NULL; - xmlNodePtr trav,env,head,body,func; - xmlAttrPtr attr; - sdlFunctionPtr function; - - encode_reset_ns(); - - /* Get element */ - env = NULL; - trav = request->children; +static xmlNodePtr get_envelope(xmlNodePtr trav, int *version, char **envelope_ns) { while (trav != NULL) { if (trav->type == XML_ELEMENT_NODE) { - if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) { - env = trav; + if (node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) { *version = SOAP_1_1; - envelope_ns = SOAP_1_1_ENV_NAMESPACE; + *envelope_ns = SOAP_1_1_ENV_NAMESPACE; SOAP_GLOBAL(soap_version) = SOAP_1_1; - } else if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) { - env = trav; + return trav; + } + + if (node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) { *version = SOAP_1_2; - envelope_ns = SOAP_1_2_ENV_NAMESPACE; + *envelope_ns = SOAP_1_2_ENV_NAMESPACE; SOAP_GLOBAL(soap_version) = SOAP_1_2; - } else { - soap_server_fault("VersionMismatch", "Wrong Version", NULL, NULL, NULL); + return trav; } + + soap_server_fault("VersionMismatch", "Wrong Version", NULL, NULL, NULL); } trav = trav->next; } - if (env == NULL) { + + return NULL; +} + +static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers) /* {{{ */ +{ + char* envelope_ns = NULL; + xmlNodePtr trav,env,head,body,func; + xmlAttrPtr attr; + sdlFunctionPtr function; + + encode_reset_ns(); + + /* Get element */ + env = get_envelope(request->children, version, &envelope_ns); + if (!env) { soap_server_fault("Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, NULL); } diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 6eede2b20a79f..a9f287a8eaac9 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -701,6 +701,9 @@ static void from_zval_write_sockaddr_aux(const zval *container, zval *elem; int fill_sockaddr; + *sockaddr_ptr = NULL; + *sockaddr_len = 0; + if (Z_TYPE_P(container) != IS_ARRAY) { do_from_zval_err(ctx, "%s", "expected an array here"); return; diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index 4ad29f3c94e3d..08ecbdf5f6aa0 100644 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -1,6 +1,5 @@ dnl config.m4 for extension SPL - AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard PHP Library) support]) PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h]) PHP_ADD_EXTENSION_DEP(spl, pcre, true) diff --git a/ext/spl/config.w32 b/ext/spl/config.w32 index b82333a2619ed..8d8277be23204 100644 --- a/ext/spl/config.w32 +++ b/ext/spl/config.w32 @@ -1,6 +1,5 @@ // vim:ft=javascript EXTENSION("spl", "php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -AC_DEFINE('HAVE_SPL', 1); PHP_SPL="yes"; PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h"); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index ab488726df37a..284bb71c81de7 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1470,7 +1470,8 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam } else { GC_DELREF(aht); } - efree(Z_REF(params[0])); + ZVAL_NULL(Z_REFVAL(params[0])); + zval_ptr_dtor(¶ms[0]); zend_string_free(Z_STR(function_name)); } } /* }}} */ @@ -1812,6 +1813,80 @@ SPL_METHOD(Array, unserialize) } /* }}} */ +/* {{{ proto array ArrayObject::__serialize() */ +SPL_METHOD(Array, __serialize) +{ + spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); + zval tmp; + + if (zend_parse_parameters_none_throw() == FAILURE) { + return; + } + + array_init(return_value); + + /* flags */ + ZVAL_LONG(&tmp, (intern->ar_flags & SPL_ARRAY_CLONE_MASK)); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); + + /* storage */ + if (intern->ar_flags & SPL_ARRAY_IS_SELF) { + ZVAL_NULL(&tmp); + } else { + ZVAL_COPY(&tmp, &intern->array); + } + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); + + /* members */ + ZVAL_ARR(&tmp, zend_std_get_properties(ZEND_THIS)); + Z_TRY_ADDREF(tmp); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); +} +/* }}} */ + + +/* {{{ proto void ArrayObject::__unserialize(array data) */ +SPL_METHOD(Array, __unserialize) +{ + spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); + HashTable *data; + zval *flags_zv, *storage_zv, *members_zv; + zend_long flags; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "h", &data) == FAILURE) { + return; + } + + flags_zv = zend_hash_index_find(data, 0); + storage_zv = zend_hash_index_find(data, 1); + members_zv = zend_hash_index_find(data, 2); + if (!flags_zv || !storage_zv || !members_zv || + Z_TYPE_P(flags_zv) != IS_LONG || Z_TYPE_P(members_zv) != IS_ARRAY) { + zend_throw_exception(spl_ce_UnexpectedValueException, + "Incomplete or ill-typed serialization data", 0); + return; + } + + flags = Z_LVAL_P(flags_zv); + intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK; + intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK; + + if (flags & SPL_ARRAY_IS_SELF) { + zval_ptr_dtor(&intern->array); + ZVAL_UNDEF(&intern->array); + } else if (Z_TYPE_P(storage_zv) == IS_ARRAY) { + zval_ptr_dtor(&intern->array); + ZVAL_COPY_VALUE(&intern->array, storage_zv); + ZVAL_NULL(storage_zv); + SEPARATE_ARRAY(&intern->array); + } else { + spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1); + } + + object_properties_load(&intern->std, Z_ARRVAL_P(members_zv)); +} +/* }}} */ + /* {{{ arginfo and function table */ ZEND_BEGIN_ARG_INFO_EX(arginfo_array___construct, 0, 0, 0) ZEND_ARG_INFO(0, input) @@ -1884,6 +1959,8 @@ static const zend_function_entry spl_funcs_ArrayObject[] = { SPL_ME(Array, natcasesort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, __unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) + SPL_ME(Array, __serialize, arginfo_array_void, ZEND_ACC_PUBLIC) /* ArrayObject specific */ SPL_ME(Array, getIterator, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, exchangeArray, arginfo_array_exchangeArray, ZEND_ACC_PUBLIC) @@ -1911,6 +1988,8 @@ static const zend_function_entry spl_funcs_ArrayIterator[] = { SPL_ME(Array, natcasesort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, __unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) + SPL_ME(Array, __serialize, arginfo_array_void, ZEND_ACC_PUBLIC) /* ArrayIterator specific */ SPL_ME(Array, rewind, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, current, arginfo_array_void, ZEND_ACC_PUBLIC) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 430d13011f0da..97f4429e8fdab 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1598,7 +1598,7 @@ SPL_METHOD(GlobIterator, __construct) } /* }}} */ -/* {{{ proto int GlobIterator::cont() +/* {{{ proto int GlobIterator::count() Return the number of directories and files found by globbing */ SPL_METHOD(GlobIterator, count) { diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 2a274595f3cda..299cf70174e0c 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1220,6 +1220,67 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) } /* }}} */ +/* {{{ proto array SplDoublyLinkedList::__serialize() */ +SPL_METHOD(SplDoublyLinkedList, __serialize) +{ + spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); + spl_ptr_llist_element *current = intern->llist->head; + zval tmp; + + if (zend_parse_parameters_none_throw() == FAILURE) { + return; + } + + array_init(return_value); + + /* flags */ + ZVAL_LONG(&tmp, intern->flags); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); + + /* elements */ + array_init_size(&tmp, intern->llist->count); + while (current) { + zend_hash_next_index_insert(Z_ARRVAL(tmp), ¤t->data); + current = current->next; + } + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); + + /* members */ + ZVAL_ARR(&tmp, zend_std_get_properties(ZEND_THIS)); + Z_TRY_ADDREF(tmp); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); +} /* }}} */ + +/* {{{ proto void SplDoublyLinkedList::__unserialize(array serialized) */ +SPL_METHOD(SplDoublyLinkedList, __unserialize) { + spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); + HashTable *data; + zval *flags_zv, *storage_zv, *members_zv, *elem; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "h", &data) == FAILURE) { + return; + } + + flags_zv = zend_hash_index_find(data, 0); + storage_zv = zend_hash_index_find(data, 1); + members_zv = zend_hash_index_find(data, 2); + if (!flags_zv || !storage_zv || !members_zv || + Z_TYPE_P(flags_zv) != IS_LONG || Z_TYPE_P(storage_zv) != IS_ARRAY || + Z_TYPE_P(members_zv) != IS_ARRAY) { + zend_throw_exception(spl_ce_UnexpectedValueException, + "Incomplete or ill-typed serialization data", 0); + return; + } + + intern->flags = (int) Z_LVAL_P(flags_zv); + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(storage_zv), elem) { + spl_ptr_llist_push(intern->llist, elem); + } ZEND_HASH_FOREACH_END(); + + object_properties_load(&intern->std, Z_ARRVAL_P(members_zv)); +} /* }}} */ + /* {{{ proto void SplDoublyLinkedList::add(mixed index, mixed newval) Inserts a new entry before the specified $index consisting of $newval. */ SPL_METHOD(SplDoublyLinkedList, add) @@ -1374,6 +1435,8 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = { /* Serializable */ SPL_ME(SplDoublyLinkedList, unserialize, arginfo_dllist_serialized, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, serialize, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, __unserialize, arginfo_dllist_serialized, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, __serialize, arginfo_dllist_void, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 8b170afaee69c..381019519369d 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -868,6 +868,78 @@ SPL_METHOD(SplObjectStorage, unserialize) } /* }}} */ +/* {{{ proto auto SplObjectStorage::__serialize() */ +SPL_METHOD(SplObjectStorage, __serialize) +{ + spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); + spl_SplObjectStorageElement *elem; + zval tmp; + + if (zend_parse_parameters_none_throw() == FAILURE) { + return; + } + + array_init(return_value); + + /* storage */ + array_init_size(&tmp, 2 * zend_hash_num_elements(&intern->storage)); + ZEND_HASH_FOREACH_PTR(&intern->storage, elem) { + Z_TRY_ADDREF(elem->obj); + zend_hash_next_index_insert(Z_ARRVAL(tmp), &elem->obj); + Z_TRY_ADDREF(elem->inf); + zend_hash_next_index_insert(Z_ARRVAL(tmp), &elem->inf); + } ZEND_HASH_FOREACH_END(); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); + + /* members */ + ZVAL_ARR(&tmp, zend_std_get_properties(ZEND_THIS)); + Z_TRY_ADDREF(tmp); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); +} /* }}} */ + +/* {{{ proto void SplObjectStorage::__unserialize(array serialized) */ +SPL_METHOD(SplObjectStorage, __unserialize) +{ + spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); + HashTable *data; + zval *storage_zv, *members_zv, *key, *val; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "h", &data) == FAILURE) { + return; + } + + storage_zv = zend_hash_index_find(data, 0); + members_zv = zend_hash_index_find(data, 1); + if (!storage_zv || !members_zv || + Z_TYPE_P(storage_zv) != IS_ARRAY || Z_TYPE_P(members_zv) != IS_ARRAY) { + zend_throw_exception(spl_ce_UnexpectedValueException, + "Incomplete or ill-typed serialization data", 0); + return; + } + + if (zend_hash_num_elements(Z_ARRVAL_P(storage_zv)) % 2 != 0) { + zend_throw_exception(spl_ce_UnexpectedValueException, "Odd number of elements", 0); + return; + } + + key = NULL; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(storage_zv), val) { + if (key) { + if (Z_TYPE_P(key) != IS_OBJECT) { + zend_throw_exception(spl_ce_UnexpectedValueException, "Non-object key", 0); + return; + } + + spl_object_storage_attach(intern, ZEND_THIS, key, val); + key = NULL; + } else { + key = val; + } + } ZEND_HASH_FOREACH_END(); + + object_properties_load(&intern->std, Z_ARRVAL_P(members_zv)); +} + ZEND_BEGIN_ARG_INFO(arginfo_Object, 0) ZEND_ARG_INFO(0, object) ZEND_END_ARG_INFO(); @@ -917,6 +989,8 @@ static const zend_function_entry spl_funcs_SplObjectStorage[] = { /* Serializable */ SPL_ME(SplObjectStorage, unserialize, arginfo_Serialized, 0) SPL_ME(SplObjectStorage, serialize, arginfo_splobject_void,0) + SPL_ME(SplObjectStorage, __unserialize, arginfo_Serialized, 0) + SPL_ME(SplObjectStorage, __serialize, arginfo_splobject_void,0) /* ArrayAccess */ SPL_MA(SplObjectStorage, offsetExists, SplObjectStorage, contains, arginfo_offsetGet, 0) SPL_MA(SplObjectStorage, offsetSet, SplObjectStorage, attach, arginfo_attach, 0) diff --git a/ext/spl/tests/SplDoublyLinkedList_serialization.phpt b/ext/spl/tests/SplDoublyLinkedList_serialization.phpt index 7ab7d78174f7e..d04e0cbe72514 100644 --- a/ext/spl/tests/SplDoublyLinkedList_serialization.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_serialization.phpt @@ -29,7 +29,7 @@ object(SplQueue)#%d (2) { string(1) "b" } } -string(42) "C:8:"SplQueue":22:{i:4;:s:1:"a";:s:1:"b";}" +string(71) "O:8:"SplQueue":3:{i:0;i:4;i:1;a:2:{i:0;s:1:"a";i:1;s:1:"b";}i:2;a:0:{}}" object(SplQueue)#%d (2) { ["flags":"SplDoublyLinkedList":private]=> int(4) @@ -52,7 +52,7 @@ object(SplStack)#%d (2) { string(1) "b" } } -string(42) "C:8:"SplStack":22:{i:6;:s:1:"a";:s:1:"b";}" +string(71) "O:8:"SplStack":3:{i:0;i:6;i:1;a:2:{i:0;s:1:"a";i:1;s:1:"b";}i:2;a:0:{}}" object(SplStack)#%d (2) { ["flags":"SplDoublyLinkedList":private]=> int(6) diff --git a/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt b/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt index daf415049c911..c75662c66ecc9 100644 --- a/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt +++ b/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt @@ -18,7 +18,7 @@ echo $s."\n"; $so1 = unserialize($s); var_dump($so1); --EXPECTF-- -C:16:"SplObjectStorage":76:{x:i:2;O:8:"stdClass":1:{s:1:"a";O:8:"stdClass":0:{}},i:1;;r:4;,i:2;;m:a:0:{}} +O:16:"SplObjectStorage":2:{i:0;a:4:{i:0;O:8:"stdClass":1:{s:1:"a";O:8:"stdClass":0:{}}i:1;i:1;i:2;r:4;i:3;i:2;}i:1;a:0:{}} object(SplObjectStorage)#4 (1) { ["storage":"SplObjectStorage":private]=> array(2) { diff --git a/ext/spl/tests/array_025.phpt b/ext/spl/tests/array_025.phpt index 35893ea1eaf55..9a95de60eb48d 100644 --- a/ext/spl/tests/array_025.phpt +++ b/ext/spl/tests/array_025.phpt @@ -24,7 +24,7 @@ ArrayObject Object ) ) -C:11:"ArrayObject":76:{x:i:0;C:11:"ArrayObject":37:{x:i:0;a:2:{i:0;i:1;i:1;i:2;};m:a:0:{}};m:a:0:{}} +O:11:"ArrayObject":3:{i:0;i:0;i:1;O:11:"ArrayObject":3:{i:0;i:0;i:1;a:2:{i:0;i:1;i:1;i:2;}i:2;a:0:{}}i:2;a:0:{}} ArrayObject Object ( [storage:ArrayObject:private] => ArrayObject Object diff --git a/ext/spl/tests/bug45826.phpt b/ext/spl/tests/bug45826.phpt index 7993bfaa95875..8187b3a3203aa 100644 --- a/ext/spl/tests/bug45826.phpt +++ b/ext/spl/tests/bug45826.phpt @@ -31,12 +31,12 @@ var_dump($o2[2][2] === $o2[2]); echo "#### Extending ArrayObject\n"; unset($o,$x,$s1,$s2,$o1,$o2); class ArrayObject2 extends ArrayObject { - public function serialize() { - return parent::serialize(); + public function __serialize() { + return parent::__serialize(); } - public function unserialize($s) { - return parent::unserialize($s); + public function __unserialize($s) { + return parent::__unserialize($s); } } @@ -50,17 +50,17 @@ var_dump($o[0] === $o[1]); var_dump($o[2] === $o); $s1 = serialize($o); -$s2 = $o->serialize(); +$s2 = $o->__serialize(); var_dump($s1); var_dump($s2); -$o1 =unserialize($s1); +$o1 = unserialize($s1); var_dump($o1[0] === $o1[1]); var_dump($o1[2] === $o1); $o2 = new ArrayObject2(); -$o2->unserialize($s2); +$o2->__unserialize($s2); var_dump($o2[0] === $o2[1]); var_dump($o2[2] !== $o2); @@ -69,8 +69,8 @@ var_dump($o2[2][2] === $o2[2]); --EXPECT-- bool(true) bool(true) -string(84) "C:11:"ArrayObject":60:{x:i:0;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:4;i:2;r:1;};m:a:0:{}}" -string(125) "x:i:0;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:3;i:2;C:11:"ArrayObject":45:{x:i:0;a:3:{i:0;r:3;i:1;r:3;i:2;r:5;};m:a:0:{}}};m:a:0:{}" +string(90) "O:11:"ArrayObject":3:{i:0;i:0;i:1;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:4;i:2;r:1;}i:2;a:0:{}}" +string(131) "x:i:0;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:3;i:2;O:11:"ArrayObject":3:{i:0;i:0;i:1;a:3:{i:0;r:3;i:1;r:3;i:2;r:5;}i:2;a:0:{}}};m:a:0:{}" bool(true) bool(true) bool(true) @@ -79,8 +79,28 @@ bool(true) #### Extending ArrayObject bool(true) bool(true) -string(85) "C:12:"ArrayObject2":60:{x:i:0;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:4;i:2;r:1;};m:a:0:{}}" -string(126) "x:i:0;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:3;i:2;C:12:"ArrayObject2":45:{x:i:0;a:3:{i:0;r:3;i:1;r:3;i:2;r:5;};m:a:0:{}}};m:a:0:{}" +string(91) "O:12:"ArrayObject2":3:{i:0;i:0;i:1;a:3:{i:0;O:8:"stdClass":0:{}i:1;r:4;i:2;r:1;}i:2;a:0:{}}" +array(3) { + [0]=> + int(0) + [1]=> + array(3) { + [0]=> + object(stdClass)#8 (0) { + } + [1]=> + object(stdClass)#8 (0) { + } + [2]=> + object(ArrayObject2)#5 (1) { + ["storage":"ArrayObject":private]=> + *RECURSION* + } + } + [2]=> + array(0) { + } +} bool(true) bool(true) bool(true) diff --git a/ext/spl/tests/bug49263.phpt b/ext/spl/tests/bug49263.phpt index a2e2e0b3968b0..4d9e8e1d60a59 100644 --- a/ext/spl/tests/bug49263.phpt +++ b/ext/spl/tests/bug49263.phpt @@ -17,7 +17,7 @@ var_dump(unserialize($ss)); ?> ===DONE=== --EXPECTF-- -C:16:"SplObjectStorage":113:{x:i:2;O:8:"stdClass":0:{},a:2:{s:4:"prev";i:2;s:4:"next";O:8:"stdClass":0:{}};r:6;,a:1:{s:4:"prev";r:3;};m:a:0:{}} +O:16:"SplObjectStorage":2:{i:0;a:4:{i:0;O:8:"stdClass":0:{}i:1;a:2:{s:4:"prev";i:2;s:4:"next";O:8:"stdClass":0:{}}i:2;r:6;i:3;a:1:{s:4:"prev";r:3;}}i:1;a:0:{}} object(SplObjectStorage)#2 (1) { ["storage":"SplObjectStorage":private]=> array(2) { diff --git a/ext/spl/tests/bug74669.phpt b/ext/spl/tests/bug74669.phpt index 5e4fcd023b10f..264cd3b97a358 100644 --- a/ext/spl/tests/bug74669.phpt +++ b/ext/spl/tests/bug74669.phpt @@ -104,7 +104,7 @@ object(SelfArray)#9 (1) { ["foo"]=> string(3) "bar" } -string(62) "C:9:"SelfArray":41:{x:i:16777216;m:a:1:{s:3:"foo";s:3:"bar";}}" +string(71) "O:9:"SelfArray":3:{i:0;i:16777216;i:1;N;i:2;a:1:{s:3:"foo";s:3:"bar";}}" object(SelfArray)#9 (1) { ["foo"]=> string(3) "bar" diff --git a/ext/spl/tests/bug77903.phpt b/ext/spl/tests/bug77903.phpt new file mode 100644 index 0000000000000..842de9cca2eae --- /dev/null +++ b/ext/spl/tests/bug77903.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #77903: ArrayIterator stops iterating after offsetSet call +--FILE-- +rewind(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +$a->offsetSet(1,1); +var_dump($a->valid()); // true +var_dump($a->current()); // 1 +$a->next(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +$a->offsetSet(4,4); +var_dump($a->valid()); // true +var_dump($a->current()); // 4 +$a->next(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +$a->next(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +$a->offsetSet(2,2); +var_dump($a->valid()); // true +var_dump($a->current()); // 2 +$a->next(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +$a->next(); +var_dump($a->valid()); // false +var_dump($a->current()); // null +?> +--EXPECT-- +bool(false) +NULL +bool(true) +int(1) +bool(false) +NULL +bool(true) +int(4) +bool(false) +NULL +bool(false) +NULL +bool(true) +int(2) +bool(false) +NULL +bool(false) +NULL diff --git a/ext/spl/tests/spl_autoload_007.phpt b/ext/spl/tests/spl_autoload_007.phpt index 1a81f191c7e20..3233120790fa2 100644 --- a/ext/spl/tests/spl_autoload_007.phpt +++ b/ext/spl/tests/spl_autoload_007.phpt @@ -116,7 +116,7 @@ array(2) { [1]=> string(8) "noAccess" } -Passed array does not specify a callable method (cannot access protected method MyAutoLoader::noAccess()) +Passed array does not specify a callable static method (cannot access protected method MyAutoLoader::noAccess()) array(2) { [0]=> diff --git a/ext/spl/tests/unserialize_errors.phpt b/ext/spl/tests/unserialize_errors.phpt new file mode 100644 index 0000000000000..237d0673c46be --- /dev/null +++ b/ext/spl/tests/unserialize_errors.phpt @@ -0,0 +1,138 @@ +--TEST-- +Errors from __unserialize() with invalid data +--FILE-- +getMessage(), "\n"; +} + +try { + unserialize('O:11:"ArrayObject":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:11:"ArrayObject":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:11:"ArrayObject":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +echo "ArrayIterator:\n"; + +try { + unserialize('O:13:"ArrayIterator":0:{}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:13:"ArrayIterator":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:13:"ArrayIterator":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:13:"ArrayIterator":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +echo "SplDoublyLinkedList:\n"; + +try { + unserialize('O:19:"SplDoublyLinkedList":0:{}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:19:"SplDoublyLinkedList":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:19:"SplDoublyLinkedList":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:19:"SplDoublyLinkedList":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +echo "SplObjectStorage:\n"; + +try { + unserialize('O:16:"SplObjectStorage":0:{}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:16:"SplObjectStorage":2:{i:0;i:0;i:1;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:16:"SplObjectStorage":2:{i:0;a:0:{}i:1;i:1;}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:16:"SplObjectStorage":2:{i:0;a:1:{i:0;i:0;}i:1;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +try { + unserialize('O:16:"SplObjectStorage":2:{i:0;a:2:{i:0;i:0;i:1;i:0;}i:1;a:0:{}}'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +ArrayObject: +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Passed variable is not an array or object +ArrayIterator: +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Passed variable is not an array or object +SplDoublyLinkedList: +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +SplObjectStorage: +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Incomplete or ill-typed serialization data +Odd number of elements +Non-object key diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 205d97255091d..4f7d496972963 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -865,6 +865,11 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in zval retval; int ret; + // Exception occurred on previous callback. Don't attempt to call function. + if (EG(exception)) { + return 0; + } + collation->fci.fci.size = (sizeof(collation->fci.fci)); ZVAL_COPY_VALUE(&collation->fci.fci.function_name, &collation->cmp_func); collation->fci.fci.object = NULL; @@ -876,13 +881,8 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in collation->fci.fci.params = zargs; - if (!EG(exception)) { - //Exception occurred on previous callback. Don't attempt to call function - if ((ret = zend_call_function(&collation->fci.fci, &collation->fci.fcc)) == FAILURE) { - php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback"); - } - } else { - ZVAL_UNDEF(&retval); + if ((ret = zend_call_function(&collation->fci.fci, &collation->fci.fcc)) == FAILURE) { + php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback"); } zval_ptr_dtor(&zargs[0]); diff --git a/ext/standard/array.c b/ext/standard/array.c index 2658ad68f5a17..e257caa3c8be7 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -3145,6 +3145,7 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H } /* replace HashTable data */ + HT_SET_ITERATORS_COUNT(&out_hash, HT_ITERATORS_COUNT(in_hash)); HT_SET_ITERATORS_COUNT(in_hash, 0); in_hash->pDestructor = NULL; zend_hash_destroy(in_hash); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 29ee2fb3f2554..c78de74f2f2e0 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4690,6 +4690,8 @@ PHP_FUNCTION(get_current_user) } /* }}} */ +static void add_config_entries(HashTable *hash, zval *return_value); + /* {{{ add_config_entry */ static void add_config_entry(zend_ulong h, zend_string *key, zval *entry, zval *retval) @@ -4701,14 +4703,9 @@ static void add_config_entry(zend_ulong h, zend_string *key, zval *entry, zval * add_index_str(retval, h, zend_string_copy(Z_STR_P(entry))); } } else if (Z_TYPE_P(entry) == IS_ARRAY) { - zend_ulong h; - zend_string *key; - zval *zv, tmp; - + zval tmp; array_init(&tmp); - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(entry), h, key, zv) - add_config_entry(h, key, zv, &tmp); - ZEND_HASH_FOREACH_END(); + add_config_entries(Z_ARRVAL_P(entry), &tmp); zend_hash_update(Z_ARRVAL_P(retval), key, &tmp); } } diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 611cbccdbea90..b01aed1e96ba2 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -661,11 +661,11 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, array_init(response_header); } - if (!php_stream_eof(stream)) { - size_t tmp_line_len; + { /* get response header */ - - if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) { + size_t tmp_line_len; + if (!php_stream_eof(stream) && + php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) { zval http_response; if (tmp_line_len > 9) { @@ -726,10 +726,10 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } ZVAL_STRINGL(&http_response, tmp_line, tmp_line_len); zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response); + } else { + php_stream_wrapper_log_error(wrapper, options, "HTTP request failed, unexpected end of socket!"); + goto out; } - } else { - php_stream_wrapper_log_error(wrapper, options, "HTTP request failed, unexpected end of socket!"); - goto out; } /* read past HTTP headers */ diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 36fe523d92d7a..053f8417ec3df 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -181,7 +181,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa int fd = -1; int mode_rw = 0; php_stream * stream = NULL; - char *p, *token, *pathdup; + char *p, *token = NULL, *pathdup; zend_long max_memory; FILE *file = NULL; #ifdef PHP_WIN32 diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 32de9d2fe6a7e..37461b0d1df48 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1488,7 +1488,7 @@ PHP_FUNCTION(stream_socket_enable_crypto) zend_long cryptokind = 0; zval *zstream, *zsessstream = NULL; php_stream *stream, *sessstream = NULL; - zend_bool enable, cryptokindnull; + zend_bool enable, cryptokindnull = 1; int ret; ZEND_PARSE_PARAMETERS_START(2, 4) @@ -1502,7 +1502,7 @@ PHP_FUNCTION(stream_socket_enable_crypto) php_stream_from_zval(stream, zstream); if (enable) { - if (ZEND_NUM_ARGS() < 3 || cryptokindnull) { + if (cryptokindnull) { zval *val; if (!GET_CTX_OPT(stream, "ssl", "crypto_method", val)) { diff --git a/ext/standard/string.c b/ext/standard/string.c index c78ec5ffacd76..41a391876c765 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -5029,7 +5029,6 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const uint8_t state = 0; size_t pos; char *allow_free = NULL; - const char *allow_actual; char is_xml = 0; buf = estrndup(rbuf, len); @@ -5040,7 +5039,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const br = 0; if (allow) { allow_free = zend_str_tolower_dup_ex(allow, allow_len); - allow_actual = allow_free ? allow_free : allow; + allow = allow_free ? allow_free : allow; tbuf = emalloc(PHP_TAG_BUF_SIZE + 1); tp = tbuf; } else { @@ -5145,7 +5144,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const } *(tp++) = '>'; *tp='\0'; - if (php_tag_find(tbuf, tp-tbuf, allow_actual)) { + if (php_tag_find(tbuf, tp-tbuf, allow)) { memcpy(rp, tbuf, tp-tbuf); rp += tp-tbuf; } @@ -5339,11 +5338,11 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const *rp = '\0'; } efree((void *)buf); - if (allow) { + if (tbuf) { efree(tbuf); - if (allow_free) { - efree(allow_free); - } + } + if (allow_free) { + efree(allow_free); } if (stateptr) *stateptr = state; diff --git a/ext/standard/tests/file/lstat_stat_variation15.phpt b/ext/standard/tests/file/lstat_stat_variation15.phpt index 8278b8dba9323..467c0ef5518c2 100644 --- a/ext/standard/tests/file/lstat_stat_variation15.phpt +++ b/ext/standard/tests/file/lstat_stat_variation15.phpt @@ -43,7 +43,7 @@ $new_stat = lstat($linkname); var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat -var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "==") ); echo "\n--- Done ---"; ?> diff --git a/ext/standard/tests/file/realpath_basic3.phpt b/ext/standard/tests/file/realpath_basic3.phpt index 0feccfc150638..622c1d6ccea83 100644 --- a/ext/standard/tests/file/realpath_basic3.phpt +++ b/ext/standard/tests/file/realpath_basic3.phpt @@ -10,11 +10,11 @@ echo "\n*** Testing basic functions of realpath() with files ***\n"; /* creating directories and files */ $file_path = __DIR__; -mkdir("$file_path/realpath_basic/home/test/", 0777, true); +mkdir("$file_path/realpath_basic3/home/test/", 0777, true); -$file_handle1 = fopen("$file_path/realpath_basic/home/test/realpath_basic.tmp", "w"); -$file_handle2 = fopen("$file_path/realpath_basic/home/realpath_basic.tmp", "w"); -$file_handle3 = fopen("$file_path/realpath_basic/realpath_basic.tmp", "w"); +$file_handle1 = fopen("$file_path/realpath_basic3/home/test/realpath_basic3.tmp", "w"); +$file_handle2 = fopen("$file_path/realpath_basic3/home/realpath_basic3.tmp", "w"); +$file_handle3 = fopen("$file_path/realpath_basic3/realpath_basic3.tmp", "w"); fclose($file_handle1); fclose($file_handle2); fclose($file_handle3); @@ -22,17 +22,17 @@ fclose($file_handle3); echo "\n*** Testing realpath() on filenames ***\n"; $filenames = array ( /* filenames resulting in valid paths */ - "./realpath_basic/home/realpath_basic.tmp", - "./realpath_basic/realpath_basic.tmp", - "./realpath_basic//home/test//../test/./realpath_basic.tmp", - "./realpath_basic/home//../././realpath_basic.tmp", + "./realpath_basic3/home/realpath_basic3.tmp", + "./realpath_basic3/realpath_basic3.tmp", + "./realpath_basic3//home/test//../test/./realpath_basic3.tmp", + "./realpath_basic3/home//../././realpath_basic3.tmp", /* filenames with invalid path */ // checking for binary safe - "./realpath_basicx000/home/realpath_basic.tmp", + "./realpath_basic3x000/home/realpath_basic3.tmp", - ".///realpath_basic/home//..//././test//realpath_basic.tmp", - "./realpath_basic/home/../home/../test/..realpath_basic.tmp" + ".///realpath_basic3/home//..//././test//realpath_basic3.tmp", + "./realpath_basic3/home/../home/../test/..realpath_basic3.tmp" ); chdir("$file_path/.."); @@ -50,10 +50,10 @@ echo "Done\n"; ?> --CLEAN-- --CLEAN-- --EXPECTF-- -1. %s%erealpath_basic%ehome -2. %s%erealpath_basic%ehome%etest +1. %s%erealpath_basic4%ehome +2. %s%erealpath_basic4%ehome%etest diff --git a/ext/standard/tests/file/stat_variation3-win32.phpt b/ext/standard/tests/file/stat_variation3-win32.phpt index c59d0b10ec313..d08612fc7f0df 100644 --- a/ext/standard/tests/file/stat_variation3-win32.phpt +++ b/ext/standard/tests/file/stat_variation3-win32.phpt @@ -54,7 +54,7 @@ $new_stat1 = stat($dirname); // compare self stats var_dump( compare_self_stat($new_stat1) ); // compare the stats -var_dump(compare_stats($new_stat, $new_stat1, $all_stat_keys, "=")); +var_dump(compare_stats($new_stat, $new_stat1, $affected_members, "<")); clearstatcache(); echo "\n*** Done ***"; diff --git a/ext/standard/tests/file/stat_variation4-win32.phpt b/ext/standard/tests/file/stat_variation4-win32.phpt index d95eaaa2a7a63..a5e25f99d03a4 100644 --- a/ext/standard/tests/file/stat_variation4-win32.phpt +++ b/ext/standard/tests/file/stat_variation4-win32.phpt @@ -44,7 +44,7 @@ $new_stat = stat($old_dirname); var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat -var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "==") ); // clear the stat clearstatcache(); @@ -62,7 +62,7 @@ $new_stat = stat($old_filename); var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat -var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $all_stat_keys, "==") ); // clear the stat clearstatcache(); diff --git a/ext/standard/tests/file/stat_variation5-win32.phpt b/ext/standard/tests/file/stat_variation5-win32.phpt index 9f188bb307e4a..d2c9fd4c84225 100644 --- a/ext/standard/tests/file/stat_variation5-win32.phpt +++ b/ext/standard/tests/file/stat_variation5-win32.phpt @@ -42,7 +42,7 @@ var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat $affected_members = array(10, 'ctime'); -var_dump( compare_stats($old_stat, $new_stat, $affected_members, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $affected_members, "==") ); // clear the stat clearstatcache(); diff --git a/ext/standard/tests/file/stat_variation6-win32.phpt b/ext/standard/tests/file/stat_variation6-win32.phpt index cf38bd3150b3a..38c69f97f20d1 100644 --- a/ext/standard/tests/file/stat_variation6-win32.phpt +++ b/ext/standard/tests/file/stat_variation6-win32.phpt @@ -43,7 +43,7 @@ var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat $affected_members = array( 10, 'ctime'); -var_dump( compare_stats($old_stat, $new_stat, $affected_members, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $affected_members, "==") ); // clear the stat clearstatcache(); // clear statement cache @@ -60,7 +60,7 @@ var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat $affected_members = array( 10, 'ctime'); -var_dump( compare_stats($old_stat, $new_stat, $affected_members, "=") ); +var_dump( compare_stats($old_stat, $new_stat, $affected_members, "==") ); // clear the stat clearstatcache(); // clear statement cache diff --git a/ext/standard/tests/general_functions/get_cfg_var_array.phpt b/ext/standard/tests/general_functions/get_cfg_var_array.phpt new file mode 100644 index 0000000000000..720e635885a0c --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_array.phpt @@ -0,0 +1,27 @@ +--TEST-- +Using get_cfg_var() on an array ini value +--INI-- +ary[a] = 1 +ary[b] = 2 +ary2[1] = a +ary2[2] = b +--FILE-- + +--EXPECT-- +array(2) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" +} +array(2) { + [1]=> + string(1) "a" + [2]=> + string(1) "b" +} diff --git a/ext/standard/tests/serialize/__serialize_002.phpt b/ext/standard/tests/serialize/__serialize_002.phpt index 143ee933ed5f6..72851eed4bc95 100644 --- a/ext/standard/tests/serialize/__serialize_002.phpt +++ b/ext/standard/tests/serialize/__serialize_002.phpt @@ -17,4 +17,4 @@ try { ?> --EXPECT-- -__serialize() must return an array +Test::__serialize() must return an array diff --git a/ext/standard/tests/serialize/__serialize_006.phpt b/ext/standard/tests/serialize/__serialize_006.phpt new file mode 100644 index 0000000000000..f824787662b25 --- /dev/null +++ b/ext/standard/tests/serialize/__serialize_006.phpt @@ -0,0 +1,17 @@ +--TEST-- +Failure while parsing data array for __unserialize() +--FILE-- + +--EXPECTF-- +Notice: unserialize(): Unexpected end of serialized data in %s on line %d + +Notice: unserialize(): Error at offset 14 of 15 bytes in %s on line %d +bool(false) diff --git a/ext/standard/tests/serialize/bug45706.phpt b/ext/standard/tests/serialize/bug45706.phpt index 218cdcca2d506..12cadfe0fa87f 100644 --- a/ext/standard/tests/serialize/bug45706.phpt +++ b/ext/standard/tests/serialize/bug45706.phpt @@ -13,15 +13,22 @@ $s = str_replace("Foo", "Bar", $s); $y = unserialize($s); var_dump($y); --EXPECTF-- -Warning: Class __PHP_Incomplete_Class has no unserializer in %sbug45706.php on line %d array(2) { [0]=> - object(__PHP_Incomplete_Class)#%d (1) { + object(__PHP_Incomplete_Class)#3 (4) { ["__PHP_Incomplete_Class_Name"]=> string(4) "Bar1" + ["0"]=> + int(0) + ["1"]=> + array(0) { + } + ["2"]=> + array(0) { + } } [1]=> - object(__PHP_Incomplete_Class)#%d (1) { + object(__PHP_Incomplete_Class)#4 (1) { ["__PHP_Incomplete_Class_Name"]=> string(4) "Bar2" } diff --git a/ext/standard/tests/strings/htmlentities01.phpt b/ext/standard/tests/strings/htmlentities01.phpt index 4ab49472d1f38..092027a7a46bb 100644 --- a/ext/standard/tests/strings/htmlentities01.phpt +++ b/ext/standard/tests/strings/htmlentities01.phpt @@ -2,7 +2,7 @@ htmlentities() test 1 (cp1252) --INI-- output_handler= -mbstring.internal_encoding=pass +internal_encoding=pass --FILE-- name)); return FAILURE; } diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index afb992cca4a53..1dadbe5a2914e 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -646,6 +646,7 @@ static inline int object_common(UNSERIALIZE_PARAMETER, zend_long elements, zend_ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL(ary), elements, NULL)) { ZVAL_DEREF(rval); GC_ADD_FLAGS(Z_OBJ_P(rval), IS_OBJ_DESTRUCTOR_CALLED); + zval_ptr_dtor(&ary); return 0; } diff --git a/ext/xml/config.m4 b/ext/xml/config.m4 index 45d0ab421413e..ce18d37f8ee57 100644 --- a/ext/xml/config.m4 +++ b/ext/xml/config.m4 @@ -6,15 +6,6 @@ PHP_ARG_ENABLE([xml], [Disable XML support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [XML: libxml2 install prefix])], - [no], - [no]) -fi - PHP_ARG_WITH([libexpat-dir], [libexpat install dir], [AS_HELP_STRING([--with-libexpat-dir=DIR], @@ -30,14 +21,12 @@ if test "$PHP_XML" != "no"; then if test "$PHP_LIBEXPAT_DIR" = "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([XML extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([XML extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(XML_SHARED_LIBADD, [ xml_extra_sources="compat.c" PHP_ADD_EXTENSION_DEP(xml, libxml) - ], [ - AC_MSG_ERROR([libxml2 not found. Use --with-libxml-dir=]) ]) fi diff --git a/ext/xmlreader/config.m4 b/ext/xmlreader/config.m4 index 5bc768a3b0d7c..616bd9bb8436f 100644 --- a/ext/xmlreader/config.m4 +++ b/ext/xmlreader/config.m4 @@ -6,19 +6,10 @@ PHP_ARG_ENABLE([xmlreader], [Disable XMLReader support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [XMLReader: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_XMLREADER" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([XMLReader extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([XMLReader extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(XMLREADER_SHARED_LIBADD, [ @@ -26,7 +17,5 @@ if test "$PHP_XMLREADER" != "no"; then PHP_NEW_EXTENSION(xmlreader, php_xmlreader.c, $ext_shared) PHP_ADD_EXTENSION_DEP(xmlreader, dom, true) PHP_SUBST(XMLREADER_SHARED_LIBADD) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) fi diff --git a/ext/xmlrpc/config.m4 b/ext/xmlrpc/config.m4 index cf9a3111e7709..f7d8ca45f7fe2 100644 --- a/ext/xmlrpc/config.m4 +++ b/ext/xmlrpc/config.m4 @@ -10,15 +10,6 @@ PHP_ARG_WITH([xmlrpc], [AS_HELP_STRING([[--with-xmlrpc[=DIR]]], [Include XMLRPC-EPI support])]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [XMLRPC-EPI: libxml2 install prefix])], - [no], - [no]) -fi - PHP_ARG_WITH([libexpat-dir], [libexpat dir for XMLRPC-EPI], [AS_HELP_STRING([--with-libexpat-dir=DIR], @@ -45,7 +36,7 @@ if test "$PHP_XMLRPC" != "no"; then if test "$PHP_LIBEXPAT_DIR" = "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([XML-RPC extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([XML-RPC extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(XMLRPC_SHARED_LIBADD, [ @@ -53,8 +44,6 @@ if test "$PHP_XMLRPC" != "no"; then PHP_ADD_SOURCES(ext/xml, compat.c) PHP_ADD_BUILD_DIR(ext/xml) fi - ], [ - AC_MSG_ERROR([libxml2 not found. Use --with-libxml-dir=]) ]) else testval=no diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index 979e46c3f4ef6..7383c911e5956 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -1,5 +1,3 @@ -static const char rcsid[] = "#(@) $Id$"; - /* Encode or decode file as MIME base64 (RFC 1341) diff --git a/ext/xmlrpc/libxmlrpc/encodings.c b/ext/xmlrpc/libxmlrpc/encodings.c index fb75dbb9dc210..d422987e8986f 100644 --- a/ext/xmlrpc/libxmlrpc/encodings.c +++ b/ext/xmlrpc/libxmlrpc/encodings.c @@ -32,8 +32,6 @@ #include -static const char rcsid[] = "#(@) $Id$"; - #include #include diff --git a/ext/xmlrpc/libxmlrpc/queue.c b/ext/xmlrpc/libxmlrpc/queue.c index 961b4ca873dc0..3bc857febc9fe 100644 --- a/ext/xmlrpc/libxmlrpc/queue.c +++ b/ext/xmlrpc/libxmlrpc/queue.c @@ -1,5 +1,3 @@ -static const char rcsid[] = "#(@) $Id$"; - /* * Date last modified: Jan 2001 * Modifications by Dan Libby (dan@libby.com), including: diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index fed6b4387da5b..345ce663cd61b 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -32,8 +32,6 @@ #include -static const char rcsid[] = "#(@) $Id$"; - #define SIMPLESTRING_INCR 32 diff --git a/ext/xmlrpc/libxmlrpc/xml_element.c b/ext/xmlrpc/libxmlrpc/xml_element.c index 86aad6108a3c6..16787593516d4 100644 --- a/ext/xmlrpc/libxmlrpc/xml_element.c +++ b/ext/xmlrpc/libxmlrpc/xml_element.c @@ -31,10 +31,6 @@ */ -static const char rcsid[] = "#(@) $Id$"; - - - /****h* ABOUT/xml_element * NAME * xml_element @@ -331,7 +327,7 @@ static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, X char *NewBuffer; int ToBeXmlEscaped=0; int iLength; - bufcopy = buf; + bufcopy = (const unsigned char *) buf; iLength= old_len ? old_len : strlen(buf); while(*bufcopy) { if( should_escape(*bufcopy, flags) ) { @@ -346,7 +342,7 @@ static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, X NewBuffer= emalloc(iLength+1); if(NewBuffer) { - bufcopy=buf; + bufcopy = (const unsigned char *) buf; while(*bufcopy) { if(should_escape(*bufcopy, flags)) { iNewBufLen += create_xml_escape(NewBuffer+iNewBufLen,*bufcopy); @@ -713,13 +709,13 @@ xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTI } /* parse the XML */ - if(XML_Parse(parser, in_buf, len, 1) == 0) { + if(XML_Parse(parser, (const unsigned char *) in_buf, len, 1) == 0) { enum XML_Error err_code = XML_GetErrorCode(parser); int line_num = XML_GetCurrentLineNumber(parser); int col_num = XML_GetCurrentColumnNumber(parser); long byte_idx = XML_GetCurrentByteIndex(parser); /* int byte_total = XML_GetCurrentByteCount(parser); */ - const char * error_str = XML_ErrorString(err_code); + const char * error_str = (const char *) XML_ErrorString(err_code); if(byte_idx > len) { byte_idx = len; } diff --git a/ext/xmlrpc/libxmlrpc/xml_to_soap.c b/ext/xmlrpc/libxmlrpc/xml_to_soap.c index cd0933fcbc4fc..de8520f32b0d5 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_soap.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_soap.c @@ -21,8 +21,6 @@ ************************************************************************/ -static const char rcsid[] = "#(@) $Id:"; - #include #include #include "xml_to_soap.h" diff --git a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c index 860cba3e36c23..ad62196640b66 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c @@ -31,8 +31,6 @@ */ -static const char rcsid[] = "#(@) $Id$"; - #include "php.h" #include "main/snprintf.h" #include diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c index 7a7d9c833c731..07fec0c69848a 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c @@ -31,9 +31,6 @@ */ -static const char rcsid[] = "#(@) $Id$"; - - /****h* ABOUT/xmlrpc * NAME * XMLRPC_VALUE diff --git a/ext/xmlwriter/config.m4 b/ext/xmlwriter/config.m4 index c3381db741a47..54204f1280e37 100644 --- a/ext/xmlwriter/config.m4 +++ b/ext/xmlwriter/config.m4 @@ -6,26 +6,15 @@ PHP_ARG_ENABLE([xmlwriter], [Disable XMLWriter support])], [yes]) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH([libxml-dir], - [libxml2 install dir], - [AS_HELP_STRING([--with-libxml-dir=DIR], - [XMLWriter: libxml2 install prefix])], - [no], - [no]) -fi - if test "$PHP_XMLWRITER" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([XMLWriter extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([XMLWriter extension requires LIBXML extension, add --with-libxml]) fi PHP_SETUP_LIBXML(XMLWRITER_SHARED_LIBADD, [ AC_DEFINE(HAVE_XMLWRITER,1,[ ]) PHP_NEW_EXTENSION(xmlwriter, php_xmlwriter.c, $ext_shared) PHP_SUBST(XMLWRITER_SHARED_LIBADD) - ], [ - AC_MSG_ERROR([libxml2 not found. Please check your libxml2 installation.]) ]) fi diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4 index 733ff89d17b25..5109d628959fa 100644 --- a/ext/xsl/config.m4 +++ b/ext/xsl/config.m4 @@ -9,7 +9,7 @@ PHP_ARG_WITH([xsl], if test "$PHP_XSL" != "no"; then if test "$PHP_LIBXML" = "no"; then - AC_MSG_ERROR([XSL extension requires LIBXML extension, add --enable-libxml]) + AC_MSG_ERROR([XSL extension requires LIBXML extension, add --with-libxml]) fi if test "$PHP_DOM" = "no"; then diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index d71460efcfbb0..18443f9efa8fb 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -174,7 +174,7 @@ static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params) static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { xsltTransformContextPtr tctxt; - zval *args; + zval *args = NULL; zval retval; int result, i; int error = 0; diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 02b8b6c49e0ad..abf901da1fcd5 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -28,11 +28,7 @@ #include "ext/standard/php_string.h" #include "ext/pcre/php_pcre.h" #include "ext/standard/php_filestat.h" -#if PHP_VERSION_ID >= 70200 #include "zend_interfaces.h" -#elif defined(HAVE_SPL) -#include "ext/spl/spl_iterators.h" -#endif #include "php_zip.h" /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */ @@ -3017,11 +3013,7 @@ static PHP_MINIT_FUNCTION(zip) php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG); php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING); php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING); -#if PHP_VERSION_ID >= 70200 zend_class_implements(zip_class_entry, 1, zend_ce_countable); -#elif defined(HAVE_SPL) - zend_class_implements(zip_class_entry, 1, spl_ce_Countable); -#endif REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE); REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL); diff --git a/ext/zlib/tests/gzfile_variation15.phpt b/ext/zlib/tests/gzfile_variation15.phpt index 153f56715bc57..866348efa0e93 100644 --- a/ext/zlib/tests/gzfile_variation15.phpt +++ b/ext/zlib/tests/gzfile_variation15.phpt @@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) { ?> --FILE-- --FILE-- d_name[0] = '\0'; - readdir_r(dirp, entry); - - if (entry->d_name[0] == '\0') { - *result = NULL; - ret = errno; - } else { - *result = entry; - } - return ret; -#else - struct dirent *ptr; - int ret = 0; - - local_lock(READDIR_R); - - errno = 0; - - ptr = readdir(dirp); - - if (!ptr && errno != 0) - ret = errno; - - if (ptr) - memcpy(entry, ptr, sizeof(*ptr)); - - *result = ptr; - - local_unlock(READDIR_R); - - return ret; -#endif -} - -#endif - #if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME) PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index dc74bfccc1729..1bfb2129dc4d8 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -926,16 +926,15 @@ PHPAPI php_stream_ops php_stream_stdio_ops = { static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count) { DIR *dir = (DIR*)stream->abstract; - /* avoid libc5 readdir problems */ - char entry[sizeof(struct dirent)+MAXPATHLEN]; - struct dirent *result = (struct dirent *)&entry; + struct dirent *result; php_stream_dirent *ent = (php_stream_dirent*)buf; /* avoid problems if someone mis-uses the stream */ if (count != sizeof(php_stream_dirent)) return 0; - if (php_readdir_r(dir, (struct dirent *)entry, &result) == 0 && result) { + result = readdir(dir); + if (result) { PHP_STRLCPY(ent->d_name, result->d_name, sizeof(ent->d_name), strlen(result->d_name)); return sizeof(php_stream_dirent); } diff --git a/php.ini-development b/php.ini-development index 5883743e53fa5..1ba130de34907 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1186,11 +1186,11 @@ mysqli.default_port = 3306 ; http://php.net/mysqli.default-socket mysqli.default_socket = -; Default host for mysql_connect() (doesn't apply in safe mode). +; Default host for mysqli_connect() (doesn't apply in safe mode). ; http://php.net/mysqli.default-host mysqli.default_host = -; Default user for mysql_connect() (doesn't apply in safe mode). +; Default user for mysqli_connect() (doesn't apply in safe mode). ; http://php.net/mysqli.default-user mysqli.default_user = diff --git a/php.ini-production b/php.ini-production index 5ae76c810a0d6..c900e0544877e 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1193,11 +1193,11 @@ mysqli.default_port = 3306 ; http://php.net/mysqli.default-socket mysqli.default_socket = -; Default host for mysql_connect() (doesn't apply in safe mode). +; Default host for mysqli_connect() (doesn't apply in safe mode). ; http://php.net/mysqli.default-host mysqli.default_host = -; Default user for mysql_connect() (doesn't apply in safe mode). +; Default user for mysqli_connect() (doesn't apply in safe mode). ; http://php.net/mysqli.default-user mysqli.default_user = diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 46ba86e9c2bda..6889278bcac70 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -1448,6 +1448,7 @@ static void normalize_vpath(char **retval, size_t *retval_len, const char *vpath char *p; *retval = NULL; + *retval_len = 0; decoded_vpath = pestrndup(vpath, vpath_len, persistent); if (!decoded_vpath) { diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index 3174eef2fbe12..cfdcf6509457b 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -99,9 +99,9 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * return -1; } - if (ZEND_CALL_KIND_EX((*call_info) >> ZEND_CALL_INFO_SHIFT) == ZEND_CALL_TOP_CODE) { + if (ZEND_CALL_KIND_EX(*call_info) == ZEND_CALL_TOP_CODE) { return 0; - } else if (ZEND_CALL_KIND_EX(*(call_info) >> ZEND_CALL_INFO_SHIFT) == ZEND_CALL_NESTED_CODE) { + } else if (ZEND_CALL_KIND_EX(*call_info) == ZEND_CALL_NESTED_CODE) { memcpy(buf, "[INCLUDE_OR_EVAL]", sizeof("[INCLUDE_OR_EVAL]")); } else { ZEND_ASSERT(0); diff --git a/sapi/fpm/status.html.in b/sapi/fpm/status.html.in index 863fcf3b54e99..d3b6d5efd3e59 100644 --- a/sapi/fpm/status.html.in +++ b/sapi/fpm/status.html.in @@ -40,7 +40,7 @@
- PHP Logo

PHP-FPM real-time status page

+ PHP Logo

PHP-FPM real-time status page

diff --git a/sapi/litespeed/README.md b/sapi/litespeed/README.md index 3f5b7ad14f846..e98a940b3df7b 100644 --- a/sapi/litespeed/README.md +++ b/sapi/litespeed/README.md @@ -1,221 +1,204 @@ -Introduction -============ +# Introduction LiteSpeed SAPI module is a dedicated interface for PHP integration with -LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the -FastCGI SAPI with there major enhancements: better performance, dynamic -spawning and PHP configuration modification through web server -configuration and .htaccess files. +LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the FastCGI +SAPI with there major enhancements: better performance, dynamic spawning and PHP +configuration modification through web server configuration and `.htaccess` +files. -Our simple benchmark test ("hello world") shows that PHP with -LiteSpeed SAPI has 30% better performance over PHP with FastCGI SAPI, -which is nearly twice the performance that Apache mod_php can deliver. +A simple benchmark test ("hello world") shows that PHP with LiteSpeed SAPI has +30% better performance over PHP with FastCGI SAPI, which is nearly twice the +performance that Apache mod_php can deliver. -A major drawback of FastCGI PHP comparing to Apache mod_php is lacking -the flexibilities in PHP configurations. PHP configurations cannot be -changed at runtime via configuration files like .htaccess files or web -server's virtual host configuration. In shared hosting environment, -each hosting account will has its own "open_basedir" overridden in -server configuration to enhance server security when mod_php is used. -usually, FastCGI PHP is not an option in shared hosting environment -due to lacking of this flexibility. LiteSpeed SAPI is carefully designed -to address this issue. PHP configurations can be modified the same way -as that in mod_php with the same configuration directives. +A major drawback of FastCGI PHP comparing to Apache mod_php is lacking the +flexibilities in PHP configurations. PHP configurations cannot be changed at +runtime via configuration files like `.htaccess` files or web server's virtual +host configuration. In shared hosting environment, each hosting account will has +its own `open_basedir` overridden in server configuration to enhance server +security when mod_php is used. Usually, FastCGI PHP is not an option in shared +hosting environment due to lacking of this flexibility. LiteSpeed SAPI is +carefully designed to address this issue. PHP configurations can be modified the +same way as that in mod_php with the same configuration directives. -PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for -PHP scripting with LiteSpeed web server. +PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for PHP scripting +with LiteSpeed web server. +## Building PHP with LiteSpeed SAPI -Building PHP with LiteSpeed SAPI -================================ - -You need to add "--with-litespeed" to the configure command to build -PHP with LiteSpeed SAPI, all other SAPI related configure options -should be removed. +You need to add `--with-litespeed` to the configure command to build PHP with +LiteSpeed SAPI, all other SAPI related configure options should be removed. For example: - ./configure --with-litespeed - make -You should find an executable called 'php' under sapi/litespeed/ -directory after the compilation succeeds. Copy it to -'lsws/fcgi-bin/lsphp' or wherever you prefer, if LiteSpeed web server -has been configured to run PHP with LiteSpeed SAPI already, you just -need to overwrite the old executable with this one and you are all -set. +```bash +./configure --with-litespeed +make +``` -Start PHP from command line -=========================== +You should find an executable called `lsphp` under `sapi/litespeed/` directory +after the compilation succeeds. Copy it to `lsws/fcgi-bin/lsphp` or wherever you +prefer, if LiteSpeed web server has been configured to run PHP with LiteSpeed +SAPI already, you just need to overwrite the old executable with this one and +you are all set. -Usually, lsphp is managed by LiteSpeed web server in a single server -installation. lsphp can be used in clustered environment with one -LiteSpeed web server at the front, load balancing lsphp processes -running on multiple backend servers. In such environment, lsphp can be -start manually from command with option "-b ", socket -address can be IPv4, IPv6 or Unix Domain Socket address. -for example: +## Start PHP from command line - ./lsphp -b [::]:3000 +Usually, `lsphp` is managed by LiteSpeed web server in a single server +installation. lsphp can be used in clustered environment with one LiteSpeed web +server at the front, load balancing lsphp processes running on multiple backend +servers. In such environment, lsphp can be start manually from command with +option `-b `, socket address can be IPv4, IPv6 or Unix Domain +Socket address. -have lsphp bind to port 3000 on all IPv4 and IPv6 address, +For example: - ./lsphp -b *:3000 +```bash +./lsphp -b [::]:3000 +``` -have lsphp bind to port 300 on all IPv4 address. +have lsphp bind to port 3000 on all IPv4 and IPv6 address, - ./lsphp -b 192.168.0.2:3000 +```bash +./lsphp -b *:3000 +``` -have lsphp bind to address 192.168.0.2:3000. +have lsphp bind to port 300 on all IPv4 address, - ./lsphp -b /tmp/lsphp_manual.sock +```bash +./lsphp -b 192.168.0.2:3000 +``` -have lsphp accept request on Unix domain socket "/tmp/lsphp_manual.sock" +have lsphp bind to address 192.168.0.2:3000, +```bash +./lsphp -b /tmp/lsphp_manual.sock +``` -Using LiteSpeed PHP with LiteSpeed Web Server -============================================= +have lsphp accept request on Unix domain socket `/tmp/lsphp_manual.sock`. -Detailed information about how to configure LiteSpeed web server with -PHP support is available from our website, at: +## Using LiteSpeed PHP with LiteSpeed Web Server -https://www.litespeedtech.com/docs/webserver +Detailed information about how to configure LiteSpeed web server with PHP +support is available from +[LiteSpeed website](https://www.litespeedtech.com/docs/webserver). -Usually, PHP support has been configured out of box, you don't need to -change it unless you want to change PHP interface from FastCGI to -LiteSpeed SAPI or vice versa. +Usually, PHP support has been configured out of box, you don't need to change it +unless you want to change PHP interface from FastCGI to LiteSpeed SAPI or vice +versa. Brief instructions are as follow: -1) Login to web administration interface, go to 'Server'->'Ext App' tab, - add an external application of type "LSAPI app", "Command" should be - set to a shell command that executes the PHP binary you just built. - "Instances" should be set to "1". Add "LSAPI_CHILDREN" environment - variable to match the value of "Max Connections". More tunable - environment variable described below can be added. +1. Login to web administration interface, go to 'Server'->'Ext App' tab, add an + external application of type "LSAPI app", "Command" should be set to a shell + command that executes the PHP binary you just built. "Instances" should be + set to "1". Add "LSAPI_CHILDREN" environment variable to match the value of + "Max Connections". More tunable environment variable described below can be + added. -2) Go to 'Server'->'Script Handler' tab, add a script handler - configuration: set 'suffix' to 'php', 'Handler Type' to 'LiteSpeed - API', 'Handler Name' should be the name of external application - just defined. +2. Go to 'Server'->'Script Handler' tab, add a script handler configuration: set + 'suffix' to 'php', 'Handler Type' to 'LiteSpeed API', 'Handler Name' should + be the name of external application just defined. - -3) Click 'Apply Changes' link on the top left of the page, then click +3. Click 'Apply Changes' link on the top left of the page, then click 'graceful restart'. Now PHP is running with LiteSpeed SAPI. -Tunings -------- +## Tunings There are a few environment variables that can be tweaked to control the behavior of LSAPI application. -* LSAPI_CHILDREN or PHP_LSAPI_CHILDREN (default: 0) - -There are two ways to let PHP handle multiple requests concurrently, -Server Managed Mode and Self Managed Mode. In Server Managed Mode, -LiteSpeed web server dynamically spawn/stop PHP processes, in this mode -"Instances" should match "Max Connections" configuration for PHP -external application. To start PHP in Self Managed Mode, "Instances" -should be set to "1", while "LSAPI_CHILDREN" environment variable should -be set to match the value of "Max Connections" and >1. Web Server will -start one PHP process, this process will start/stop children PHP processes -dynamically based on on demand. If "LSAPI_CHILDREN" <=1, PHP will be -started in server managed mode. - -Self Managed Mode is preferred because all PHP processes can share one -shared memory block for the opcode cache. - -Usually, there is no need to set value of LSAPI_CHILDREN over 100 in -most server environment. +* `LSAPI_CHILDREN` or `PHP_LSAPI_CHILDREN` (default: 0) + There are two ways to let PHP handle multiple requests concurrently, Server + Managed Mode and Self Managed Mode. In Server Managed Mode, LiteSpeed web + server dynamically spawn/stop PHP processes, in this mode "Instances" should + match "Max Connections" configuration for PHP external application. To start + PHP in Self Managed Mode, "Instances" should be set to "1", while + `LSAPI_CHILDREN` environment variable should be set to match the value of "Max + Connections" and greater than 1. Web Server will start one PHP process, this + process will start/stop children PHP processes dynamically based on on demand. + If `LSAPI_CHILDREN` less or equal to 1, PHP will be started in server managed + mode. -* LSAPI_AVOID_FORK (default: 0) + Self Managed Mode is preferred because all PHP processes can share one shared + memory block for the opcode cache. -LSAPI_AVOID_FORK specifies the policy of the internal process manager in -"Self Managed Mode". When set to 0, the internal process manager will stop -and start children process on demand to save system resource. This is -preferred in a shared hosting environment. When set to 1, the internal -process manager will try to avoid freqently stopping and starting children -process. This might be preferred in a dedicate hosting environment. + Usually, there is no need to set value of `LSAPI_CHILDREN` over 100 in most + server environments. +* `LSAPI_AVOID_FORK` (default: 0) -* LSAPI_EXTRA_CHILDREN (default: 1/3 of LSAPI_CHILDREN or 0) + `LSAPI_AVOID_FORK` specifies the policy of the internal process manager in + "Self Managed Mode". When set to 0, the internal process manager will stop and + start children process on demand to save system resource. This is preferred in + a shared hosting environment. When set to 1, the internal process manager will + try to avoid freqently stopping and starting children process. This might be + preferred in a dedicate hosting environment. -LSAPI_EXTRA_CHILDREN controls the maximum number of extra children processes -can be started when some or all existing children processes are in -malfunctioning state. Total number of children processes will be reduced to -LSAPI_CHILDREN level as soon as service is back to normal. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value is 0. +* `LSAPI_EXTRA_CHILDREN` (default: 1/3 of `LSAPI_CHILDREN` or 0) + `LSAPI_EXTRA_CHILDREN` controls the maximum number of extra children processes + can be started when some or all existing children processes are in + malfunctioning state. Total number of children processes will be reduced to + `LSAPI_CHILDREN` level as soon as service is back to normal. When + `LSAPI_AVOID_FORK` is set to 0, the default value is 1/3 of `LSAPI_CHILDREN`, + When `LSAPI_AVOID_FORK` is set to 1, the default value is 0. -* LSAPI_MAX_REQS or PHP_LSAPI_MAX_REQUESTS (default value: 10000) +* `LSAPI_MAX_REQS` or `PHP_LSAPI_MAX_REQUESTS` (default value: 10000) -This controls how many requests each child process will handle before -it exits automatically. Several PHP functions have been identified -having memory leaks. This parameter can help reducing memory usage -of leaky PHP functions. + This controls how many requests each child process will handle before it exits + automatically. Several PHP functions have been identified having memory leaks. + This parameter can help reducing memory usage of leaky PHP functions. +* `LSAPI_MAX_IDLE` (default value: 300 seconds) -* LSAPI_MAX_IDLE (default value: 300 seconds) + In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child process + will wait for a new request before it exits. This option help releasing system + resources taken by idle processes. -In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child -process will wait for a new request before it exits. This option help -releasing system resources taken by idle processes. +* `LSAPI_MAX_IDLE_CHILDREN` (default value: 1/3 of `LSAPI_CHILDREN` or + `LSAPI_CHILDREN`) + In Self Managed Mode, `LSAI_MAX_IDLE_CHILDREN` controls how many idle children + processes are allowed. Excessive idle children processes will be killed by the + parent process immediately. When `LSAPI_AVOID_FORK` is set to 0, the default + value is 1/3 of `LSAPI_CHIDLREN`, When `LSAPI_AVOID_FORK` is set to 1, the + default value is `LSAPI_CHILDREN`. -* LSAPI_MAX_IDLE_CHILDREN - (default value: 1/3 of LSAPI_CHILDREN or LSAPI_CHILDREN) +* `LSAPI_MAX_PROCESS_TIME` (default value: 300 seconds) -In Self Managed Mode, LSAI_MAX_IDLE_CHILDREN controls how many idle -children processes are allowed. Excessive idle children processes -will be killed by the parent process immediately. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value -is LSAPI_CHILDREN. + In Self Managed Mode, `LSAPI_MAX_PROCESS_TIME` controls the maximum processing + time allowed when processing a request. If a child process can not finish + processing of a request in the given time period, it will be killed by the + parent process. This option can help getting rid of dead or runaway child + process. +* `LSAPI_PGRP_MAX_IDLE` (default value: FOREVER) -* LSAPI_MAX_PROCESS_TIME (default value: 300 seconds) + In Self Managed Mode, `LSAPI_PGRP_MAX_IDLE` controls how long the parent + process will wait before exiting when there is no child process. This option + helps releasing system resources taken by an idle parent process. -In Self Managed Mode, LSAPI_MAX_PROCESS_TIME controls the maximum -processing time allowed when processing a request. If a child process -can not finish processing of a request in the given time period, it -will be killed by the parent process. This option can help getting rid -of dead or runaway child process. +* `LSAPI_PPID_NO_CHECK` + By default a LSAPI application check the existence of its parent process and + exits automatically if the parent process died. This is to reduce orphan + process when web server is restarted. However, it is desirable to disable this + feature, such as when a LSAPI process was started manually from command line. + `LSAPI_PPID_NO_CHECK` should be set when you want to disable the checking of + existence of parent process. When PHP is started by `-b` option, it is + disabled automatically. -* LSAPI_PGRP_MAX_IDLE (default value: FOREVER ) - -In Self Managed Mode, LSAPI_PGRP_MAX_IDLE controls how long the parent -process will wait before exiting when there is no child process. -This option help releasing system resources taken by an idle parent -process. - - -* LSAPI_PPID_NO_CHECK - -By default a LSAPI application check the existence of its parent process -and exits automatically if the parent process died. This is to reduce -orphan process when web server is restarted. However, it is desirable -to disable this feature, such as when a LSAPI process was started -manually from command line. LSAPI_PPID_NO_CHECK should be set when -you want to disable the checking of existence of parent process. -When PHP started by "-b" option, it is disabled automatically. - - -Compatibility with Apache mod_php -================================= +## Compatibility with Apache mod_php LSAPI PHP supports PHP configuration overridden via web server configuration -as well as .htaccess. -Since 4.0 release "apache_response_headers" function is supported. - - +as well as `.htaccess`. -Contact -======= +Since 4.0 release `apache_response_headers` function is supported. -For support questions, please post to our free support forum, at: +## Contact -https://www.litespeedtech.com/support/forum/ +For support questions, please post to the free support +[forum](https://www.litespeedtech.com/support/forum/): For bug report, please send bug report to bug [at] litespeedtech.com. diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 4a6b1a0f3f91d..66f973ada81e5 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -448,7 +448,7 @@ static int sapi_lsapi_activate() static sapi_module_struct lsapi_sapi_module = { "litespeed", - "LiteSpeed V7.2", + "LiteSpeed V7.3", php_lsapi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ @@ -1368,6 +1368,7 @@ ZEND_END_ARG_INFO() PHP_FUNCTION(litespeed_request_headers); PHP_FUNCTION(litespeed_response_headers); PHP_FUNCTION(apache_get_modules); +PHP_FUNCTION(litespeed_finish_request); PHP_MINFO_FUNCTION(litespeed); @@ -1375,9 +1376,11 @@ static const zend_function_entry litespeed_functions[] = { PHP_FE(litespeed_request_headers, arginfo_litespeed__void) PHP_FE(litespeed_response_headers, arginfo_litespeed__void) PHP_FE(apache_get_modules, arginfo_litespeed__void) + PHP_FE(litespeed_finish_request, arginfo_litespeed__void) PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) + PHP_FALIAS(fastcgi_finish_request, litespeed_finish_request, arginfo_litespeed__void) {NULL, NULL, NULL} }; @@ -1504,3 +1507,18 @@ PHP_FUNCTION(apache_get_modules) } } /* }}} */ + + +/* {{{ proto array litespeed_finish_request(void) + Flushes all response data to the client */ +PHP_FUNCTION(litespeed_finish_request) +{ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + if (LSAPI_End_Response() != -1) { + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index c5ae5aff05d38..00d5592623095 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include #include @@ -115,10 +116,18 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX; #define LSAPI_ST_REQ_BODY 2 #define LSAPI_ST_RESP_HEADER 4 #define LSAPI_ST_RESP_BODY 8 +#define LSAPI_ST_BACKGROUND 16 #define LSAPI_RESP_BUF_SIZE 8192 #define LSAPI_INIT_RESP_HEADER_LEN 4096 +enum +{ + LSAPI_STATE_IDLE, + LSAPI_STATE_CONNECTED, + LSAPI_STATE_ACCEPTING, +}; + typedef struct _lsapi_child_status { int m_pid; @@ -126,7 +135,7 @@ typedef struct _lsapi_child_status volatile short m_iKillSent; volatile char m_inProcess; - volatile char m_connected; + volatile char m_state; volatile int m_iReqCounter; volatile long m_tmWaitBegin; @@ -158,6 +167,9 @@ static int s_max_busy_workers = -1; static char *s_stderr_log_path = NULL; static int s_stderr_is_pipe = 0; static int s_ignore_pid = -1; +static size_t s_total_pages = 1; +static size_t s_min_avail_pages = 256 * 1024; +static size_t *s_avail_pages = &s_total_pages; LSAPI_Request g_req = { .m_fdListen = -1, .m_fd = -1 }; @@ -417,7 +429,7 @@ static void lsapi_close_connection(LSAPI_Request *pReq) if (s_busy_workers) __sync_fetch_and_sub(s_busy_workers, 1); if (s_worker_status) - s_worker_status->m_connected = 0; + __sync_lock_test_and_set(&s_worker_status->m_state, LSAPI_STATE_IDLE); } @@ -1560,7 +1572,8 @@ int LSAPI_Accept_r( LSAPI_Request * pReq ) else { if (s_worker_status) - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_fetch_and_add(s_busy_workers, 1); lsapi_set_nblock( pReq->m_fd , 0 ); @@ -1623,6 +1636,37 @@ int LSAPI_Finish_r( LSAPI_Request * pReq ) } +int LSAPI_End_Response_r(LSAPI_Request * pReq) +{ + if (!pReq) + return -1; + if (pReq->m_reqState) + { + if ( pReq->m_fd != -1 ) + { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); + } + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { + Flush_RespBuf_r( pReq ); + } + + pReq->m_pIovecCur->iov_base = (void *)&finish; + pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; + pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN; + ++pReq->m_pIovecCur; + LSAPI_Flush_r( pReq ); + } + send_conn_close_notification(pReq->m_fd); + lsapi_close_connection(pReq); + pReq->m_reqState |= LSAPI_ST_BACKGROUND; + } + return 0; +} + + void LSAPI_Reset_r( LSAPI_Request * pReq ) { pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -1808,7 +1852,11 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) ssize_t packetLen; int skip = 0; - if ( !pReq || !pBuf || (pReq->m_fd == -1) ) + if (!pReq || !pBuf) + return -1; + if (pReq->m_reqState & LSAPI_ST_BACKGROUND) + return len; + if (pReq->m_fd == -1) return -1; if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { @@ -2710,6 +2758,9 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ) s_ppid = getppid(); s_pid = getpid(); setpgid( s_pid, s_pid ); +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + s_total_pages = sysconf(_SC_PHYS_PAGES); +#endif g_prefork_server->m_iAvoidFork = avoidFork; g_prefork_server->m_iMaxChildren = max_children; @@ -2844,11 +2895,19 @@ static void lsapi_sigchild( int signal ) child_status = find_child_status( pid ); if ( child_status ) { - if (child_status->m_connected) + if (__sync_bool_compare_and_swap(&child_status->m_state, + LSAPI_STATE_CONNECTED, + LSAPI_STATE_IDLE)) { if (s_busy_workers) __sync_fetch_and_sub(s_busy_workers, 1); - child_status->m_connected = 0; + } + else if (__sync_bool_compare_and_swap(&child_status->m_state, + LSAPI_STATE_ACCEPTING, + LSAPI_STATE_IDLE)) + { + if (s_accepting_workers) + __sync_fetch_and_sub(s_accepting_workers, 1); } child_status->m_pid = 0; --g_prefork_server->m_iCurChildren; @@ -2884,6 +2943,7 @@ static int lsapi_init_children_status(void) s_busy_workers = (int *)g_prefork_server->m_pChildrenStatusEnd; s_accepting_workers = s_busy_workers + 1; s_global_counter = s_accepting_workers + 1; + s_avail_pages = (size_t *)(s_global_counter + 1); return 0; } @@ -3023,6 +3083,17 @@ void set_skip_write() { s_skip_write = 1; } +int is_enough_free_mem() +{ +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + //minimum 1GB or 10% available free memory + return (*s_avail_pages > s_min_avail_pages + || (*s_avail_pages * 10) / s_total_pages > 0); +#endif + return 1; +} + + static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq ) { @@ -3092,6 +3163,12 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, } } +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + *s_avail_pages = sysconf(_SC_AVPHYS_PAGES); + lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n", + s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages); + +#endif FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 1; @@ -3099,11 +3176,15 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout); if (ret == 1 ) { - if (pServer->m_iCurChildren >= pServer->m_iMaxChildren - && s_accepting_workers - && (ret = __sync_add_and_fetch(s_accepting_workers, 0)) > 0) + int accepting = 0; + if (s_accepting_workers) + accepting = __sync_add_and_fetch(s_accepting_workers, 0); + + if (pServer->m_iCurChildren > 0 && accepting > 0) { - usleep( 200 ); + usleep(400); + while(accepting-- > 0) + sched_yield(); continue; } } @@ -3164,14 +3245,17 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, if (pthread_atfork_func) (*pthread_atfork_func)(NULL, NULL, set_skip_write); - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_add_and_fetch(s_busy_workers, 1); lsapi_set_nblock( pReq->m_fd, 0 ); //keep it open if busy_count is used. - if (s_busy_workers && s_uid != 0) + if (s_busy_workers + && *s_busy_workers > (pServer->m_iMaxChildren >> 1)) s_keepListener = 1; - else if ( pReq->m_fdListen != -1 ) + if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem()) + && pReq->m_fdListen != -1 ) { close( pReq->m_fdListen ); pReq->m_fdListen = -1; @@ -3297,6 +3381,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) timeout.tv_usec = 0; if (fd == pReq->m_fdListen) { + if (s_worker_status) + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_ACCEPTING); if (s_accepting_workers) __sync_fetch_and_add(s_accepting_workers, 1); } @@ -3305,6 +3392,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) { if (s_accepting_workers) __sync_fetch_and_sub(s_accepting_workers, 1); + if (s_worker_status) + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_IDLE); } if ( ret == 0 ) @@ -3312,7 +3402,8 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) if ( s_worker_status ) { s_worker_status->m_inProcess = 0; - if (fd == pReq->m_fdListen) + if (fd == pReq->m_fdListen + && (s_keepListener != 2 || !is_enough_free_mem())) return -1; } ++wait_secs; @@ -3339,7 +3430,8 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) if ( pReq->m_fd != -1 ) { if (s_worker_status) - s_worker_status->m_connected = 1; + __sync_lock_test_and_set(&s_worker_status->m_state, + LSAPI_STATE_CONNECTED); if (s_busy_workers) __sync_fetch_and_add(s_busy_workers, 1); @@ -3347,7 +3439,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) lsapi_set_nblock( fd, 0 ); //init_conn_key( pReq->m_fd ); - if ( !s_keepListener ) + if (!s_keepListener) { close( pReq->m_fdListen ); pReq->m_fdListen = -1; @@ -3613,6 +3705,7 @@ static int lsapi_reopen_stderr(const char *p) int LSAPI_Init_Env_Parameters( fn_select_t fp ) { const char *p; + char ch; int n; int avoidFork = 0; @@ -3634,10 +3727,28 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) LSAPI_Set_Max_Reqs( n ); } + p = getenv( "LSAPI_KEEP_LISTEN" ); + if ( p ) + { + n = atoi( p ); + s_keepListener = n; + } + p = getenv( "LSAPI_AVOID_FORK" ); if ( p ) { avoidFork = atoi( p ); + if (avoidFork) + { + s_keepListener = 2; + ch = *(p + strlen(p) - 1); + if ( ch == 'G' || ch == 'g' ) + avoidFork *= 1024 * 1024 * 1024; + else if ( ch == 'M' || ch == 'm' ) + avoidFork *= 1024 * 1024; + if (avoidFork >= 1024 * 10240) + s_min_avail_pages = avoidFork / 4096; + } } p = getenv( "LSAPI_ACCEPT_NOTIFY" ); @@ -3672,14 +3783,6 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) LSAPI_Set_Max_Idle( n ); } - p = getenv( "LSAPI_KEEP_LISTEN" ); - if ( p ) - { - n = atoi( p ); - s_keepListener = n; - } - - if ( LSAPI_Is_Listen() ) { n = 0; @@ -3690,7 +3793,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp ) n = atoi( p ); if ( n > 1 ) { - LSAPI_Init_Prefork_Server( n, fp, avoidFork ); + LSAPI_Init_Prefork_Server( n, fp, avoidFork != 0 ); LSAPI_Set_Server_fd( g_req.m_fdListen ); } diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h index a10fe457b71c3..07dbfb0ade7d1 100644 --- a/sapi/litespeed/lsapilib.h +++ b/sapi/litespeed/lsapilib.h @@ -265,6 +265,9 @@ static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) } +int LSAPI_End_Response_r(LSAPI_Request * pReq); + + int LSAPI_Is_Listen(void); @@ -348,6 +351,9 @@ static inline int LSAPI_SetRespStatus( int code ) static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen ) { return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); } +static inline int LSAPI_End_Response(void) +{ return LSAPI_End_Response_r( &g_req ); } + int LSAPI_IsRunning(void); int LSAPI_CreateListenSock( const char * pBind, int backlog ); diff --git a/sapi/phpdbg/README.md b/sapi/phpdbg/README.md index 6eccb512de9b3..68d9766f0aa4f 100644 --- a/sapi/phpdbg/README.md +++ b/sapi/phpdbg/README.md @@ -1,81 +1,78 @@ -The interactive PHP debugger -============================ +# The interactive PHP debugger -Implemented as a SAPI module, phpdbg can exert complete control over the environment without impacting the functionality or performance of your code. +Implemented as a SAPI module, phpdbg can exert complete control over the +environment without impacting the functionality or performance of your code. -phpdbg aims to be a lightweight, powerful, easy to use debugging platform for PHP 5.4+ +phpdbg aims to be a lightweight, powerful, easy to use debugging platform for +PHP 5.4+. -Features -======== +## Features - - Stepthrough Debugging - - Flexible Breakpoints (Class Method, Function, File:Line, Address, Opcode) - - Easy Access to PHP with built-in eval() - - Easy Access to Currently Executing Code - - Userland API - - SAPI Agnostic - Easily Integrated - - PHP Configuration File Support - - JIT Super Globals - Set Your Own!! - - Optional readline Support - Comfortable Terminal Operation - - Remote Debugging Support - Bundled Java GUI - - Easy Operation - See Help :) +* Stepthrough Debugging +* Flexible Breakpoints (Class Method, Function, File:Line, Address, Opcode) +* Easy Access to PHP with built-in eval() +* Easy Access to Currently Executing Code +* Userland API +* SAPI Agnostic - Easily Integrated +* PHP Configuration File Support +* JIT Super Globals - Set Your Own!! +* Optional readline Support - Comfortable Terminal Operation +* Remote Debugging Support - Bundled Java GUI +* Easy Operation - See Help -Planned -======= +## Planned - - Improve Everything :) +* Improve Everything :) -Installation -============ +## Installation -To install **phpdbg**, you must compile the source against your PHP installation sources, and enable the SAPI with the configure command. +To install **phpdbg**, you must compile the source against your PHP installation +sources, and enable the SAPI with the configure command. It is enabled by +default: -``` -cd /usr/src/php-src/sapi -git clone https://github.com/krakjoe/phpdbg -cd ../ +```bash +cd /path/to/php-src ./buildconf --force -./configure --enable-phpdbg +./configure make -j8 -make install-phpdbg +./sapi/phpdbg/phpdbg --version ``` -Where the source directory has been used previously to build PHP, there exists a file named *config.nice* which can be used to invoke configure with the same -parameters as were used by the last execution of *configure*. +Where the source directory has been used previously to build PHP, there exists a +file named `config.nice` which can be used to invoke configure with the same +parameters as were used by the last execution of `configure`. -**Note:** PHP must be configured with the switch --with-readline for phpdbg to support history, autocompletion, tab-listing etc. +**Note:** PHP must be configured with the switch `--with-readline` for phpdbg to +support history, autocompletion, tab-listing etc. -Command Line Options -==================== +## Command line options The following switches are implemented (just like cli SAPI): - - -n ignore php ini - - -c search for php ini in path - - -z load zend extension - - -d define php ini entry +* `-n` ignore php ini +* `-c` search for php ini in path +* `-z` load zend extension +* `-d` define php ini entry The following switches change the default behaviour of phpdbg: - - -v disables quietness - - -s enabled stepping - - -e sets execution context - - -b boring - disables use of colour on the console - - -I ignore .phpdbginit (default init file) - - -i override .phpgdbinit location (implies -I) - - -O set oplog output file - - -q do not print banner on startup - - -r jump straight to run - - -E enable step through eval() - - -l listen ports for remote mode - - -a listen address for remote mode - - -S override SAPI name - -**Note:** Passing -rr will cause phpdbg to quit after execution, rather than returning to the console. - -Getting Started -=============== - -See the website for tutorials/documentation - -https://phpdbg.room11.org +* `-v` disables quietness +* `-s` enabled stepping +* `-e` sets execution context +* `-b` boring - disables use of colour on the console +* `-I` ignore .phpdbginit (default init file) +* `-i` override .phpgdbinit location (implies -I) +* `-O` set oplog output file +* `-q` do not print banner on startup +* `-r` jump straight to run +* `-E` enable step through eval() +* `-l` listen ports for remote mode +* `-a` listen address for remote mode +* `-S` override SAPI name + +**Note:** Passing `-rr` will cause phpdbg to quit after execution, rather than +returning to the console. + +## Getting started + +See the [website](https://phpdbg.room11.org) for tutorials/documentation. diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 51c6cde122271..b9149287bae89 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -671,11 +671,11 @@ static PHP_FUNCTION(phpdbg_end_oplog) { zend_string *last_file = NULL; - HashTable *file_ht; + HashTable *file_ht = NULL; zend_string *last_function = (void *)~(uintptr_t)0; zend_class_entry *last_scope = NULL; - HashTable *insert_ht; + HashTable *insert_ht = NULL; zend_long insert_idx; do { @@ -717,6 +717,7 @@ static PHP_FUNCTION(phpdbg_end_oplog) insert_idx = cur->op->lineno; } + ZEND_ASSERT(insert_ht && file_ht); { zval *num = zend_hash_index_find(insert_ht, insert_idx); if (!num) { diff --git a/sapi/phpdbg/phpdbg_eol.c b/sapi/phpdbg/phpdbg_eol.c index 50e0056fa8319..dc4e07c76c8ff 100644 --- a/sapi/phpdbg/phpdbg_eol.c +++ b/sapi/phpdbg/phpdbg_eol.c @@ -81,27 +81,30 @@ char *phpdbg_eol_rep(int id) return NULL; } +/* Marked as never_inline to work around a -Walloc-size-larger-than bug in GCC. */ +static zend_never_inline int count_lf_and_cr(const char *in, int in_len) { + int i, count = 0; + for (i = 0; i < in_len; i++) { + if (0x0a == in[i] || 0x0d == in[i]) { + count++; + } + } + return count; +} /* Inspired by https://ccrma.stanford.edu/~craig/utility/flip/flip.cpp */ void phpdbg_eol_convert(char **str, int *len) { - char *in = *str, *out ; - int in_len = *len, out_len, cursor, i; + char *in = *str, *out; + int in_len = *len, cursor, i; char last, cur; if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) != PHPDBG_IS_REMOTE) { return; } - out_len = *len; if (PHPDBG_EOL_CRLF == PHPDBG_G(eol)) { /* XXX add LFCR case if it's gonna be needed */ - /* depending on the source EOL the out str will have all CR/LF duplicated */ - for (i = 0; i < in_len; i++) { - if (0x0a == in[i] || 0x0d == in[i]) { - out_len++; - } - } - out = (char *)emalloc(out_len); + out = (char *)emalloc(in_len + count_lf_and_cr(in, in_len)); last = cur = in[0]; i = cursor = 0; @@ -142,7 +145,7 @@ void phpdbg_eol_convert(char **str, int *len) } /* We gonna have a smaller or equally long string, estimation is almost neglecting */ - out = (char *)emalloc(out_len); + out = (char *)emalloc(in_len); last = cur = in[0]; i = cursor = 0; diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c index fb7acc20cebee..912089ea2303d 100644 --- a/sapi/phpdbg/phpdbg_frame.c +++ b/sapi/phpdbg/phpdbg_frame.c @@ -171,7 +171,7 @@ void phpdbg_switch_frame(int frame) /* {{{ */ static void phpdbg_dump_prototype(zval *tmp) /* {{{ */ { - zval *funcname, *class, class_zv, *type, *args, *argstmp; + zval *funcname, *class, class_zv, *args, *argstmp; funcname = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("function")); @@ -183,21 +183,22 @@ static void phpdbg_dump_prototype(zval *tmp) /* {{{ */ } if (class) { - type = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("type")); + zval *type = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("type")); + + phpdbg_xml(" symbol=\"%s%s%s\"", Z_STRVAL_P(class), Z_STRVAL_P(type), Z_STRVAL_P(funcname)); + phpdbg_out("%s%s%s(", Z_STRVAL_P(class), Z_STRVAL_P(type), Z_STRVAL_P(funcname)); + } else { + phpdbg_xml(" symbol=\"%s\"", Z_STRVAL_P(funcname)); + phpdbg_out("%s(", Z_STRVAL_P(funcname)); } args = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("args")); - - phpdbg_xml(" symbol=\"%s%s%s\"", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname)); - if (args) { phpdbg_xml(">"); } else { phpdbg_xml(" />"); } - phpdbg_out("%s%s%s(", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname)); - if (args) { const zend_function *func = NULL; const zend_arg_info *arginfo = NULL; diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c index 167ada399a22e..bcec3361fc92e 100644 --- a/sapi/phpdbg/phpdbg_info.c +++ b/sapi/phpdbg/phpdbg_info.c @@ -343,11 +343,11 @@ PHPDBG_INFO(literal) /* {{{ */ PHPDBG_INFO(memory) /* {{{ */ { size_t used, real, peak_used, peak_real; - zend_mm_heap *heap; + zend_mm_heap *orig_heap = NULL; zend_bool is_mm; if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { - heap = zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem()); + orig_heap = zend_mm_set_heap(phpdbg_original_heap_sigsafe_mem()); } if ((is_mm = is_zend_mm())) { used = zend_memory_usage(0); @@ -355,8 +355,8 @@ PHPDBG_INFO(memory) /* {{{ */ peak_used = zend_memory_peak_usage(0); peak_real = zend_memory_peak_usage(1); } - if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { - zend_mm_set_heap(heap); + if (orig_heap) { + zend_mm_set_heap(orig_heap); } if (is_mm) { diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c index 559ff12a60b27..6917daa9d96ea 100644 --- a/sapi/phpdbg/phpdbg_io.c +++ b/sapi/phpdbg/phpdbg_io.c @@ -208,7 +208,7 @@ static int phpdbg_output_pager(int sock, const char *ptr, int len) { if (*buf == 'q') { break; } - write(sock, "\r", 1); + zend_quiet_write(sock, "\r", 1); } else break; } } diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c index 95f27b3c6fd84..88981e5c6fb69 100644 --- a/sapi/phpdbg/phpdbg_out.c +++ b/sapi/phpdbg/phpdbg_out.c @@ -1030,9 +1030,8 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m } else { phpdbg_mixed_write(fd, msg, msglen); } - return msglen; } - break; + return msglen; /* no formatting on logging output */ case P_LOG: @@ -1046,6 +1045,7 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m } } break; + EMPTY_SWITCH_DEFAULT_CASE() } if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index c962ce52c30f2..e1bfeb45da8ff 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1687,33 +1687,33 @@ int phpdbg_interactive(zend_bool allow_async_unsafe, char *input) /* {{{ */ return ret; } /* }}} */ +static inline void list_code() { + if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { + const char *file_char = zend_get_executed_filename(); + zend_string *file = zend_string_init(file_char, strlen(file_char), 0); + phpdbg_list_file(file, 3, zend_get_executed_lineno()-1, zend_get_executed_lineno()); + efree(file); + } +} + /* code may behave weirdly if EG(exception) is set; thus backup it */ #define DO_INTERACTIVE(allow_async_unsafe) do { \ - const zend_op *backup_opline; \ - const zend_op *before_ex; \ if (exception) { \ + const zend_op *before_ex = EG(opline_before_exception); \ + const zend_op *backup_opline = NULL; \ if (EG(current_execute_data) && EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) { \ backup_opline = EG(current_execute_data)->opline; \ } \ - before_ex = EG(opline_before_exception); \ GC_ADDREF(exception); \ zend_clear_exception(); \ - } \ - if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \ - const char *file_char = zend_get_executed_filename(); \ - zend_string *file = zend_string_init(file_char, strlen(file_char), 0); \ - phpdbg_list_file(file, 3, zend_get_executed_lineno()-1, zend_get_executed_lineno()); \ - efree(file); \ - } \ - \ - switch (phpdbg_interactive(allow_async_unsafe, NULL)) { \ - zval zv; \ - case PHPDBG_LEAVE: \ - case PHPDBG_FINISH: \ - case PHPDBG_UNTIL: \ - case PHPDBG_NEXT: \ - if (exception) { \ - if (EG(current_execute_data) && EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type) \ + list_code(); \ + switch (phpdbg_interactive(allow_async_unsafe, NULL)) { \ + zval zv; \ + case PHPDBG_LEAVE: \ + case PHPDBG_FINISH: \ + case PHPDBG_UNTIL: \ + case PHPDBG_NEXT: \ + if (backup_opline \ && (backup_opline->opcode == ZEND_HANDLE_EXCEPTION || backup_opline->opcode == ZEND_CATCH)) { \ EG(current_execute_data)->opline = backup_opline; \ EG(exception) = exception; \ @@ -1722,11 +1722,12 @@ int phpdbg_interactive(zend_bool allow_async_unsafe, char *input) /* {{{ */ zend_throw_exception_internal(&zv); \ } \ EG(opline_before_exception) = before_ex; \ - } \ - /* fallthrough */ \ - default: \ - goto next; \ + } \ + } else { \ + list_code(); \ + phpdbg_interactive(allow_async_unsafe, NULL); \ } \ + goto next; \ } while (0) void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index c40349f2a0c54..38e3d383776fc 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -430,7 +430,7 @@ PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, phpdbg_parse_var_with_arg_func step_cb, zend_bool silent, void *arg) { int ret = FAILURE; zend_bool new_index = 1; - char *last_index; + char *last_index = NULL; size_t index_len = 0; zval *zv; diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c index de0ecbe59f06d..69be24a953ec3 100644 --- a/sapi/phpdbg/phpdbg_wait.c +++ b/sapi/phpdbg/phpdbg_wait.c @@ -243,7 +243,7 @@ void phpdbg_webdata_decompress(char *msg, int len) { zend_extension *extension; zend_llist_position pos; zval *name = NULL; - zend_string *strkey; + zend_string *strkey = NULL; extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); while (extension) { @@ -257,6 +257,7 @@ void phpdbg_webdata_decompress(char *msg, int len) { break; } name = NULL; + strkey = NULL; } ZEND_HASH_FOREACH_END(); if (name) { @@ -283,6 +284,7 @@ void phpdbg_webdata_decompress(char *msg, int len) { pefree(elm, zend_extensions.persistent); zend_extensions.count--; } else { + ZEND_ASSERT(strkey); zend_hash_del(Z_ARRVAL_P(zvp), strkey); } } @@ -377,21 +379,25 @@ PHPDBG_COMMAND(wait) /* {{{ */ return FAILURE; } - char msglen[5]; - int recvd = 4; + unsigned char msglen_buf[4]; + int needed = 4; do { - recvd -= recv(sr, &(msglen[4 - recvd]), recvd, 0); - } while (recvd > 0); + needed -= recv(sr, &msglen_buf[4 - needed], needed, 0); + } while (needed > 0); - recvd = *(size_t *) msglen; - char *data = emalloc(recvd); + uint32_t msglen = (msglen_buf[3] << 24) + | (msglen_buf[2] << 16) + | (msglen_buf[1] << 8) + | (msglen_buf[0] << 0); + char *data = emalloc(msglen); + needed = msglen; do { - recvd -= recv(sr, &(data[(*(int *) msglen) - recvd]), recvd, 0); - } while (recvd > 0); + needed -= recv(sr, &(data[msglen - needed]), needed, 0); + } while (needed > 0); - phpdbg_webdata_decompress(data, *(int *) msglen); + phpdbg_webdata_decompress(data, msglen); if (PHPDBG_G(socket_fd) != -1) { close(PHPDBG_G(socket_fd)); diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c index 35d316b8ea464..d9f9f8673fe4c 100644 --- a/sapi/phpdbg/phpdbg_watch.c +++ b/sapi/phpdbg/phpdbg_watch.c @@ -1014,13 +1014,14 @@ void phpdbg_check_watchpoint(phpdbg_watchpoint_t *watch) { } if (watch->type == WATCH_ON_BUCKET) { if (watch->backup.bucket.key != watch->addr.bucket->key || (watch->backup.bucket.key != NULL && watch->backup.bucket.h != watch->addr.bucket->h)) { - phpdbg_watch_element *element; + phpdbg_watch_element *element = NULL; zval *new; ZEND_HASH_FOREACH_PTR(&watch->elements, element) { break; } ZEND_HASH_FOREACH_END(); + ZEND_ASSERT(element); /* elements must be non-empty */ new = zend_symtable_find(element->parent_container, element->name_in_parent); if (!new) { diff --git a/scripts/phpize.in b/scripts/phpize.in index 57c09555d2e59..ccb93575744df 100644 --- a/scripts/phpize.in +++ b/scripts/phpize.in @@ -160,6 +160,10 @@ phpize_autotools() { $PHP_AUTOCONF || exit 1 $PHP_AUTOHEADER || exit 1 + + # Disable PACKAGE_* symbols in config.h.in + $SED -e 's/^#undef PACKAGE_[^ ]*/\/\* & \*\//g' < config.h.in > config.h.in.tmp + mv config.h.in.tmp config.h.in } # Main script diff --git a/tests/basic/029.phpt b/tests/basic/029.phpt index 6d95c0771d733..21d9082cffb8b 100644 --- a/tests/basic/029.phpt +++ b/tests/basic/029.phpt @@ -9,8 +9,8 @@ if (!extension_loaded("mbstring")) { --INI-- file_uploads=1 mbstring.encoding_translation=1 -mbstring.http_input=Shift_JIS -mbstring.internal_encoding=UTF-8 +input_encoding=Shift_JIS +internal_encoding=UTF-8 --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/travis/compile.sh b/travis/compile.sh index 987338014e32f..65c11ff3788a8 100755 --- a/travis/compile.sh +++ b/travis/compile.sh @@ -73,7 +73,7 @@ $TS \ --with-enchant=/usr \ --with-kerberos \ --enable-sysvmsg \ ---enable-zend-test \ +--enable-zend-test=shared \ > "$CONFIG_LOG_FILE" make "-j${MAKE_JOBS}" $MAKE_QUIET > "$MAKE_LOG_FILE" diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index 06632b0e20d61..0403f6c5428bb 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -50,7 +50,6 @@ #define HAVE_GETHOSTNAME 1 #define HAVE_GETCWD 1 -#define HAVE_POSIX_READDIR_R 1 #define NEED_ISBLANK 1 #define DISCARD_PATH 0 #undef HAVE_SETITIMER diff --git a/win32/ioutil.c b/win32/ioutil.c index 287a9c117c94a..c819e41712815 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -308,18 +308,35 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode) already needs to be a long path. The given path is already normalized and prepared, need only to prefix it. */ - wchar_t *tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); + wchar_t *tmp = (wchar_t *) malloc((path_len + 1) * sizeof(wchar_t)); if (!tmp) { SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY); return -1; } + memmove(tmp, path, (path_len + 1) * sizeof(wchar_t)); - memmove(tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); - memmove(tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, path, path_len * sizeof(wchar_t)); - path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; - tmp[path_len] = L'\0'; + if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&tmp, path_len, &path_len)) { + free(tmp); + return -1; + } + + if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, path_len)) { + wchar_t *_tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); + if (!_tmp) { + SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY); + free(tmp); + return -1; + } + memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); + memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, path_len * sizeof(wchar_t)); + path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; + _tmp[path_len] = L'\0'; + free(tmp); + tmp = _tmp; + } my_path = tmp; + } else { my_path = path; } @@ -575,7 +592,7 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len) /* Partial normalization can still be acceptable, explicit fail has to be caught. */ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len) {/*{{{*/ - wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN]; + wchar_t *idx = *buf, canonicalw[MAXPATHLEN], _tmp[MAXPATHLEN], *pos = _tmp; size_t ret_len = len; if (len >= MAXPATHLEN) { @@ -584,12 +601,17 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w return PHP_WIN32_IOUTIL_NORM_FAIL; } - while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && (size_t)(idx - *buf) <= len) { - *pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; - idx = pos++; + for (; (size_t)(idx - *buf) <= len; idx++, pos++) { + *pos = *idx; + if (PHP_WIN32_IOUTIL_FW_SLASHW == *pos) { + *pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; + } + while (PHP_WIN32_IOUTIL_IS_SLASHW(*idx) && PHP_WIN32_IOUTIL_IS_SLASHW(*(idx+1))) { + idx++; + } } - if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) { + if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, _tmp, PATHCCH_ALLOW_LONG_PATHS)) { /* Length unchanged. */ *new_len = len; return PHP_WIN32_IOUTIL_NORM_PARTIAL; diff --git a/win32/readdir.c b/win32/readdir.c index b4d5e3afae8de..c172f16fc2d7d 100644 --- a/win32/readdir.c +++ b/win32/readdir.c @@ -127,46 +127,6 @@ struct dirent *readdir(DIR *dp) return &(dp->dent); }/*}}}*/ -int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result) -{/*{{{*/ - char *_tmp; - size_t reclen; - - if (!dp || dp->finished) { - *result = NULL; - return 0; - } - - if (dp->offset != 0) { - if (FindNextFileW(dp->handle, &(dp->fileinfo)) == 0) { - dp->finished = 1; - *result = NULL; - return 0; - } - } - - _tmp = php_win32_cp_conv_w_to_any(dp->fileinfo.cFileName, PHP_WIN32_CP_IGNORE_LEN, &reclen); - if (!_tmp) { - /* wide to utf8 failed, should never happen. */ - result = NULL; - return 0; - } - memmove(dp->dent.d_name, _tmp, reclen + 1); - free(_tmp); - dp->dent.d_reclen = (unsigned short)reclen; - - dp->offset++; - - dp->dent.d_ino = 1; - dp->dent.d_off = dp->offset; - - memcpy(entry, &dp->dent, sizeof(*entry)); - - *result = &dp->dent; - - return 0; -}/*}}}*/ - int closedir(DIR *dp) {/*{{{*/ if (!dp) diff --git a/win32/readdir.h b/win32/readdir.h index a39b6d4865ddc..61876f3dc10fc 100644 --- a/win32/readdir.h +++ b/win32/readdir.h @@ -15,8 +15,6 @@ extern "C" { #include "ioutil.h" -#define php_readdir_r readdir_r - /* struct dirent - same as Unix */ struct dirent { long d_ino; /* inode (always 1 in WIN32) */ @@ -39,7 +37,6 @@ typedef struct DIR_W32 DIR; /* Function prototypes */ DIR *opendir(const char *); struct dirent *readdir(DIR *); -int readdir_r(DIR *, struct dirent *, struct dirent **); int closedir(DIR *); int rewinddir(DIR *);