diff --git a/.github/actions/apk/action.yml b/.github/actions/apk/action.yml new file mode 100644 index 0000000000000..49e336aa0fecb --- /dev/null +++ b/.github/actions/apk/action.yml @@ -0,0 +1,61 @@ +name: apk +runs: + using: composite + steps: + - shell: sh + run: | + set -x + + apk update -q + apk add \ + util-linux \ + bash \ + sudo \ + build-base \ + autoconf \ + unzip \ + tar \ + bison \ + re2c \ + pkgconf \ + mysql-client \ + aspell-dev \ + hunspell-dev \ + hunspell-en \ + bzip2-dev \ + curl-dev \ + freetype-dev \ + gettext-dev \ + gnu-libiconv-dev \ + gmp-dev \ + icu-dev \ + icu-data-full \ + jpeg-dev \ + libffi-dev \ + libpng-dev \ + libsodium-dev \ + libwebp-dev \ + libxml2-dev \ + libxpm-dev \ + libxslt-dev \ + libzip-dev \ + oniguruma-dev \ + openssl-dev \ + readline-dev \ + sqlite-dev \ + tidyhtml-dev \ + krb5-dev \ + gdbm-dev \ + lmdb-dev \ + argon2-dev \ + enchant2-dev \ + enchant2-hunspell \ + freetds-dev \ + imap-dev \ + net-snmp-dev \ + openldap-dev \ + unixodbc-dev \ + postgresql14-dev \ + tzdata \ + musl-locales \ + musl-locales-lang diff --git a/.github/actions/configure-alpine/action.yml b/.github/actions/configure-alpine/action.yml new file mode 100644 index 0000000000000..fe02dacfcdaf6 --- /dev/null +++ b/.github/actions/configure-alpine/action.yml @@ -0,0 +1,79 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false + skipSlow: + default: false + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + ${{ inputs.skipSlow == 'false' && '--with-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-pgsql' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-sqlite' || '' }} \ + --enable-intl \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --with-xpm \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + ${{ inputs.skipSlow == 'false' && '--with-tidy' || '' }} \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline \ + --enable-mbstring \ + --with-iconv=/usr \ + --with-curl \ + --with-gettext \ + --enable-sockets \ + --with-bz2 \ + --with-openssl \ + --with-gmp \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + ${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + ${{ inputs.skipSlow == 'false' && '--enable-dl-test=shared' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-ldap-sasl' || '' }} \ + --with-password-argon2 \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --with-cdb \ + --enable-flatfile \ + --enable-inifile \ + --with-lmdb \ + --with-gdbm \ + ${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.skipSlow == 'false' && '--with-pdo-dblib' || '' }} \ + --enable-werror \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/install-alpine/action.yml b/.github/actions/install-alpine/action.yml new file mode 100644 index 0000000000000..3bb26c8cf35d5 --- /dev/null +++ b/.github/actions/install-alpine/action.yml @@ -0,0 +1,10 @@ +name: Install +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo make install + sudo mkdir -p /etc/php.d + sudo chmod 777 /etc/php.d diff --git a/.github/actions/test-alpine/action.yml b/.github/actions/test-alpine/action.yml new file mode 100644 index 0000000000000..e14e3176b8efd --- /dev/null +++ b/.github/actions/test-alpine/action.yml @@ -0,0 +1,25 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false + jitType: + default: 'disable' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export STACK_LIMIT_DEFAULTS_CHECK=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -d opcache.jit=${{ inputs.jitType }} \ + -d opcache.jit_buffer_size=64M \ + -j$(nproc) \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/nightly_matrix.php b/.github/nightly_matrix.php index a5804eaa02456..f0603dd97d73e 100644 --- a/.github/nightly_matrix.php +++ b/.github/nightly_matrix.php @@ -121,6 +121,26 @@ function get_macos_matrix_include(array $branches) { return $jobs; } +function get_alpine_matrix_include(array $branches) { + $jobs = []; + foreach ($branches as $branch) { + if ([$branch['version']['major'], $branch['version']['minor']] < [8, 4]) { + continue; + } + $jobs[] = [ + 'name' => '_ASAN_UBSAN', + 'branch' => $branch, + 'debug' => true, + 'zts' => true, + 'asan' => true, + 'test_jit' => true, + 'configuration_parameters' => "CFLAGS='-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC' LDFLAGS='-fsanitize=undefined,address -fno-sanitize=function' CC=clang-17 CXX=clang++-17", + 'run_tests_parameters' => '--asan -x', + ]; + } + return $jobs; +} + function get_current_version(): array { $file = dirname(__DIR__) . '/main/php_version.h'; $content = file_get_contents($file); @@ -145,10 +165,12 @@ function get_current_version(): array { $matrix_include = get_matrix_include($branches); $windows_matrix_include = get_windows_matrix_include($branches); $macos_matrix_include = get_macos_matrix_include($branches); +$alpine_matrix_include = get_alpine_matrix_include($branches); $f = fopen(getenv('GITHUB_OUTPUT'), 'a'); fwrite($f, 'branches=' . json_encode($branches, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'matrix-include=' . json_encode($matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'windows-matrix-include=' . json_encode($windows_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($f, 'macos-matrix-include=' . json_encode($macos_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); +fwrite($f, 'alpine-matrix-include=' . json_encode($alpine_matrix_include, JSON_UNESCAPED_SLASHES) . "\n"); fclose($f); diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 6899045c196d8..d4da1fdc84eb0 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -15,6 +15,7 @@ jobs: matrix-include: ${{ steps.set-matrix.outputs.matrix-include }} windows-matrix-include: ${{ steps.set-matrix.outputs.windows-matrix-include }} macos-matrix-include: ${{ steps.set-matrix.outputs.macos-matrix-include }} + alpine-matrix-include: ${{ steps.set-matrix.outputs.alpine-matrix-include }} steps: - uses: actions/checkout@v4 with: @@ -39,6 +40,65 @@ jobs: uses: ./.github/actions/notify-slack with: token: ${{ secrets.ACTION_MONITORING_SLACK }} + ALPINE: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.GENERATE_MATRIX.outputs.alpine-matrix-include) }} + name: "${{ matrix.branch.name }}_ALPINE_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-22.04 + container: + image: 'alpine:3.20.1' + steps: + - name: git checkout + uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch.ref }} + - name: apk + uses: ./.github/actions/apk + - name: LLVM 17 (ASAN-only) + if: ${{ matrix.asan }} + # libclang_rt.asan-x86_64.a is provided by compiler-rt, and only for clang17: + # https://pkgs.alpinelinux.org/contents?file=libclang_rt.asan-x86_64.a&path=&name=&branch=v3.20 + run: | + apk add clang17 compiler-rt + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed package versions" + apk list + echo "::endgroup::" + - name: ./configure + uses: ./.github/actions/configure-alpine + with: + configurationParameters: >- + ${{ matrix.configuration_parameters }} + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + skipSlow: ${{ matrix.asan }} + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-alpine + - name: Test Tracing JIT + if: matrix.test_jit + uses: ./.github/actions/test-alpine + with: + jitType: tracing + runTestsParameters: >- + ${{ matrix.run_tests_parameters }} + -d zend_extension=opcache.so + -d opcache.enable_cli=1 + - name: Notify Slack + if: failure() + uses: ./.github/actions/notify-slack + with: + token: ${{ secrets.ACTION_MONITORING_SLACK }} + LINUX_X64: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} diff --git a/EXTENSIONS b/EXTENSIONS index 35f5c76f1d1dd..ec75284085b71 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -409,7 +409,7 @@ MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- EXTENSION: random -PRIMARY MAINTAINER Go Kudo (2022 - 2022) +PRIMARY MAINTAINER Go Kudo (2022 - 2024) Tim Düsterhus (2022 - 2024) MAINTENANCE: Maintained STATUS: Working diff --git a/NEWS b/NEWS index 2c65e9799aba4..27c25de5709f7 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,94 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.4.0beta2 +?? ??? ????, PHP 8.4.0beta5 + +- Core: + . Fixed bug GH-15330 (Do not scan generator frames more than once). (Arnaud) + +- DOM: + . Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in + PHP 8.1 than in PHP 8.0). (nielsdos) + +27 Aug 2024, PHP 8.4.0beta4 + +- Core: + . Fixed bug GH-15408 (MSan false-positve on zend_max_execution_timer). + (zeriyoshi) + . Fixed bug GH-15438 (Hooks on constructor promoted properties without + visibility are ignored). (ilutov) + . Fixed bug GH-15419 (Missing readonly+hook incompatibility check for readonly + classes). (ilutov) + . Fixed bug GH-15187 (Various hooked object iterator issues). (ilutov) + . Fixed bug GH-15456 (Crash in get_class_vars() on virtual properties). + (ilutov) + . Fixed bug GH-15501 (Windows HAVE_
_H macros defined to 1 or + undefined). (Peter Kokot) + . Fixed bug GH-15565 (--disable-ipv6 during compilation produces error + EAI_SYSTEM not found). (nielsdos) + . Implemented asymmetric visibility for properties. (ilutov) + +- Date: + . Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end + date). (Mark Bennewitz, Derick) + +- DOM: + . Fixed bug GH-15551 (Segmentation fault (access null pointer) in + ext/dom/xml_common.h). (nielsdos) + . Fixed bug GH-15570 (Segmentation fault (access null pointer) in + ext/dom/html5_serializer.c). (nielsdos) + +- FPM: + . Added memory peak to the scoreboard / status page. (Flávio Heleno) + +- MySQLnd: + . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, + Kamil Tekiela) + +- Opcache: + . Fixed bug GH-15490 (Building of callgraph modifies preloaded symbols). + (ilutov) + . Fixed bug GH-15178 (Assertion in tracing JIT on hooks). (ilutov) + +- PDO_MYSQL: + . mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla) + +- Session: + . Emit warnings for non-positive values of session.gc_divisor and negative values + of session.gc_probability. (Jorg Sowa) + +- Standard: + . The "allowed_classes" option for unserialize() now throws TypeErrors and + ValueErrors if it is not an array of class names. (Girgias) + +- Streams: + . Fixed bug GH-14930 (Custom stream wrapper dir_readdir output truncated to + 255 characters in PHP 8.3). (Joe Cai) + + +15 Aug 2024, PHP 8.4.0beta3 - Core: . Exiting a namespace now clears seen symbols. (ilutov) + . The exit (and die) language constructs now behave more like a function. + They can be passed liked callables, are affected by the strict_types + declare statement, and now perform the usual type coercions instead of + casting any non-integer value to a string. + As such, passing invalid types to exit/die may now result in a TypeError + being thrown. (Girgias) + +- CURL: + . Added CURLOPT_TCP_KEEPCNT to set the number of probes to send before + dropping the connection. (David Carlier) + +- Hash: + . Fix GH-15384 (Build fails on Alpine / Musl for amd64). (timwolla) + +- Sockets: + . Added SO_BINDTOIFINDEX to bind a socket to an interface index. + (David Carlier) + +- Standard: + . php_uname() now throws ValueErrors on invalid inputs. (Girgias) 15 Aug 2024, PHP 8.4.0beta1 @@ -398,7 +483,7 @@ PHP NEWS - PCNTL: . Added pcntl_setns for Linux. (David Carlier) - . Added pcntl_getaffinity/pcntl_setaffinity. (David Carlier) + . Added pcntl_getcpuaffinity/pcntl_setcpuaffinity. (David Carlier) . Updated pcntl_get_signal_handler signal id upper limit to be more in line with platforms limits. (David Carlier) . Added pcntl_getcpu for Linux/FreeBSD/Solaris/Illumos. (David Carlier) diff --git a/UPGRADING b/UPGRADING index bcf95365538b9..9b16369e3e8e6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -37,6 +37,13 @@ PHP 8.4 UPGRADE NOTES allowed, e.g. $ref = &$this->readonly. This was already forbidden for readonly initialization, and was an oversight in the "readonly reinitialization during cloning" implementation. + . The exit (and die) language constructs now behave more like a function. + They can be passed liked callables, are affected by the strict_types + declare statement, and now perform the usual type coercions instead of + casting any non-integer value to a string. + As such, passing invalid types to exit/die may now result in a TypeError + being thrown. + RFC: https://wiki.php.net/rfc/exit-as-function - DBA: . dba_open() and dba_popen() will now return a Dba\Connection @@ -57,8 +64,8 @@ PHP 8.4 UPGRADE NOTES object. This is no longer possible, and cloning a DOMXPath object now throws an error. . DOMDocument::$actualEncoding, DOMDocument::config, DOMEntity::$actualEncoding, - DOMEntity::$encoding, DOMEntity::$version have been deprecated as part of the - https://wiki.php.net/rfc/deprecations_php_8_4 RFC. + DOMEntity::$encoding, DOMEntity::$version have been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#formally_deprecate_soft-deprecated_domdocument_and_domentity_properties - GMP: . The GMP class is now final and cannot be extended anymore. @@ -119,22 +126,9 @@ PHP 8.4 UPGRADE NOTES has changed. Consult https://github.com/PCRE2Project/pcre2/blob/master/NEWS for a full changelog. -- PDO_DBLIB: - . setAttribute, DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER and DBLIB_ATTR_DATETIME_CONVERT - have been changed to set value as a bool. - -- PDO_FIREBIRD: - . Since some Firebird C++ APIs are used now, this extension requires a C++ - compiler to be built. - . getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool. - -- PDO_MYSQL: - . getAttribute, ATTR_AUTOCOMMIT, ATTR_EMULATE_PREPARES, MYSQL_ATTR_DIRECT_QUERY have - been changed to get values as bool. - -- PDO_PGSQL: - . The DSN's credentials, when set, are given priority over their PDO - constructor counterparts, being closer to the documentation states. +- MySQLnd + . The error code reported for MySQL server wait timeouts has been changed from 2006 + to 4031 for MySQL server versions 8.0.24 and above. - PCNTL: . The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and @@ -152,6 +146,24 @@ PHP 8.4 UPGRADE NOTES - A ValueError if $nanoseconds is less than 0 or greater than 1e9 - A ValueError if both $seconds and $nanoseconds are 0 +- PDO_DBLIB: + . setAttribute, DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER and DBLIB_ATTR_DATETIME_CONVERT + have been changed to set value as a bool. + +- PDO_FIREBIRD: + . Since some Firebird C++ APIs are used now, this extension requires a C++ + compiler to be built. This also implies that the extension has to be built + against fbclient 3.0 or higher. + . getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool. + +- PDO_MYSQL: + . getAttribute, ATTR_AUTOCOMMIT, ATTR_EMULATE_PREPARES, MYSQL_ATTR_DIRECT_QUERY have + been changed to get values as bool. + +- PDO_PGSQL: + . The DSN's credentials, when set, are given priority over their PDO + constructor counterparts, being closer to the documentation states. + - SimpleXML: . Get methods called, or casting to a string on a SimpleXMLElement will no longer implicitly reset the iterator data, unless explicitly rewound. @@ -193,6 +205,9 @@ PHP 8.4 UPGRADE NOTES $enclosure arguments are not one byte long, or if the $escape is not one byte long or the empty string. This aligns the behaviour to be identical to that of fputcsv() and fgetcsv(). + . php_uname() now throws ValueErrors on invalid inputs. + . The "allowed_classes" option for unserialize() now throws TypeErrors and + ValueErrors if it is not an array of class names. - Tidy: . Failures in the constructor now throw exceptions rather than emitting @@ -252,6 +267,8 @@ PHP 8.4 UPGRADE NOTES namespace block, even if a previous namespace block declared a symbol with the same name. See Zend/tests/use_function/ns_end_resets_seen_symbols_1.phpt. + . Implemented asymmetric property visibility. + RFC: https://wiki.php.net/rfc/asymmetric-visibility-v2 - Curl: . curl_version() returns an additional feature_list value, which is an @@ -279,6 +296,7 @@ PHP 8.4 UPGRADE NOTES - FPM: . Flushing headers without a body will now succeed. See GH-12785. + . Status page has a new field to display a memory peak. - Hash: . Added HashContext::__debugInfo(). @@ -293,36 +311,6 @@ PHP 8.4 UPGRADE NOTES openssl_pkey_get_details as well as openssl_sign and openssl_verify were extended to support those keys. -- PDO: - . Added support for driver specific SQL parsers. The default parser supports: - - single and double quoted literals, with doubling as escaping mechanism. - - two-dashes and non-nested C-style comments. - -- PDO_MYSQL: - . Added custom parser supporting: - - single and double-quoted literals, with doubling and backslash as escaping - mechanism - - backtick literal identifiers and with doubling as escaping mechanism - - two dashes followed by at least 1 whitespace, non-nested C-style comments, - and hash-comments - -- PDO_PGSQL: - . Added custom parser supporting: - - single and double quoted literals, with doubling as escaping mechanism - - C-style "escape" string literals (E'string') - - dollar-quoted string literals - - two-dashes and C-style comments (non-nested) - - support for "??" as escape sequence for the "?" operator - -- PDO_SQLITE: - . Added custom parser supporting: - - single, double quoted, and backtick literals, with doubling as escaping mechanism - - square brackets quoting for identifiers - - two-dashes and C-style comments (non-nested) - -- Phar: - . Added support for the unix timestamp extension for zip archives. - - PCRE: . The bundled pcre2lib has been updated to version 10.44. As a consequence, LoongArch JIT support has been added, spaces @@ -342,6 +330,10 @@ PHP 8.4 UPGRADE NOTES database-specific functionalities. The new classes are instantiatable either via calling the PDO::connect() method or by invoking their constructor directly. + . Added support for driver specific SQL parsers. The default parser supports: + - single and double quoted literals, with doubling as escaping mechanism. + - two-dashes and non-nested C-style comments. + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_DBLIB: . Added class Pdo\DbLib. @@ -351,15 +343,40 @@ PHP 8.4 UPGRADE NOTES - PDO_MYSQL: . Added class Pdo\Mysql. + . Added custom parser supporting: + - single and double-quoted literals, with doubling and backslash as escaping + mechanism + - backtick literal identifiers and with doubling as escaping mechanism + - two dashes followed by at least 1 whitespace, non-nested C-style comments, + and hash-comments + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_ODBC: . Added class Pdo\Odbc. - PDO_PGSQL: . Added class Pdo\Pgsql. + . Added custom parser supporting: + - single and double quoted literals, with doubling as escaping mechanism + - C-style "escape" string literals (E'string') + - dollar-quoted string literals + - two-dashes and C-style comments (non-nested) + - support for "??" as escape sequence for the "?" operator + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers - PDO_SQLITE: . Added class Pdo\Sqlite. + . Added custom parser supporting: + - single, double quoted, and backtick literals, with doubling as escaping mechanism + - square brackets quoting for identifiers + - two-dashes and C-style comments (non-nested) + RFC: https://wiki.php.net/rfc/pdo_driver_specific_parsers + +- Phar: + . Added support for the unix timestamp extension for zip archives. + +- PgSQL: + . Added pg_result_memory_size to get the visibility the memory used by a query result. - POSIX: . Added constant POSIX_SC_CHILD_MAX @@ -435,7 +452,7 @@ PHP 8.4 UPGRADE NOTES . Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and SUNFUNCS_RET_DOUBLE are now deprecated, following the deprecation of the associated date_sunset() and date_sunrise() functions in PHP 8.1. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#constants_sunfuncs_ret_string_sunfuncs_ret_double_sunfuncs_ret_timestamp - DBA: . Passing null or false to dba_key_split() is deprecated. @@ -447,7 +464,7 @@ PHP 8.4 UPGRADE NOTES - Hash: . Deprecated passing incorrect data types for options to ext/hash functions. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_incorrect_data_types_for_options_to_exthash_functions - Intl: . Calling intlcal_set() as well as calling IntlCalendar::set() with @@ -486,18 +503,17 @@ PHP 8.4 UPGRADE NOTES is no longer necessary to escape question marks inside them. - PgSQL: - . Calling pgsql_fetch_result() with 2 arguments is deprecated. Use the + . Calling pg_fetch_result() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. . Calling pg_field_prtlen() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. . Calling pg_field_is_null() with 2 arguments is deprecated. Use the 3-parameter signature with a null $row parameter instead. - . Added pg_result_memory_size to get the visibility the memory used by a query result. - Random: . lcg_value() is deprecated, as the function is broken in multiple ways. Use \Random\Randomizer::getFloat() instead. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_lcg_value - Reflection: . Calling ReflectionMethod::__construct() with 1 argument is deprecated. @@ -509,7 +525,7 @@ PHP 8.4 UPGRADE NOTES . Changing the INI settings session.sid_length and session.sid_bits_per_character is deprecated. Update the session storage backend to accept 32 character hexadecimal session IDs and stop changing these two INI settings. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#sessionsid_length_and_sessionsid_bits_per_character - SOAP: . Passing an int to SoapServer::addFunction() is now deprecated. @@ -535,7 +551,7 @@ PHP 8.4 UPGRADE NOTES . Raising zero to the power of negative number is deprecated. RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number . Unserializing strings using the uppercase 'S' tag is deprecated. - RFC: https://wiki.php.net/rfc/deprecations_php_8_4 + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#unserialize_s_s_tag . Passing a non-empty string for the $enclosure parameter of: - fputcsv() - fgetcsv() @@ -558,6 +574,10 @@ PHP 8.4 UPGRADE NOTES . trigger_error() and user_error() now have a return type of true instead of bool. +- Curl: + . curl_multi_select throws a ValueError if the timeout argument if it's negative + or greater than PHP_INT_MAX. + - DOM: . DOMDocument::registerNodeClass() now has a tentative return type of true. Previously, the return type was bool but only true could be returned in practice. @@ -598,6 +618,12 @@ PHP 8.4 UPGRADE NOTES . The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16 strings. (For valid UTF-8 and UTF-16 strings, there is no change.) +- ODBC: + . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and + odbc_fetch_into() now has a default value of null, consistent with + odbc_fetch_row(). Previously, the default values were -1, -1, and 0, + respectively. + - OpenSSL: . The extra_attributes parameter in openssl_csr_new sets CSR attributes instead of subject DN which was incorrectly done previously. @@ -609,12 +635,6 @@ PHP 8.4 UPGRADE NOTES for OpenSSL version below 3.2 (-1 is returned for such fields). The OpenSSL version 3.3+ does not load such certificates already. -- ODBC: - . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and - odbc_fetch_into() now has a default value of null, consistent with - odbc_fetch_row(). Previously, the default values were -1, -1, and 0, - respectively. - - Output: . Output handler status flags passed to the flags parameter of ob_start are now cleared. @@ -647,6 +667,10 @@ PHP 8.4 UPGRADE NOTES - PGSQL: . pg_select, the conditions arguments accepts an empty array and is optional. +- Phar: + . Phar::setAlias() and Phar::setDefaultStub() methods now have a tentative + return type of true instead of bool. + - POSIX: . posix_isatty now sets the error number when the file descriptor/stream argument is invalid. @@ -675,11 +699,9 @@ PHP 8.4 UPGRADE NOTES earlier PHP versions. . The $mode parameter of the round() function has been widened to RoundingMode|int, accepting instances of a new RoundingMode enum. - RFC: https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum . Four new modes have been added to the round() function: RoundingMode::PositiveInfinity, RoundingMode::NegativeInfinity, RoundingMode::TowardsZero, RoundingMode::AwayFromZero. - RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function . Fixed a bug caused by "pre-rounding" of the round() function. Previously, using "pre-rounding" to treat a value like 0.285 (actually 0.28499999999999998) as a @@ -691,7 +713,6 @@ PHP 8.4 UPGRADE NOTES but now returns `4503599627370496`. . The default value of the 'cost' option for PASSWORD_BCRYPT for password_hash() has been increased from '10' to '12'. - RFC: https://wiki.php.net/rfc/bcrypt_cost_2023 . debug_zval_dump() now indicates whether an array is packed. . long2ip() now returns string instead of string|false. @@ -736,8 +757,8 @@ PHP 8.4 UPGRADE NOTES - PCNTL: . Added pcntl_setns allowing a process to be reassociated with a namespace in order to share resources with other processes within this context. - . Added pcntl_getaffinity to get the cpu(s) bound to a process and - pcntl_setaffinity to bind 1 or more cpus to a process. + . Added pcntl_getcpuaffinity to get the cpu(s) bound to a process and + pcntl_setcpuaffinity to bind 1 or more cpus to a process. . Added pcntl_getcpu to get the cpu id from where the current process runs. . Added pcntl_getqos_class to get the QoS level (aka performance and related energy consumption) of the current process and pcntl_setqos_class to set it. @@ -865,12 +886,28 @@ PHP 8.4 UPGRADE NOTES $domain name is empty or too long, and if $variant is not INTL_IDNA_VARIANT_UTS46. +- LibXML: + . The libxml extension now requires at least libxml2 2.9.4. + - MBString: . Unicode data tables have been updated to Unicode 15.1. -- mysqli: +- Mysqli: . The unused and undocumented constant MYSQLI_SET_CHARSET_DIR has been removed. + . The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been removed. + The feature is unavailable with mysqlnd. + . The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE + constants have been removed. This functionality was never implemented, + neither with mysqlnd nor with libmysql. + . The unused MYSQLI_TYPE_INTERVAL constant, which is currently a stub + and an alias for MYSQLI_TYPE_ENUM, has been removed. There are no + plans to add such data type to MySQL yet, so it's unclear what its value + would finally be. + . A new constant has been added: MYSQLI_TYPE_VECTOR. + +- Mysqlnd + . Support for the new VECTOR data type from MySQL 9. - OpenSSL: . The OpenSSL extension now requires at least OpenSSL 1.1.1. @@ -878,10 +915,10 @@ PHP 8.4 UPGRADE NOTES - PDO: . The class constants are typed now. -- pdo_pgsql: +- PDO_PGSQL: . The pdo_pgsql extension now requires at least libpq 10.0. -- pgsql: +- PgSQL: . The pgsql extension now requires at least libpq 10.0. - Reflection: @@ -914,6 +951,7 @@ PHP 8.4 UPGRADE NOTES - Curl: . CURL_HTTP_VERSION_3. . CURL_HTTP_VERSION_3ONLY. + . CURL_TCP_KEEPCNT - Intl: . The IntlDateFormatter class exposes now the new PATTERN constant @@ -958,6 +996,9 @@ PHP 8.4 UPGRADE NOTES . P_SID (NetBSD/FreeBSD only). . P_JAILID (FreeBSD only). +- PgSQL: + . PGSQL_TUPLES_CHUNK + - Sockets: . SO_EXCLUSIVEADDRUSE (Windows only). . SOCK_CONN_DGRAM (NetBSD only). @@ -972,6 +1013,7 @@ PHP 8.4 UPGRADE NOTES . IP_PORTRANGE_LOW (FreeBSD/NetBSD/OpenBSD only). . SOCK_NONBLOCK. . SOCK_CLOEXEC. + . SOCK_BINDTOIFINDEX. - Sodium: . SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES @@ -996,6 +1038,8 @@ PHP 8.4 UPGRADE NOTES 12. Windows Support ======================================== +* Native AVX-512 builds are now supported (--enable-native-intrinsics=avx512). + ======================================== 13. Other Changes ======================================== @@ -1039,6 +1083,7 @@ PHP 8.4 UPGRADE NOTES an xpath query. This can give a time improvement of easily two order of magnitude for documents with tens of thousands of nodes. . Improved performance and reduce memory consumption of XML serialization. + . Reduced memory usage of node classes. - FTP: . Improved the performance of FTP uploads up to a factor of 10x for large diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 448f220ff659a..85b0da4cf00cc 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -178,9 +178,11 @@ PHP 8.4 INTERNALS UPGRADE NOTES - M4 macro PHP_EVAL_LIBLINE got a new 3rd argument to override the ext_shared checks. - M4 macro PHP_SETUP_LIBXML doesn't define the redundant HAVE_LIBXML symbol - anymore. + anymore and requires at least libxml2 2.9.4. - M4 macro PHP_SETUP_ICONV doesn't define the HAVE_ICONV symbol anymore. - M4 macro PHP_OUTPUT is obsolete (use AC_CONFIG_FILES). + - M4 macro PHP_PROG_SETUP now accepts an argument to set the minimum required + PHP version during the build. - TSRM/tsrm.m4 file and its TSRM_CHECK_PTHREADS M4 macro have been removed. - Added pkg-config support to find libpq for the pdo_pgsql and pgsql extensions. The libpq paths can be customized with the PGSQL_CFLAGS and @@ -230,6 +232,9 @@ PHP 8.4 INTERNALS UPGRADE NOTES - Added configure option --enable-phpdbg-debug to build phpdbg in debug mode. - The win32/build/libs_version.txt file has been removed. - MSVC builds now use the new preprocessor (/Zc:preprocessor). + - The CHECK_HEADER_ADD_INCLUDE function now consistently defines preprocessor + macros HAVE_
_H either to value 1 or leaves them undefined to match + the Autotools headers checks. ======================== 3. Module changes @@ -338,6 +343,9 @@ PHP 8.4 INTERNALS UPGRADE NOTES the caller now. - The php_info_html_esc() function has been removed, use php_escape_html_entities() with ENT_QUOTES directly instead. + - The deprecated php_uint32 and php_int32 typedefs have been removed from + ext/standard/basic_functions.h. Use the standard uint32_t and int32_t + types instead. h. ext/session - Added the php_get_session_status() API to get the session status, which is @@ -367,6 +375,8 @@ PHP 8.4 INTERNALS UPGRADE NOTES * YIELD and YIELD_FROM do not increment the opline anymore. +* The EXIT opcode has been removed as exit is now implemented as a function. + ======================== 5. SAPI changes ======================== diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index cd6dce6a5c10a..6fcbd04f12af5 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -868,7 +868,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array break; case ZEND_RETURN: - case ZEND_EXIT: if (opline->op1_type == IS_TMP_VAR) { src = VAR_SOURCE(opline->op1); if (src && src->opcode == ZEND_QM_ASSIGN) { @@ -1221,8 +1220,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr target = op_array->opcodes + target_block->start; if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || - target->opcode == ZEND_GENERATOR_RETURN || - target->opcode == ZEND_EXIT) && + target->opcode == ZEND_GENERATOR_RETURN) && !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { /* JMP L, L: RETURN to immediate RETURN */ *last_op = *target; diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 7543c15341c97..7c9f1c99a2820 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -331,7 +331,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_THROW: case ZEND_MATCH_ERROR: case ZEND_CATCH: diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 93e431fece440..2cbd0e3406521 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -88,8 +88,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) MAKE_NOP(opline); } else if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || - target->opcode == ZEND_GENERATOR_RETURN || - target->opcode == ZEND_EXIT) && + target->opcode == ZEND_GENERATOR_RETURN) && !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { /* JMP L, L: RETURN to immediate RETURN */ *opline = *target; diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index fd63f587336a3..8a2f8ea2a7e1a 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -79,7 +79,8 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 if (build_flags & ZEND_CALL_TREE) { call_info->next_caller = NULL; - } else if (func->type == ZEND_INTERNAL_FUNCTION) { + } else if (func->type == ZEND_INTERNAL_FUNCTION + || func->op_array.filename != script->filename) { call_info->next_caller = NULL; } else { zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array); @@ -162,10 +163,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 call_info->send_unpack = 1; } break; - case ZEND_EXIT: - /* In this case the DO_CALL opcode may have been dropped - * and caller_call_opline will be NULL. */ - break; } opline++; } diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 2a0fe369cfc6a..a05cf6fb79235 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -302,7 +302,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, } break; case ZEND_MATCH_ERROR: - case ZEND_EXIT: case ZEND_THROW: /* Don't treat THROW as terminator if it's used in expression context, * as we may lose live ranges when eliminating unreachable code. */ @@ -506,7 +505,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_THROW: case ZEND_MATCH_ERROR: case ZEND_VERIFY_NEVER_TYPE: diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index b7b44fb140872..47ea9c831d524 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -133,7 +133,10 @@ dnl AC_DEFUN([ZEND_INIT], [dnl AC_REQUIRE([AC_PROG_CC]) -AC_CHECK_HEADERS([cpuid.h]) +AC_CHECK_HEADERS(m4_normalize([ + cpuid.h + libproc.h +])) dnl Check for library functions. AC_CHECK_FUNCS(m4_normalize([ @@ -223,11 +226,17 @@ AC_DEFUN([ZEND_CHECK_STACK_DIRECTION], [AC_RUN_IFELSE([AC_LANG_SOURCE([dnl #include +#ifdef __has_builtin +# if __has_builtin(__builtin_frame_address) +# define builtin_frame_address __builtin_frame_address(0) +# endif +#endif + int (*volatile f)(uintptr_t); int stack_grows_downwards(uintptr_t arg) { -#if defined(__has_builtin) && __has_builtin(__builtin_frame_address) - uintptr_t addr = (uintptr_t)__builtin_frame_address(0); +#ifdef builtin_frame_address + uintptr_t addr = (uintptr_t)builtin_frame_address; #else int local; uintptr_t addr = (uintptr_t)&local; @@ -237,8 +246,8 @@ int stack_grows_downwards(uintptr_t arg) { } int main(void) { -#if defined(__has_builtin) && __has_builtin(__builtin_frame_address) - uintptr_t addr = (uintptr_t)__builtin_frame_address(0); +#ifdef builtin_frame_address + uintptr_t addr = (uintptr_t)builtin_frame_address; #else int local; uintptr_t addr = (uintptr_t)&local; diff --git a/Zend/tests/arginfo_zpp_mismatch.inc b/Zend/tests/arginfo_zpp_mismatch.inc index 023bfefa5d501..5b2711fdb6303 100644 --- a/Zend/tests/arginfo_zpp_mismatch.inc +++ b/Zend/tests/arginfo_zpp_mismatch.inc @@ -6,6 +6,9 @@ function skipFunction($function): bool { || $function === 'readline' || $function === 'readline_read_history' || $function === 'readline_write_history' + /* terminates script */ + || $function === 'exit' + || $function === 'die' /* intentionally violate invariants */ || $function === 'zend_create_unterminated_string' || $function === 'zend_test_array_return' diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 5a4bbecbe9147..695c4c166a83c 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -1,5 +1,5 @@ --TEST-- -AST pretty-peinter +AST pretty-printer --INI-- zend.assertions=1 --FILE-- diff --git a/Zend/tests/asymmetric_visibility/__set.phpt b/Zend/tests/asymmetric_visibility/__set.phpt new file mode 100644 index 0000000000000..7476f5304e253 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/__set.phpt @@ -0,0 +1,43 @@ +--TEST-- +Asymmetric visibility __set +--FILE-- +bar = $bar; + } + + public function unsetBar() { + unset($this->bar); + } + + public function __set(string $name, mixed $value) { + echo __CLASS__, '::', __METHOD__, "\n"; + } +} + +$foo = new Foo(); +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->unsetBar(); +$foo->bar = 'baz'; + +?> +--EXPECT-- +Cannot modify private(set) property Foo::$bar from global scope +Cannot modify private(set) property Foo::$bar from global scope +Foo::Foo::__set diff --git a/Zend/tests/asymmetric_visibility/__unset.phpt b/Zend/tests/asymmetric_visibility/__unset.phpt new file mode 100644 index 0000000000000..3d5977d79782b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/__unset.phpt @@ -0,0 +1,47 @@ +--TEST-- +Asymmetric visibility __unset +--FILE-- +bar = $bar; + } + + public function unsetBar() { + unset($this->bar); + } + + public function __unset($name) { + echo __METHOD__, "\n"; + } +} + +function test($foo) { + try { + unset($foo->bar); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +} + +$foo = new Foo(); +test($foo); + +$foo->unsetBar(); +test($foo); + +$foo->setBar('bar'); +test($foo); + +$foo->unsetBar(); +test($foo); + +?> +--EXPECT-- +Cannot unset private(set) property Foo::$bar from global scope +Foo::__unset +Cannot unset private(set) property Foo::$bar from global scope +Foo::__unset diff --git a/Zend/tests/asymmetric_visibility/ast_printing.phpt b/Zend/tests/asymmetric_visibility/ast_printing.phpt new file mode 100644 index 0000000000000..25803e67c09df --- /dev/null +++ b/Zend/tests/asymmetric_visibility/ast_printing.phpt @@ -0,0 +1,28 @@ +--TEST-- +private(set) protected(set) ast printing +--INI-- +zend.assertions=1 +assert.exception=1 +--FILE-- +getMessage(); +} + +?> +--EXPECT-- +assert(function () { + class Foo { + public private(set) string $bar; + public protected(set) string $baz; + } + +} && false) diff --git a/Zend/tests/asymmetric_visibility/bug001.phpt b/Zend/tests/asymmetric_visibility/bug001.phpt new file mode 100644 index 0000000000000..c306434d610b1 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug001.phpt @@ -0,0 +1,33 @@ +--TEST-- +Unset from __unset respects set visibility +--FILE-- +a); + } +} + +class D extends C { + public function __unset($name) { + unset($this->a); + } +} + +$c = new D(); +try { + unset($c->a); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Cannot unset private(set) property C::$a from scope D +object(D)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/asymmetric_visibility/bug002.phpt b/Zend/tests/asymmetric_visibility/bug002.phpt new file mode 100644 index 0000000000000..1f6dc2b852780 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug002.phpt @@ -0,0 +1,33 @@ +--TEST-- +Set from __set respects set visibility +--FILE-- +a); + } +} + +class D extends C { + public function __set($name, $value) { + $this->a = $value; + } +} + +$c = new D(); +try { + $c->a = 2; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Cannot modify private(set) property C::$a from scope D +object(D)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/asymmetric_visibility/bug003.phpt b/Zend/tests/asymmetric_visibility/bug003.phpt new file mode 100644 index 0000000000000..9f541f87f7cdb --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug003.phpt @@ -0,0 +1,28 @@ +--TEST-- +Explicitly unset property with a-vis still respects set visibility +--FILE-- +a); + } +} + +$c = new C(); +try { + $c->a = 2; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + unset($c->a); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot modify private(set) property C::$a from global scope +Cannot unset private(set) property C::$a from global scope diff --git a/Zend/tests/asymmetric_visibility/bug004.phpt b/Zend/tests/asymmetric_visibility/bug004.phpt new file mode 100644 index 0000000000000..f44d69cd21644 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/bug004.phpt @@ -0,0 +1,18 @@ +--TEST-- +Missing property initialization for private(set) constructor promoted property +--FILE-- + +--EXPECTF-- +object(T)#%d (1) { + ["prop"]=> + string(4) "Test" +} diff --git a/Zend/tests/asymmetric_visibility/cpp_no_type.phpt b/Zend/tests/asymmetric_visibility/cpp_no_type.phpt new file mode 100644 index 0000000000000..b1d169b6e1888 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_no_type.phpt @@ -0,0 +1,14 @@ +--TEST-- +Asymmetric visibility in CPP with no type +--FILE-- + +--EXPECTF-- +Fatal error: Property with asymmetric visibility Foo::$bar must have type in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/cpp_private.phpt b/Zend/tests/asymmetric_visibility/cpp_private.phpt new file mode 100644 index 0000000000000..c308330d3ab01 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_private.phpt @@ -0,0 +1,32 @@ +--TEST-- +Asymmetric visibility private(set) CPP +--FILE-- +bar = $bar; + } +} + +$foo = new Foo('bar'); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +var_dump($foo->bar); + +?> +--EXPECT-- +string(3) "bar" +Cannot modify private(set) property Foo::$bar from global scope +string(3) "baz" diff --git a/Zend/tests/asymmetric_visibility/cpp_protected.phpt b/Zend/tests/asymmetric_visibility/cpp_protected.phpt new file mode 100644 index 0000000000000..f13351e32003b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_protected.phpt @@ -0,0 +1,42 @@ +--TEST-- +Asymmetric visibility protected(set) CPP +--FILE-- +bar = $bar; + } +} + +class FooChild extends Foo { + public function setBarProtected($bar) { + $this->bar = $bar; + } +} + +$foo = new FooChild('bar'); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBarPrivate('baz'); +var_dump($foo->bar); + +$foo->setBarProtected('qux'); +var_dump($foo->bar); + +?> +--EXPECT-- +string(3) "bar" +Cannot modify protected(set) property Foo::$bar from global scope +string(3) "baz" +string(3) "qux" diff --git a/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt b/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt new file mode 100644 index 0000000000000..45fcc96518691 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt @@ -0,0 +1,14 @@ +--TEST-- +Asymmetric visibility private(get) protected(set) in CPP is not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt new file mode 100644 index 0000000000000..affe965b45c47 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_private_private.phpt @@ -0,0 +1,13 @@ +--TEST-- +Asymmetric visibility private(get) private(set) is allowed +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt new file mode 100644 index 0000000000000..625f12382cf7e --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_private_protected.phpt @@ -0,0 +1,12 @@ +--TEST-- +Asymmetric visibility private(get) protected(set) not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt b/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt new file mode 100644 index 0000000000000..7d98b61b47420 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/decrease_scope_protected_protected.phpt @@ -0,0 +1,13 @@ +--TEST-- +Asymmetric visibility protected(get) protected(set) is allowed +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/asymmetric_visibility/dim_add.phpt b/Zend/tests/asymmetric_visibility/dim_add.phpt new file mode 100644 index 0000000000000..f7bf0ceaf939c --- /dev/null +++ b/Zend/tests/asymmetric_visibility/dim_add.phpt @@ -0,0 +1,34 @@ +--TEST-- +Asymmetric visibility DIM add +--FILE-- +bars[] = $bar; + } +} + +$foo = new Foo(); + +try { + $foo->bars[] = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bars); + +$foo->addBar('baz'); +var_dump($foo->bars); + +?> +--EXPECT-- +Cannot indirectly modify private(set) property Foo::$bars from global scope +array(0) { +} +array(1) { + [0]=> + string(3) "baz" +} diff --git a/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt b/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt new file mode 100644 index 0000000000000..d09eacd18deae --- /dev/null +++ b/Zend/tests/asymmetric_visibility/duplicate_modifier.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate asymmetric visibility modifier +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt b/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt new file mode 100644 index 0000000000000..832c57b296e67 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/duplicate_modifier_2.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate asymmetric visibility modifier +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/nested_write.phpt b/Zend/tests/asymmetric_visibility/nested_write.phpt new file mode 100644 index 0000000000000..8386b6b2503c6 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/nested_write.phpt @@ -0,0 +1,24 @@ +--TEST-- +Asymmetric visibility nested write +--FILE-- +bar = new Bar; + } +} + +class Bar { + public int $baz; +} + +$foo = new Foo(); +$foo->bar->baz = 42; +var_dump($foo->bar->baz); + +?> +--EXPECT-- +int(42) diff --git a/Zend/tests/asymmetric_visibility/no_type.phpt b/Zend/tests/asymmetric_visibility/no_type.phpt new file mode 100644 index 0000000000000..3e48bdbb06feb --- /dev/null +++ b/Zend/tests/asymmetric_visibility/no_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Asymmetric visibility with no type +--FILE-- + +--EXPECTF-- +Fatal error: Property with asymmetric visibility Foo::$bar must have type in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/object_reference.phpt b/Zend/tests/asymmetric_visibility/object_reference.phpt new file mode 100644 index 0000000000000..26cc08386107b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/object_reference.phpt @@ -0,0 +1,37 @@ +--TEST-- +Attempting to obtain reference of object of private(set) object returns a copy instead +--FILE-- +bar = new Bar(); + } +} + +class Bar {} + +function test() { + $foo = new Foo(); + $bar = &$foo->bar; + var_dump($foo); +} + +test(); +// Test zend_fetch_property_address with warmed cache +test(); + +?> +--EXPECT-- +object(Foo)#1 (1) { + ["bar"]=> + object(Bar)#2 (0) { + } +} +object(Foo)#2 (1) { + ["bar"]=> + object(Bar)#1 (0) { + } +} diff --git a/Zend/tests/asymmetric_visibility/override_private_public.phpt b/Zend/tests/asymmetric_visibility/override_private_public.phpt new file mode 100644 index 0000000000000..122c6efbda633 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_private_public.phpt @@ -0,0 +1,16 @@ +--TEST-- +private(set) property is implicitly final +--FILE-- + +--EXPECTF-- +Fatal error: Cannot override final property A::$foo in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_protected_private.phpt b/Zend/tests/asymmetric_visibility/override_protected_private.phpt new file mode 100644 index 0000000000000..958e886dd807f --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_protected_private.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten protected asymmetric property with private asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be protected(set) (as in class A) or weaker in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_protected_public.phpt b/Zend/tests/asymmetric_visibility/override_protected_public.phpt new file mode 100644 index 0000000000000..36890c50b4b5e --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_protected_public.phpt @@ -0,0 +1,20 @@ +--TEST-- +Overwritten protected asymmetric property with public property +--FILE-- +foo = 'foo'; +echo $b->foo, "\n"; + +?> +--EXPECT-- +foo diff --git a/Zend/tests/asymmetric_visibility/override_public_private.phpt b/Zend/tests/asymmetric_visibility/override_public_private.phpt new file mode 100644 index 0000000000000..f1b2191ac16d4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_public_private.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten public property with private asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be omitted (as in class A) in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/override_public_protected.phpt b/Zend/tests/asymmetric_visibility/override_public_protected.phpt new file mode 100644 index 0000000000000..5611d368b19d4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/override_public_protected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Overwritten public property with protected asymmetric property +--FILE-- + +--EXPECTF-- +Fatal error: Set access level of B::$foo must be omitted (as in class A) in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/private.phpt b/Zend/tests/asymmetric_visibility/private.phpt new file mode 100644 index 0000000000000..48e557c6e87d3 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/private.phpt @@ -0,0 +1,61 @@ +--TEST-- +Asymmetric visibility private(set) +--FILE-- +bar = $bar; + } + + public function setBaz($baz) { + $this->baz = $baz; + } +} + +class FooChild extends Foo { + public function modifyBar($bar) { + $this->bar = $bar; + } +} + +$foo = new Foo(); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBar('baz'); +var_dump($foo->bar); + +try { + $foo->baz = 'baz2'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBaz('baz2'); +var_dump($foo->baz); + +$child = new FooChild(); +try { + $child->modifyBar('baz'); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +string(3) "bar" +Cannot modify private(set) property Foo::$bar from global scope +string(3) "baz" +Cannot modify private(set) property Foo::$baz from global scope +string(4) "baz2" +Cannot modify private(set) property Foo::$bar from scope FooChild diff --git a/Zend/tests/asymmetric_visibility/protected.phpt b/Zend/tests/asymmetric_visibility/protected.phpt new file mode 100644 index 0000000000000..49a39b399362b --- /dev/null +++ b/Zend/tests/asymmetric_visibility/protected.phpt @@ -0,0 +1,66 @@ +--TEST-- +Asymmetric visibility protected(set) +--FILE-- +bar = $bar; + } + + public function setBazPrivate($baz) { + $this->baz = $baz; + } +} + +class FooChild extends Foo { + public function setBarProtected($bar) { + $this->bar = $bar; + } + + public function setBazProtected($baz) { + $this->baz = $baz; + } +} + +$foo = new FooChild(); +var_dump($foo->bar); + +try { + $foo->bar = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setBarPrivate('baz'); +var_dump($foo->bar); + +$foo->setBarProtected('qux'); +var_dump($foo->bar); + +try { + $foo->baz = 'baz'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$foo->setbazPrivate('baz2'); +var_dump($foo->baz); + +$foo->setbazProtected('baz3'); +var_dump($foo->baz); + + +?> +--EXPECT-- +string(3) "bar" +Cannot modify protected(set) property Foo::$bar from global scope +string(3) "baz" +string(3) "qux" +Cannot modify protected(set) property Foo::$baz from global scope +string(4) "baz2" +string(4) "baz3" diff --git a/Zend/tests/asymmetric_visibility/readonly.phpt b/Zend/tests/asymmetric_visibility/readonly.phpt new file mode 100644 index 0000000000000..8fa77aafb1d9f --- /dev/null +++ b/Zend/tests/asymmetric_visibility/readonly.phpt @@ -0,0 +1,62 @@ +--TEST-- +Asymmetric visibility with readonly +--FILE-- +pDefault = 1; + $this->pPrivate = 1; + $this->pProtected = 1; + $this->pPublic = 1; + } +} + +class C extends P { + public function __construct() { + $this->pDefault = 1; + try { + $this->pPrivate = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + $this->pProtected = 1; + $this->pPublic = 1; + } +} + +function test() { + $p = new ReflectionClass(P::class)->newInstanceWithoutConstructor(); + try { + $p->pDefault = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + $p->pPrivate = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + $p->pProtected = 1; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + $p->pPublic = 1; +} + +new P(); +new C(); +test(); + +?> +--EXPECT-- +Cannot modify private(set) property P::$pPrivate from scope C +Cannot modify protected(set) property P::$pDefault from global scope +Cannot modify private(set) property P::$pPrivate from global scope +Cannot modify protected(set) property P::$pProtected from global scope diff --git a/Zend/tests/asymmetric_visibility/reference.phpt b/Zend/tests/asymmetric_visibility/reference.phpt new file mode 100644 index 0000000000000..ae5271418282a --- /dev/null +++ b/Zend/tests/asymmetric_visibility/reference.phpt @@ -0,0 +1,32 @@ +--TEST-- +Asymmetric visibility reference +--FILE-- +bar; + $bar++; + } +} + +$foo = new Foo(); + +try { + $bar = &$foo->bar; + $bar++; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar); + +$foo->test(); +var_dump($foo->bar); + +?> +--EXPECT-- +Cannot indirectly modify private(set) property Foo::$bar from global scope +int(0) +int(1) diff --git a/Zend/tests/asymmetric_visibility/reference_2.phpt b/Zend/tests/asymmetric_visibility/reference_2.phpt new file mode 100644 index 0000000000000..d4ef6c03a7889 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/reference_2.phpt @@ -0,0 +1,30 @@ +--TEST-- +Asymmetric visibility reference in forbidden scope +--FILE-- +prop; + $prop = 42; +} + +try { + test(new C()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +try { + test(new C()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot indirectly modify private(set) property C::$prop from global scope +Cannot indirectly modify private(set) property C::$prop from global scope diff --git a/Zend/tests/asymmetric_visibility/scope_rebinding.phpt b/Zend/tests/asymmetric_visibility/scope_rebinding.phpt new file mode 100644 index 0000000000000..8c10d10f77a42 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/scope_rebinding.phpt @@ -0,0 +1,36 @@ +--TEST-- +Changing scope with Closure::bindTo() does not confuse asymmetric visibility +--FILE-- +bar++; +}; + +($c->bindTo(null, Foo::class))(); +var_dump($foo->bar); +try { + $c(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + ($c->bindTo(null, Bar::class))(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar); + +?> +--EXPECT-- +int(2) +Cannot modify private(set) property Foo::$bar from global scope +Cannot modify private(set) property Foo::$bar from scope Bar +int(2) diff --git a/Zend/tests/asymmetric_visibility/unset.phpt b/Zend/tests/asymmetric_visibility/unset.phpt new file mode 100644 index 0000000000000..3fd3d76730810 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/unset.phpt @@ -0,0 +1,67 @@ +--TEST-- +Asymmetric visibility unset protected(set) +--FILE-- +bar = $bar; + } + + public function setSecret($s) { + $this->secret = $s; + } + + public function unsetBarPrivate() { + unset($this->bar); + } +} + +class FooChild extends Foo { + public function unsetBarProtected() { + unset($this->bar); + } + + public function unsetSecret() { + unset($this->secret); + } +} + +$foo = new FooChild(); + +$foo->setBar('bar'); +try { + unset($foo->bar); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->bar ?? 'unset'); + +$foo->setBar('bar'); +$foo->unsetBarPrivate(); +var_dump($foo->bar ?? 'unset'); + +$foo->setBar('bar'); +$foo->unsetBarProtected(); +var_dump($foo->bar ?? 'unset'); + +$foo->setSecret('beep'); +try { + $foo->unsetSecret(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($foo->secret ?? 'unset'); + +?> +--EXPECT-- +Cannot unset protected(set) property Foo::$bar from global scope +string(3) "bar" +string(5) "unset" +string(5) "unset" +Cannot unset private(set) property Foo::$secret from scope FooChild +string(4) "beep" diff --git a/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt b/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt new file mode 100644 index 0000000000000..d81f4d3891bf4 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/unshared_rw_cache_slot.phpt @@ -0,0 +1,37 @@ +--TEST-- +R/w cache slots should be unshared +--FILE-- +bar); + $this->bar = $bar; + } +} + +$c = new C(); +try { + $c->setBar(1); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + $c->setBar(1); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($c); + +?> +--EXPECTF-- +Typed property P::$bar must not be accessed before initialization +Typed property P::$bar must not be accessed before initialization +object(C)#%d (0) { + ["bar"]=> + uninitialized(string) +} diff --git a/Zend/tests/asymmetric_visibility/variation.phpt b/Zend/tests/asymmetric_visibility/variation.phpt new file mode 100644 index 0000000000000..03cac375f7126 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/variation.phpt @@ -0,0 +1,134 @@ +--TEST-- +Asymmetric visibility variations +--FILE-- +prop = 1; + $this->array = []; + } + + public function r() { + echo $this->prop; + } + + public function w() { + $this->prop = 1; + echo 'done'; + } + + public function rw() { + $this->prop += 1; + echo 'done'; + } + + public function im() { + $this->array[] = 1; + echo 'done'; + } + + public function is() { + echo (int) isset($this->prop); + } + + public function us() { + unset($this->prop); + echo 'done'; + } + + public function us_dim() { + unset($this->array[0]); + echo 'done'; + } +} + +function r($test) { + echo $test->prop; +} + +function w($test) { + $test->prop = 0; + echo 'done'; +} + +function rw($test) { + $test->prop += 1; + echo 'done'; +} + +function im($test) { + $test->array[] = 1; + echo 'done'; +} + +function is($test) { + echo (int) isset($test->prop); +} + +function us($test) { + unset($test->prop); + echo 'done'; +} + +function us_dim($test) { + unset($test->array[0]); + echo 'done'; +} + +foreach ([true, false] as $init) { + foreach ([true, false] as $scope) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { + $test = new Test(); + if ($init) { + $test->init(); + } + + echo 'Init: ' . ((int) $init) . ', scope: ' . ((int) $scope) . ', op: ' . $op . ": "; + try { + if ($scope) { + $test->{$op}(); + } else { + $op($test); + } + } catch (Error $e) { + echo $e->getMessage(); + } + echo "\n"; + } + } +} + +?> +--EXPECT-- +Init: 1, scope: 1, op: r: 1 +Init: 1, scope: 1, op: w: done +Init: 1, scope: 1, op: rw: done +Init: 1, scope: 1, op: im: done +Init: 1, scope: 1, op: is: 1 +Init: 1, scope: 1, op: us: done +Init: 1, scope: 1, op: us_dim: done +Init: 1, scope: 0, op: r: 1 +Init: 1, scope: 0, op: w: Cannot modify private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: rw: Cannot modify private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: im: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 1, scope: 0, op: is: 1 +Init: 1, scope: 0, op: us: Cannot unset private(set) property Test::$prop from global scope +Init: 1, scope: 0, op: us_dim: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 0, scope: 1, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 1, op: w: done +Init: 0, scope: 1, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 1, op: im: done +Init: 0, scope: 1, op: is: 0 +Init: 0, scope: 1, op: us: done +Init: 0, scope: 1, op: us_dim: done +Init: 0, scope: 0, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 0, op: w: Cannot modify private(set) property Test::$prop from global scope +Init: 0, scope: 0, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, scope: 0, op: im: Cannot indirectly modify private(set) property Test::$array from global scope +Init: 0, scope: 0, op: is: 0 +Init: 0, scope: 0, op: us: Cannot unset private(set) property Test::$prop from global scope +Init: 0, scope: 0, op: us_dim: done diff --git a/Zend/tests/asymmetric_visibility/variation_nested.phpt b/Zend/tests/asymmetric_visibility/variation_nested.phpt new file mode 100644 index 0000000000000..c1dc753a944f1 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/variation_nested.phpt @@ -0,0 +1,84 @@ +--TEST-- +Asymmetric visibility nested variations +--FILE-- +prop = new Inner(); + } +} + +function r($test) { + echo $test->prop->prop; +} + +function w($test) { + $test->prop->prop = 0; + echo 'done'; +} + +function rw($test) { + $test->prop->prop += 1; + echo 'done'; +} + +function im($test) { + $test->prop->array[] = 1; + echo 'done'; +} + +function is($test) { + echo (int) isset($test->prop->prop); +} + +function us($test) { + unset($test->prop->prop); + echo 'done'; +} + +function us_dim($test) { + unset($test->prop->array[0]); + echo 'done'; +} + +foreach ([true, false] as $init) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { + $test = new Test(); + if ($init) { + $test->init(); + } + + echo 'Init: ' . ((int) $init) . ', op: ' . $op . ": "; + try { + $op($test); + } catch (Error $e) { + echo $e->getMessage(); + } + echo "\n"; + } +} + +?> +--EXPECT-- +Init: 1, op: r: 1 +Init: 1, op: w: done +Init: 1, op: rw: done +Init: 1, op: im: done +Init: 1, op: is: 1 +Init: 1, op: us: done +Init: 1, op: us_dim: done +Init: 0, op: r: Typed property Test::$prop must not be accessed before initialization +Init: 0, op: w: Cannot indirectly modify private(set) property Test::$prop from global scope +Init: 0, op: rw: Typed property Test::$prop must not be accessed before initialization +Init: 0, op: im: Cannot indirectly modify private(set) property Test::$prop from global scope +Init: 0, op: is: 0 +Init: 0, op: us: done +Init: 0, op: us_dim: done diff --git a/Zend/tests/die_string_cast_exception.phpt b/Zend/tests/die_string_cast_exception.phpt deleted file mode 100644 index 9893c3389f970..0000000000000 --- a/Zend/tests/die_string_cast_exception.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Bug #79777: String cast exception during die should be handled gracefully ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught Error: Object of class stdClass could not be converted to string in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d diff --git a/Zend/tests/exit/ast_print_assert_die_const.phpt b/Zend/tests/exit/ast_print_assert_die_const.phpt new file mode 100644 index 0000000000000..7c576666abe4b --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_die_const.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of die "constant" via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_die_function.phpt b/Zend/tests/exit/ast_print_assert_die_function.phpt new file mode 100644 index 0000000000000..c83aff6692738 --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_die_function.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of die function via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_exit_const.phpt b/Zend/tests/exit/ast_print_assert_exit_const.phpt new file mode 100644 index 0000000000000..2f52ee37a42da --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_exit_const.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of exit "constant" via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/ast_print_assert_exit_function.phpt b/Zend/tests/exit/ast_print_assert_exit_function.phpt new file mode 100644 index 0000000000000..e5fd5635faec0 --- /dev/null +++ b/Zend/tests/exit/ast_print_assert_exit_function.phpt @@ -0,0 +1,16 @@ +--TEST-- +Printing AST of exit function via assert +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +AssertionError: assert(0 && \exit()) diff --git a/Zend/tests/exit/define_class_members_exit_die.phpt b/Zend/tests/exit/define_class_members_exit_die.phpt new file mode 100644 index 0000000000000..0a3816dc0d065 --- /dev/null +++ b/Zend/tests/exit/define_class_members_exit_die.phpt @@ -0,0 +1,37 @@ +--TEST-- +Can define die and exit as class methods, constants and property +--FILE-- +exit); +var_dump($o->die); +var_dump($o->exit()); +var_dump($o->die()); + +?> +--EXPECT-- +int(5) +int(10) +NULL +NULL +int(20) +int(15) diff --git a/Zend/tests/exit/define_die_constant.phpt b/Zend/tests/exit/define_die_constant.phpt new file mode 100644 index 0000000000000..393904d9356dd --- /dev/null +++ b/Zend/tests/exit/define_die_constant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define die constant +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_die_constant_namespace.phpt b/Zend/tests/exit/define_die_constant_namespace.phpt new file mode 100644 index 0000000000000..b68038ba10fb7 --- /dev/null +++ b/Zend/tests/exit/define_die_constant_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define die constant in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_die_function.phpt b/Zend/tests/exit/define_die_function.phpt new file mode 100644 index 0000000000000..4ea41d6ced5bd --- /dev/null +++ b/Zend/tests/exit/define_die_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Attempting to define die() function +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_die_function_namespace.phpt b/Zend/tests/exit/define_die_function_namespace.phpt new file mode 100644 index 0000000000000..fece46cb7acd6 --- /dev/null +++ b/Zend/tests/exit/define_die_function_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define die() function in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_exit_constant.phpt b/Zend/tests/exit/define_exit_constant.phpt new file mode 100644 index 0000000000000..33cd073401223 --- /dev/null +++ b/Zend/tests/exit/define_exit_constant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define exit constant +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_exit_constant_namespace.phpt b/Zend/tests/exit/define_exit_constant_namespace.phpt new file mode 100644 index 0000000000000..8d0097bb9da3c --- /dev/null +++ b/Zend/tests/exit/define_exit_constant_namespace.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define exit constant in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_exit_function.phpt b/Zend/tests/exit/define_exit_function.phpt new file mode 100644 index 0000000000000..4c406ef0d8905 --- /dev/null +++ b/Zend/tests/exit/define_exit_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Attempting to define exit() function +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_exit_function_namespace.phpt b/Zend/tests/exit/define_exit_function_namespace.phpt new file mode 100644 index 0000000000000..9ea785b0e53ba --- /dev/null +++ b/Zend/tests/exit/define_exit_function_namespace.phpt @@ -0,0 +1,12 @@ +--TEST-- +Attempting to define exit() function in a namespace +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_die.phpt b/Zend/tests/exit/define_goto_label_die.phpt new file mode 100644 index 0000000000000..b94ee13fa0abe --- /dev/null +++ b/Zend/tests/exit/define_goto_label_die.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called die +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token ":" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_die_with_jump.phpt b/Zend/tests/exit/define_goto_label_die_with_jump.phpt new file mode 100644 index 0000000000000..fc755d52a5794 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_die_with_jump.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called die and jump to it +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_exit.phpt b/Zend/tests/exit/define_goto_label_exit.phpt new file mode 100644 index 0000000000000..a72b6bac2d2a4 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_exit.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called exit +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token ":" in %s on line %d diff --git a/Zend/tests/exit/define_goto_label_exit_with_jump.phpt b/Zend/tests/exit/define_goto_label_exit_with_jump.phpt new file mode 100644 index 0000000000000..a810f2c44c2d8 --- /dev/null +++ b/Zend/tests/exit/define_goto_label_exit_with_jump.phpt @@ -0,0 +1,14 @@ +--TEST-- +Attempting to define a goto label called exit and jump to it +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d diff --git a/Zend/tests/exit/die_string_cast_exception.phpt b/Zend/tests/exit/die_string_cast_exception.phpt new file mode 100644 index 0000000000000..c20a873939dfa --- /dev/null +++ b/Zend/tests/exit/die_string_cast_exception.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #79777: String cast exception during die should be handled gracefully +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +exit(): Argument #1 ($status) must be of type string|int, stdClass given diff --git a/Zend/tests/exit/disabling_die.phpt b/Zend/tests/exit/disabling_die.phpt new file mode 100644 index 0000000000000..8d84067a9abda --- /dev/null +++ b/Zend/tests/exit/disabling_die.phpt @@ -0,0 +1,12 @@ +--TEST-- +Using disable_functions INI to remove die +--INI-- +disable_functions=die +--FILE-- + +--EXPECT-- +Warning: Cannot disable function die() in Unknown on line 0 diff --git a/Zend/tests/exit/disabling_exit.phpt b/Zend/tests/exit/disabling_exit.phpt new file mode 100644 index 0000000000000..a6cf277d38f72 --- /dev/null +++ b/Zend/tests/exit/disabling_exit.phpt @@ -0,0 +1,12 @@ +--TEST-- +Using disable_functions INI to remove exit +--INI-- +disable_functions=exit +--FILE-- + +--EXPECT-- +Warning: Cannot disable function exit() in Unknown on line 0 diff --git a/Zend/tests/exit/exit_as_function.phpt b/Zend/tests/exit/exit_as_function.phpt new file mode 100644 index 0000000000000..fb95b9f288171 --- /dev/null +++ b/Zend/tests/exit/exit_as_function.phpt @@ -0,0 +1,42 @@ +--TEST-- +exit() as function +--FILE-- + +--EXPECT-- +string(4) "exit" +string(3) "die" +object(Closure)#1 (2) { + ["function"]=> + string(4) "exit" + ["parameter"]=> + array(1) { + ["$status"]=> + string(10) "" + } +} +object(Closure)#2 (2) { + ["function"]=> + string(4) "exit" + ["parameter"]=> + array(1) { + ["$status"]=> + string(10) "" + } +} diff --git a/Zend/tests/exit/exit_named_arg.phpt b/Zend/tests/exit/exit_named_arg.phpt new file mode 100644 index 0000000000000..7f7d362c0bdcf --- /dev/null +++ b/Zend/tests/exit/exit_named_arg.phpt @@ -0,0 +1,59 @@ +--TEST-- +Using exit()/die() as function call with a named argument +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' --no-php-ini ' . escapeshellarg(FILE_PATH); + +foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) { + foreach ($values as $value) { + echo 'Using ', var_export($value, true), ' as value:', PHP_EOL; + $output = []; + $content = str_replace('VALUE', var_export($value, true), $code); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; + } +} + +?> +--CLEAN-- + +--EXPECT-- +Using 12 as value: +Exit status is: 12 +Output is: + +Using 'Goodbye!' as value: +Exit status is: 0 +Output is: +Goodbye! +Using 12 as value: +Exit status is: 12 +Output is: + +Using 'Goodbye!' as value: +Exit status is: 0 +Output is: +Goodbye! diff --git a/Zend/tests/exit/exit_statements.phpt b/Zend/tests/exit/exit_statements.phpt new file mode 100644 index 0000000000000..6b3147156709f --- /dev/null +++ b/Zend/tests/exit/exit_statements.phpt @@ -0,0 +1,46 @@ +--TEST-- +Using exit/die as a statement/constant +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' ' . escapeshellarg(FILE_PATH); + +foreach (['exit', 'die'] as $value) { + echo 'Using ', $value, ' as value:', PHP_EOL; + $output = []; + $content = str_replace('FUNCTION', $value, FILE_CONTENT); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; +} + +?> +--CLEAN-- + +--EXPECT-- +Using exit as value: +Exit status is: 0 +Output is: +Before exit +Using die as value: +Exit status is: 0 +Output is: +Before die diff --git a/Zend/tests/exit/exit_string_with_buffer_output.phpt b/Zend/tests/exit/exit_string_with_buffer_output.phpt new file mode 100644 index 0000000000000..a9ed44893cebc --- /dev/null +++ b/Zend/tests/exit/exit_string_with_buffer_output.phpt @@ -0,0 +1,23 @@ +--TEST-- +Throwing output buffer with exit("Message") +--FILE-- +getMessage(), PHP_EOL; +} +echo "After?\n"; + +?> +--EXPECT-- +Handler: Hello world! +Hello world! +Exception: test +After? diff --git a/Zend/tests/exit/exit_values.phpt b/Zend/tests/exit/exit_values.phpt new file mode 100644 index 0000000000000..d3909ff156828 --- /dev/null +++ b/Zend/tests/exit/exit_values.phpt @@ -0,0 +1,183 @@ +--TEST-- +exit(false); +--FILE-- +getMessage(), PHP_EOL; +} + +TEMPLATE; + +$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); +$command = $php . ' --no-php-ini ' . escapeshellarg(FILE_PATH); + +foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) { + foreach ($values as $value) { + echo 'Using ', zend_test_var_export($value), ' as value:', PHP_EOL; + $output = []; + $content = str_replace('VALUE', zend_test_var_export($value), $code); + file_put_contents(FILE_PATH, $content); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; + } + + echo 'As a statement:', PHP_EOL; + $output = []; + $content = str_replace('(VALUE)', '', $code); + exec($command, $output, $exit_status); + echo 'Exit status is: ', $exit_status, PHP_EOL, + 'Output is:', PHP_EOL, join($output), PHP_EOL; +} + +?> +--CLEAN-- + +--EXPECTF-- +Using NULL as value: +Exit status is: 0 +Output is: +Deprecated: exit(): Passing null to parameter #1 ($status) of type string|int is deprecated in %s on line %d +Using false as value: +Exit status is: 0 +Output is: + +Using true as value: +Exit status is: 1 +Output is: + +Using 0 as value: +Exit status is: 0 +Output is: + +Using 1 as value: +Exit status is: 1 +Output is: + +Using 20 as value: +Exit status is: 20 +Output is: + +Using 10.0 as value: +Exit status is: 10 +Output is: + +Using 15.5 as value: +Exit status is: 15 +Output is: +Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d +Using 'Hello world' as value: +Exit status is: 0 +Output is: +Hello world +Using [] as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, array given +Using STDERR as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, resource given +Using new stdClass() as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given +As a statement: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given +Using NULL as value: +Exit status is: 0 +Output is: +Deprecated: exit(): Passing null to parameter #1 ($status) of type string|int is deprecated in %s on line %d +Using false as value: +Exit status is: 0 +Output is: + +Using true as value: +Exit status is: 1 +Output is: + +Using 0 as value: +Exit status is: 0 +Output is: + +Using 1 as value: +Exit status is: 1 +Output is: + +Using 20 as value: +Exit status is: 20 +Output is: + +Using 10.0 as value: +Exit status is: 10 +Output is: + +Using 15.5 as value: +Exit status is: 15 +Output is: +Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d +Using 'Hello world' as value: +Exit status is: 0 +Output is: +Hello world +Using [] as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, array given +Using STDERR as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, resource given +Using new stdClass() as value: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given +As a statement: +Exit status is: 0 +Output is: +TypeError: exit(): Argument #1 ($status) must be of type string|int, stdClass given diff --git a/Zend/tests/gh15330-001.phpt b/Zend/tests/gh15330-001.phpt new file mode 100644 index 0000000000000..dafc31d8b8e22 --- /dev/null +++ b/Zend/tests/gh15330-001.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-15330 001: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$ref = $fiber; + +$fiber->start(); + +gc_collect_cycles(); + +?> +==DONE== +--EXPECT-- +string(3) "foo" +==DONE== diff --git a/Zend/tests/gh15330-002.phpt b/Zend/tests/gh15330-002.phpt new file mode 100644 index 0000000000000..cb2fdc560c5eb --- /dev/null +++ b/Zend/tests/gh15330-002.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-15330 002: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$ref = $fiber; + +$fiber->start(); + +gc_collect_cycles(); + +?> +==DONE== +--EXPECT-- +string(3) "foo" +==DONE== diff --git a/Zend/tests/gh15330-003.phpt b/Zend/tests/gh15330-003.phpt new file mode 100644 index 0000000000000..f4208c544550e --- /dev/null +++ b/Zend/tests/gh15330-003.phpt @@ -0,0 +1,57 @@ +--TEST-- +GH-15330 003: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-004.phpt b/Zend/tests/gh15330-004.phpt new file mode 100644 index 0000000000000..9e971da7f98c9 --- /dev/null +++ b/Zend/tests/gh15330-004.phpt @@ -0,0 +1,52 @@ +--TEST-- +GH-15330 004: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-005.phpt b/Zend/tests/gh15330-005.phpt new file mode 100644 index 0000000000000..774b141baf93b --- /dev/null +++ b/Zend/tests/gh15330-005.phpt @@ -0,0 +1,53 @@ +--TEST-- +GH-15330 005: Do not scan generator frames more than once +--FILE-- +current()); + $f = $iterable->next(...); + $f(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/gh15330-006.phpt b/Zend/tests/gh15330-006.phpt new file mode 100644 index 0000000000000..fb9195663de65 --- /dev/null +++ b/Zend/tests/gh15330-006.phpt @@ -0,0 +1,56 @@ +--TEST-- +GH-15330 006: Do not scan generator frames more than once +--FILE-- +current()); + $iterable->next(); + var_dump("not executed"); +}); + +$canary->value = $fiber; + +$fiber->start(); + +$iterable->current(); + +$fiber = $iterable = $canary = null; + +gc_collect_cycles(); + +?> +==DONE== +--EXPECTF-- +object(Canary)#%d (1) { + ["value"]=> + object(Fiber)#%d (0) { + } +} +string(3) "foo" +string(18) "Canary::__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/clone_calls___clone_once.phpt b/Zend/tests/lazy_objects/clone_calls___clone_once.phpt new file mode 100644 index 0000000000000..c0f91e3e27a42 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_calls___clone_once.phpt @@ -0,0 +1,77 @@ +--TEST-- +Lazy objects: clone calls __clone() once +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(5) "clone" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +string(5) "clone" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt new file mode 100644 index 0000000000000..10aab3da023b3 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_001.phpt @@ -0,0 +1,35 @@ +--TEST-- +Lazy objects: clone is independant of the original object +--FILE-- +newLazyProxy($initializer); +$reflector->getProperty('foo')->skipLazyInitialization($myProxy); + +$clonedProxy = clone $myProxy; +var_dump($clonedProxy->foo); + +$reflector->initializeLazyObject($myProxy); +$myProxy->foo = 'B'; + +$reflector->initializeLazyObject($clonedProxy); + +var_dump($myProxy->foo); +var_dump($clonedProxy->foo); + +--EXPECT-- +string(1) "A" +string(1) "B" +string(1) "A" diff --git a/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_002.phpt b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_002.phpt new file mode 100644 index 0000000000000..8b0016f1e9860 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_002.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: clone is independant of the original object +--FILE-- +value = new Value(); + } + public function __clone() { + $this->value = clone $this->value; + } +} + +class Value { + public string $value = 'A'; +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass(SomeObj::class); + + $clonedObj = clone $obj; + var_dump($clonedObj->value->value); + + $reflector->initializeLazyObject($obj); + $obj->value->value = 'B'; + + $reflector->initializeLazyObject($clonedObj); + + var_dump($obj->value->value); + var_dump($clonedObj->value->value); +} + +$reflector = new ReflectionClass(SomeObj::class); + +test('Ghost', $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +})); + +test('Proxy', $reflector->newLazyProxy(function () { + return new SomeObj(); +})); + +?> +--EXPECT-- +# Ghost: +string(1) "A" +string(1) "B" +string(1) "A" +# Proxy: +string(1) "A" +string(1) "B" +string(1) "A" diff --git a/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_003.phpt b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_003.phpt new file mode 100644 index 0000000000000..04d61d7834ca6 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_creates_object_with_independent_state_003.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: clone is independant of the original object +--FILE-- +initializeLazyObject($obj); + $reflector->getProperty('foo')->setRawValueWithoutLazyInitialization($clonedObj, 'Y'); + + $reflector->initializeLazyObject($clonedObj); + + var_dump($clonedObj->foo); +} + +$reflector = new ReflectionClass(SomeObj::class); + +test('Ghost', $reflector->newLazyGhost(function ($obj) { +})); + +test('Proxy', $reflector->newLazyProxy(function () { + return new SomeObj(); +})); + +?> +--EXPECT-- +# Ghost: +string(1) "Y" +# Proxy: +string(1) "Y" diff --git a/Zend/tests/lazy_objects/clone_initialized.phpt b/Zend/tests/lazy_objects/clone_initialized.phpt new file mode 100644 index 0000000000000..9540a0f960964 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_initialized.phpt @@ -0,0 +1,73 @@ +--TEST-- +Lazy objects: clone of initialized lazy object does not initialize twice +--FILE-- +initializeLazyObject($obj); + + $clone = clone $obj; + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_initializer_exception.phpt b/Zend/tests/lazy_objects/clone_initializer_exception.phpt new file mode 100644 index 0000000000000..72069ca650d12 --- /dev/null +++ b/Zend/tests/lazy_objects/clone_initializer_exception.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: clone: initializer exception +--FILE-- +getMessage()); + } + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +Exception: initializer +bool(true) +lazy ghost object(C)#%d (0) { +} +# Proxy: +Exception: initializer +bool(true) +lazy proxy object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/clone_initializes.phpt b/Zend/tests/lazy_objects/clone_initializes.phpt new file mode 100644 index 0000000000000..54be97fd768aa --- /dev/null +++ b/Zend/tests/lazy_objects/clone_initializes.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: clone initializes object +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/clone_preverves_object_class.phpt b/Zend/tests/lazy_objects/clone_preverves_object_class.phpt new file mode 100644 index 0000000000000..40dfbab6ddaee --- /dev/null +++ b/Zend/tests/lazy_objects/clone_preverves_object_class.phpt @@ -0,0 +1,36 @@ +--TEST-- +Lazy objects: clone returns an object of the same class +--FILE-- +foo(); } + +$r = new ReflectionClass(B::class); +$b = $r->newLazyProxy(function ($obj) { + return new A('value'); +}); + +$b->property = 'init_please'; + +$clone = clone $b; +only_b($b); +only_b($clone); + +var_dump($b::class); +var_dump($clone::class); + +?> +==DONE== +--EXPECT-- +string(1) "B" +string(1) "B" +==DONE== diff --git a/Zend/tests/lazy_objects/convert_to_array.phpt b/Zend/tests/lazy_objects/convert_to_array.phpt new file mode 100644 index 0000000000000..72eb3fd4f670e --- /dev/null +++ b/Zend/tests/lazy_objects/convert_to_array.phpt @@ -0,0 +1,93 @@ +--TEST-- +Lazy objects: Convertion to array +--FILE-- +a = 1; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 3); + + $a = []; + // Converts $obj to array internally + array_splice($a, 0, 0, $obj); + var_dump($a, $obj); + + $reflector->initializeLazyObject($obj); + + $a = []; + array_splice($a, 0, 0, $obj); + var_dump($a, $obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +array(1) { + [0]=> + int(3) +} +lazy ghost object(C)#%d (1) { + ["a"]=> + int(3) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy +array(1) { + [0]=> + int(3) +} +lazy proxy object(C)#%d (1) { + ["a"]=> + int(3) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/dtor_called_if_init.phpt b/Zend/tests/lazy_objects/dtor_called_if_init.phpt new file mode 100644 index 0000000000000..19a9c7b941b00 --- /dev/null +++ b/Zend/tests/lazy_objects/dtor_called_if_init.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: destructor of initialized objets is called +--FILE-- +newLazyGhost(function () { + var_dump("initializer"); + }); + print "After makeLazy\n"; + + var_dump($obj->a); +} + +function proxy() { + $reflector = new ReflectionClass(C::class); + + print "# Proxy:\n"; + + print "In makeLazy\n"; + $obj = $reflector->newLazyProxy(function () { + var_dump("initializer"); + return new C(); + }); + print "After makeLazy\n"; + + var_dump($obj->a); +} + +ghost(); +proxy(); + +--EXPECTF-- +# Ghost: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt new file mode 100644 index 0000000000000..f0ea2fdfc1ba2 --- /dev/null +++ b/Zend/tests/lazy_objects/dtor_not_called_if_not_init.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: destructor of lazy objets is not called if not initialized +--FILE-- +newLazyGhost(function () { + var_dump("initializer"); +}); +print "After newLazyGhost\n"; + +// Does not call destructor +$obj = null; + +print "# Proxy:\n"; + +print "In newLazyProxy\n"; +$obj = $reflector->newLazyProxy(function () { + var_dump("initializer"); +}); +print "After newLazyGhost\n"; + +// Does not call destructor +$obj = null; + +--EXPECT-- +# Ghost: +In newLazyGhost +After newLazyGhost +# Proxy: +In newLazyProxy +After newLazyGhost diff --git a/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt new file mode 100644 index 0000000000000..f2a4123c1b2ac --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_coalesce_initializes.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: property fetch coalesce initializes object +--FILE-- +a ?? null); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt new file mode 100644 index 0000000000000..1ac947f93d65e --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_coalesce_non_existing_initializes.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: property fetch coalesce on non existing property initializes object +--FILE-- +unknown ?? null); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt new file mode 100644 index 0000000000000..da3540bacc578 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_declared_prop_initializes.phpt @@ -0,0 +1,72 @@ +--TEST-- +Lazy objects: property fetch initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt new file mode 100644 index 0000000000000..a8171bcd6eb6c --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_dynamic_prop_initializes.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property fetch of dynamic property initializes object +--FILE-- +dynamic); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (0) { + ["a"]=> + uninitialized(int) + } +} diff --git a/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt new file mode 100644 index 0000000000000..b81635dfb9c84 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_hook_may_not_initialize.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: hooked property fetch does not initialize object if hook does not observe object state +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt new file mode 100644 index 0000000000000..f66f9a34a680b --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_initialize.phpt @@ -0,0 +1,76 @@ +--TEST-- +Lazy objects: virtual hooked property fetch may initialize object if hook observes object state +--FILE-- +_a; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->_a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $a = &$obj->a; + var_dump($a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (2) { + ["_a"]=> + &int(1) + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["_a"]=> + &int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt new file mode 100644 index 0000000000000..adf3c2845f21a --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_hook_virtual_may_not_initialize.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: virtual hooked property fetch does not initialize object if hook does not observe object state +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +int(1) +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +int(1) +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt new file mode 100644 index 0000000000000..491b26dbbee82 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_initialize.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: magic property fetch initializes object if magic method observes object state +--FILE-- +a; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->magic); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt new file mode 100644 index 0000000000000..3cd283705ab2b --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_magic_prop_may_not_initialize.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: magic property fetch does not not initialize object if magic method does not observe object state +--FILE-- +magic); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(5) "magic" +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(5) "magic" +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt new file mode 100644 index 0000000000000..db605826f64e5 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_magic_prop_recursive_may_initialize.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: recursive magic property fetch initializes object if magic method observes object state +--FILE-- +$name; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->magic); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" + +Warning: Undefined property: C::$magic in %s on line %d +NULL +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" + +Warning: Undefined property: C::$magic in %s on line %d +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt new file mode 100644 index 0000000000000..f6f4cddedc63e --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: dynamic property op error +--FILE-- +dynamic++); + } catch(Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new Error("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new Error("initializer"); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt new file mode 100644 index 0000000000000..3f9af1aa5f1dd --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_op_dynamic_prop_initializes.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: dynamic property op initializes object +--FILE-- +dynamic++); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +object(C)#%d (2) { + ["a"]=> + int(1) + ["dynamic"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["dynamic"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_op_error.phpt b/Zend/tests/lazy_objects/fetch_op_error.phpt new file mode 100644 index 0000000000000..4ccfef4ac4d3a --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_op_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: property op error +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + + try { + var_dump($obj->a++); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new Error("initializer"); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new Error("initializer"); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +Error: initializer +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_op_initializes.phpt b/Zend/tests/lazy_objects/fetch_op_initializes.phpt new file mode 100644 index 0000000000000..d1a8605eb1d7f --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_op_initializes.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property op initializes object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump($obj->a++); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%s (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt new file mode 100644 index 0000000000000..c1e662eaef1a3 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_op_skipped_prop_does_not_initialize.phpt @@ -0,0 +1,91 @@ +--TEST-- +Lazy objects: property op on skipped property does not initialize object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + var_dump($obj->a++); + var_dump($obj->b++); + try { + var_dump($obj->c++); + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new c(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + uninitialized(int) +} +# Proxy: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/fetch_ref_initializes.phpt b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt new file mode 100644 index 0000000000000..e1289558aaa77 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_ref_initializes.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: property fetch ref initializes object +--FILE-- +a; + var_dump($ref); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + &int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + &int(1) + } +} diff --git a/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt new file mode 100644 index 0000000000000..c64cd88781a31 --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_ref_skipped_prop_does_not_initialize.phpt @@ -0,0 +1,87 @@ +--TEST-- +Lazy objects: fetch ref on skipped property does not initialize object +--FILE-- +a; + $ref = &$obj->b; + try { + $ref = &$obj->c; + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($ref); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +Cannot access uninitialized non-nullable property C::$c by reference +int(1) +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + &int(1) + ["c"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +Cannot access uninitialized non-nullable property C::$c by reference +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + &int(1) + ["c"]=> + uninitialized(int) + } +} diff --git a/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt new file mode 100644 index 0000000000000..e93a65ee87cec --- /dev/null +++ b/Zend/tests/lazy_objects/fetch_skipped_prop_does_not_initialize.phpt @@ -0,0 +1,93 @@ +--TEST-- +Lazy objects: fetch skipped property does not initialize object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + var_dump($obj->a); + var_dump($obj->b); + try { + var_dump($obj->c); + } catch (Error $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +# Proxy: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +NULL +int(1) +Typed property C::$c must not be accessed before initialization +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt new file mode 100644 index 0000000000000..2434e69f57349 --- /dev/null +++ b/Zend/tests/lazy_objects/final_classes_can_be_initialized_lazily.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: final classes can be initialized lazily +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/gc_001.phpt b/Zend/tests/lazy_objects/gc_001.phpt new file mode 100644 index 0000000000000..7707423815a5b --- /dev/null +++ b/Zend/tests/lazy_objects/gc_001.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: GC 001 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +function proxy() { + printf("# Proxy:\n"); + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +ghost(); +proxy(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Proxy: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_002.phpt b/Zend/tests/lazy_objects/gc_002.phpt new file mode 100644 index 0000000000000..c794e4077c2bc --- /dev/null +++ b/Zend/tests/lazy_objects/gc_002.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: GC 002 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary->value = $obj; + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +function proxy() { + printf("# Proxy:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary->value = $obj; + $canary = null; + $obj = null; + + gc_collect_cycles(); +} + +ghost(); +proxy(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Proxy: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_003.phpt b/Zend/tests/lazy_objects/gc_003.phpt new file mode 100644 index 0000000000000..ce58398e509e3 --- /dev/null +++ b/Zend/tests/lazy_objects/gc_003.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: GC 003 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function proxy() { + printf("# Proxy:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +proxy(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Proxy: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_004.phpt b/Zend/tests/lazy_objects/gc_004.phpt new file mode 100644 index 0000000000000..ab0b5c2996770 --- /dev/null +++ b/Zend/tests/lazy_objects/gc_004.phpt @@ -0,0 +1,67 @@ +--TEST-- +Lazy objects: GC 004 +--FILE-- +newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyGhost($obj, function () use ($canary) { + }); + + var_dump($obj); // initializes property hash + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function proxy() { + printf("# Proxy:\n"); + + $canary = new Canary(); + + $obj = (new ReflectionClass(C::class))->newInstanceWithoutConstructor(); + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + var_dump($obj); // initializes property hash + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +proxy(); + +?> +==DONE== +--EXPECTF-- +# Ghost: +object(C)#%d (0) { +} +string(10) "__destruct" +# Proxy: +object(C)#%d (0) { +} +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_005.phpt b/Zend/tests/lazy_objects/gc_005.phpt new file mode 100644 index 0000000000000..934439adab951 --- /dev/null +++ b/Zend/tests/lazy_objects/gc_005.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: GC 005 +--FILE-- +newInstanceWithoutConstructor(); + $reflector->resetAsLazyGhost($obj, function () use ($canary) { + }); + + $reflector->getProperty('value')->setRawValueWithoutLazyInitialization($obj, $obj); + $reflector = null; + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +function proxy() { + printf("# Proxy:\n"); + + $canary = new Canary(); + + $reflector = new ReflectionClass(C::class); + $obj = $reflector->newInstanceWithoutConstructor(); + $reflector->resetAsLazyProxy($obj, function () use ($canary) { + return new C(); + }); + + $reflector->getProperty('value')->setRawValueWithoutLazyInitialization($obj, $obj); + $reflector = null; + + $canary->value = $obj; + $obj = null; + $canary = null; + + gc_collect_cycles(); +} + +ghost(); +proxy(); + +?> +==DONE== +--EXPECT-- +# Ghost: +string(10) "__destruct" +# Proxy: +string(10) "__destruct" +==DONE== diff --git a/Zend/tests/lazy_objects/gc_006.phpt b/Zend/tests/lazy_objects/gc_006.phpt new file mode 100644 index 0000000000000..e1002ffea7108 --- /dev/null +++ b/Zend/tests/lazy_objects/gc_006.phpt @@ -0,0 +1,36 @@ +--TEST-- +Lazy objects: GC 006 +--FILE-- +foo = $this; + var_dump(__METHOD__); + } + public function __destruct() { + var_dump(__METHOD__); + } +} + +$reflector = new ReflectionClass(Foo::class); +$foo = $reflector->newLazyGhost(new Initializer()); + +print "Dump\n"; + +var_dump($foo->foo); + +print "Done\n"; + +?> +--EXPECTF-- +Dump +string(21) "Initializer::__invoke" +object(Initializer)#%d (0) { +} +Done +string(23) "Initializer::__destruct" diff --git a/Zend/tests/lazy_objects/get_initializer.phpt b/Zend/tests/lazy_objects/get_initializer.phpt new file mode 100644 index 0000000000000..30b410be0a6f9 --- /dev/null +++ b/Zend/tests/lazy_objects/get_initializer.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: getLazyInitializer() returns initializer +--FILE-- +init(...), +]; + +foreach ($initializers as $i => $initializer) { + $c = $reflector->newLazyGhost($initializer); + if ($reflector->getLazyInitializer($c) !== $initializer) { + printf("Initializer %d: failed\n", $i); + continue; + } + + $reflector->initializeLazyObject($c); + if ($reflector->getLazyInitializer($c) !== null) { + printf("Initializer %d: failed\n", $i); + continue; + } + + printf("Initializer %d: ok\n", $i); +} + +?> +--EXPECT-- +Initializer 0: ok +Initializer 1: ok +Initializer 2: ok +Initializer 3: ok +Initializer 4: ok +Initializer 5: ok +Initializer 6: ok diff --git a/Zend/tests/lazy_objects/get_properties.phpt b/Zend/tests/lazy_objects/get_properties.phpt new file mode 100644 index 0000000000000..38b752c2f8b5b --- /dev/null +++ b/Zend/tests/lazy_objects/get_properties.phpt @@ -0,0 +1,27 @@ +--TEST-- +Lazy objects: get_properties failure +--FILE-- +newLazyProxy(function () { + throw new \Exception('Initializer'); +}); + +$b = new C(); + +try { + var_dump($a > $b); +} catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECT-- +Exception: Initializer diff --git a/Zend/tests/lazy_objects/init_ast_const.phpt b/Zend/tests/lazy_objects/init_ast_const.phpt new file mode 100644 index 0000000000000..018c46e4915e5 --- /dev/null +++ b/Zend/tests/lazy_objects/init_ast_const.phpt @@ -0,0 +1,27 @@ +--TEST-- +Lazy objects: Class constants are updated before initialization +--FILE-- +newLazyGhost(function () { }); + +function f() { + define('FOO', new stdClass); +} + +f(); + +try { + var_dump($c->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/init_ast_const_failure.phpt b/Zend/tests/lazy_objects/init_ast_const_failure.phpt new file mode 100644 index 0000000000000..d3f1ca0f35f5c --- /dev/null +++ b/Zend/tests/lazy_objects/init_ast_const_failure.phpt @@ -0,0 +1,26 @@ +--TEST-- +Lazy objects: Class constants are updated before initialization: update constant failure +--FILE-- +newLazyGhost(function () { }); + +function f() { + define('FOO', new stdClass); +} + +f(); + +try { + var_dump($c->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +TypeError: Cannot assign stdClass to property C::$a of type C diff --git a/Zend/tests/lazy_objects/init_exception_001.phpt b/Zend/tests/lazy_objects/init_exception_001.phpt new file mode 100644 index 0000000000000..81469b9992d6b --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_001.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: init exception 001 +--FILE-- +newLazyGhost(function ($obj) use ($i) { + if ($i === 1) { + throw new \Exception(); + } + }); + $obj->c = 1; +} + +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(Object(C)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt b/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt new file mode 100644 index 0000000000000..86ecc2c9b8e2e --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_leaves_object_lazy.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: Object is still lazy after initializer exception +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +initializer exception +Is lazy: 1 +# Proxy: +string(11) "initializer" +initializer exception +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt new file mode 100644 index 0000000000000..4edf9481ebc22 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt @@ -0,0 +1,74 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Proxy: +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt new file mode 100644 index 0000000000000..ce94fc8b2ab79 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt @@ -0,0 +1,79 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (dynamic properties) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Proxy: +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (4) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) + ["d"]=> + int(6) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt new file mode 100644 index 0000000000000..1bc3eb2cea8e1 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt @@ -0,0 +1,86 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (dynamic properties, initialized hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $obj->d = 6; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Proxy: +array(0) { +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (4) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) + ["d"]=> + int(6) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt new file mode 100644 index 0000000000000..535f93e65f63f --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_nested.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (nested) +--FILE-- +newLazyGhost(function ($c) { + $c->c = 1; +}); + +$b = $bReflector->newLazyGhost(function () { + throw new \Exception('xxx'); +}); + +$a = $aReflector->newLazyGhost(function ($a) use ($b, $c) { + $a->a = $c->c + $b->b; +}); + +try { + $a->init = 'please'; +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +var_dump($a, $b, $c); + +?> +--EXPECTF-- +Exception: xxx +lazy ghost object(A)#%d (0) { +} +lazy ghost object(B)#%d (0) { +} +object(C)#%d (1) { + ["c"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt new file mode 100644 index 0000000000000..656d267e137fa --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_overridden_prop.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: Object is still lazy after initializer exception (overridden prop) +--FILE-- +getProperty('b')->skipLazyInitialization($obj); + $i = 5; + $obj->b = &$i; + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + throw new Exception('initializer exception'); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +initializer exception +Is lazy: 1 +# Proxy: +string(11) "initializer" +initializer exception +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt new file mode 100644 index 0000000000000..c4f0bd98773fd --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt @@ -0,0 +1,85 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (properties hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + // Builds properties hashtable + var_dump(get_mangled_object_vars($obj)); + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 +# Proxy: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt new file mode 100644 index 0000000000000..094f5c9b80947 --- /dev/null +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt @@ -0,0 +1,97 @@ +--TEST-- +Lazy objects: Initializer effects are reverted after exception (properties hashtable referenced after initializer) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 0); + + // Builds properties hashtable + var_dump(get_mangled_object_vars($obj)); + + try { + $reflector->initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump($obj); + printf("Is lazy: %d\n", $reflector->isUninitializedLazyObject($obj)); + + var_dump($table); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + global $table; + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $table = (array) $obj; + throw new Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + global $table; + var_dump("initializer"); + $obj->a = 3; + $obj->b = 4; + $obj->c = 5; + $table = (array) $obj; + throw new Exception('initializer exception'); +}); + +// Initializer effects on the proxy are not reverted +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy ghost object(C)#%d (1) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(0) +} +Is lazy: 1 + +Warning: Undefined variable $table in %s on line %d +NULL +# Proxy: +array(1) { + ["c"]=> + int(0) +} +string(11) "initializer" +initializer exception +lazy proxy object(C)#%d (3) { + ["a"]=> + int(3) + ["b"]=> + int(4) + ["c"]=> + int(5) +} +Is lazy: 1 + +Warning: Undefined variable $table in %s on line %d +NULL diff --git a/Zend/tests/lazy_objects/init_fatal.phpt b/Zend/tests/lazy_objects/init_fatal.phpt new file mode 100644 index 0000000000000..7f5e03c94b0fa --- /dev/null +++ b/Zend/tests/lazy_objects/init_fatal.phpt @@ -0,0 +1,35 @@ +--TEST-- +Lazy objects: fatal error during initialization of ghost object +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +$reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, new stdClass); + +var_dump($obj); +var_dump($obj->c); +var_dump($obj); + +--EXPECTF-- +lazy ghost object(C)#%d (1) { + ["b"]=> + object(stdClass)#%d (0) { + } +} +string(11) "initializer" + +Parse error: Unclosed '{' in %s on line %d diff --git a/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt new file mode 100644 index 0000000000000..366751e02d7bb --- /dev/null +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types.phpt @@ -0,0 +1,100 @@ +--TEST-- +Lazy objects: Pre-initialization reference source types are properly handled (no initialization exception) +--FILE-- +a = null; + unset($this->b); + $this->b = null; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s:\n", $name); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $refA = &$obj->a; + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $refB = &$obj->b; + + var_dump($obj); + var_dump($obj->c); + var_dump($obj); + + try { + // $refA retained its reference source type (except for the proxy + // case: its the responsibility of the initializer to propagate + // pre-initialized properties to the instance) + $refA = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->a); + $refA = 1; + + $refB = 1; +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(null); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +NULL +object(C)#%d (3) { + ["a"]=> + &NULL + ["b"]=> + NULL + ["c"]=> + NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +# Proxy: +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +NULL +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (3) { + ["a"]=> + NULL + ["b"]=> + NULL + ["c"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt new file mode 100644 index 0000000000000..0613ca5f3f44d --- /dev/null +++ b/Zend/tests/lazy_objects/init_handles_ref_source_types_exception.phpt @@ -0,0 +1,109 @@ +--TEST-- +Lazy objects: Pre-initialization reference source types are properly handled after initializer exception +--FILE-- +b); + throw new \Exception('initializer exception'); + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s:\n", $name); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, null); + $refA = &$obj->a; + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, null); + $refB = &$obj->b; + + var_dump($obj); + try { + var_dump($obj->c); + } catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump($obj); + + try { + // $refA retained its reference source type (except for the proxy + // case: it is the responsibility of the initializer to propagate + // pre-initialized properties to the instance) + $refA = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->a); + $refA = 1; + + try { + // $refB retained its reference source type + $refB = 1; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // source type was not duplicated + unset($obj->b); + $refB = 1; + +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(null); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +Exception: initializer exception +lazy ghost object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +TypeError: Cannot assign int to reference held by property C::$b of type ?C +# Proxy: +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +string(11) "initializer" +Exception: initializer exception +lazy proxy object(C)#%d (2) { + ["a"]=> + &NULL + ["b"]=> + &NULL +} +TypeError: Cannot assign int to reference held by property C::$a of type ?C +TypeError: Cannot assign int to reference held by property C::$b of type ?C diff --git a/Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt b/Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt new file mode 100644 index 0000000000000..954433918b92b --- /dev/null +++ b/Zend/tests/lazy_objects/init_may_leave_props_uninit.phpt @@ -0,0 +1,46 @@ +--TEST-- +Lazy objects: properties with no default values are left uninitialized +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +try { + var_dump($obj->b); +} catch (Error $e) { + printf("%s\n", $e); +} +var_dump($obj); +--EXPECTF-- +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +NULL +Error: Typed property C::$b must not be accessed before initialization in %s:%d +Stack trace: +#0 {main} +object(C)#%d (1) { + ["a"]=> + NULL + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/init_preserves_identity.phpt b/Zend/tests/lazy_objects/init_preserves_identity.phpt new file mode 100644 index 0000000000000..7ef197d43112a --- /dev/null +++ b/Zend/tests/lazy_objects/init_preserves_identity.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: initialization of proxy does not change object id +--FILE-- +resetAsLazyProxy($object, function (MyObject $object) use (&$object2Id) { + $object2 = new MyObject(); + $object2Id = spl_object_id($object2); + return $object2; +}); +var_dump(spl_object_id($object) === $objectId); +$reflector->initializeLazyObject($object); +var_dump(spl_object_id($object) === $objectId); +var_dump(spl_object_id($object) !== $object2Id); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/lazy_objects/init_preserves_proxy_class.phpt b/Zend/tests/lazy_objects/init_preserves_proxy_class.phpt new file mode 100644 index 0000000000000..913450ba66b0f --- /dev/null +++ b/Zend/tests/lazy_objects/init_preserves_proxy_class.phpt @@ -0,0 +1,33 @@ +--TEST-- +Lazy objects: initialization of proxy does not change the class of the object +--FILE-- +newLazyProxy(function (B $o) { + return new A(); +}); + +var_dump(get_class($o)); +$o->foo(); +$o->s = 'init'; +var_dump(get_class($o)); +$o->foo(); + + +?> +--EXPECT-- +string(1) "B" +string(6) "B::foo" +string(1) "B" +string(6) "B::foo" diff --git a/Zend/tests/lazy_objects/init_sets_prop_default_values.phpt b/Zend/tests/lazy_objects/init_sets_prop_default_values.phpt new file mode 100644 index 0000000000000..7c0494eee0236 --- /dev/null +++ b/Zend/tests/lazy_objects/init_sets_prop_default_values.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: props are initialized to default values before calling initializer +--FILE-- +a = 3; + $this->b = 4; + } +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + var_dump($obj); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); +--EXPECTF-- +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +string(14) "C::__construct" +int(3) +object(C)#%d (2) { + ["a"]=> + int(3) + ["b"]=> + int(4) +} diff --git a/Zend/tests/lazy_objects/init_trigger_array_cast.phpt b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt new file mode 100644 index 0000000000000..d48633f33dfad --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_array_cast.phpt @@ -0,0 +1,58 @@ +--TEST-- +Lazy objects: array cast does not initialize object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump((array)$obj); + +$obj->a = 2; +var_dump((array)$obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump((array)$obj); + +$obj->a = 2; +var_dump((array)$obj); + +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} +# Proxy: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/init_trigger_compare.phpt b/Zend/tests/lazy_objects/init_trigger_compare.phpt new file mode 100644 index 0000000000000..bebd5e9c5f0c7 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_compare.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: comparison initializes object +--FILE-- +newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +$b = $reflector->newLazyProxy(function ($obj) { + return new C(); +}); + +var_dump($a > $b); + +$a = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +$b = $reflector->newLazyProxy(function ($obj) { + return new C(); +}); + +var_dump($a == $b); + +$a = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +var_dump('A' < $a); +?> +--EXPECT-- +string(14) "C::__construct" +string(14) "C::__construct" +bool(false) +string(14) "C::__construct" +string(14) "C::__construct" +bool(true) +bool(true) diff --git a/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt b/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt new file mode 100644 index 0000000000000..b755484c15d93 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_debug_zval_dump.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: debug_zval_dump does not initialize object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +debug_zval_dump($obj); +$reflector->initializeLazyObject($obj); +debug_zval_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +debug_zval_dump($obj); +$reflector->initializeLazyObject($obj); +debug_zval_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) refcount(2){ + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) refcount(2){ + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) refcount(2){ + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) refcount(2){ + ["instance"]=> + object(C)#%d (1) refcount(2){ + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/init_trigger_foreach.phpt b/Zend/tests/lazy_objects/init_trigger_foreach.phpt new file mode 100644 index 0000000000000..b8bd780666bb8 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_foreach.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: Foreach initializes object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) diff --git a/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt b/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt new file mode 100644 index 0000000000000..d955c92c5ab01 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_foreach_hooks.phpt @@ -0,0 +1,96 @@ +--TEST-- +Lazy objects: Foreach initializes object +--FILE-- +b; } + set(int $value) { $this->b = $value; } + } + public int $c { + get { return $this->a + 2; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + $this->b = 2; + $this->d = 4; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +foreach ($obj as $prop => $value) { + var_dump($prop, $value); +} + +print "# Ghost (init exception):\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy (init exception):\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +string(1) "d" +int(4) +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +# Ghost (init exception): +Exception: +# Proxy (init exception): +Exception: diff --git a/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt new file mode 100644 index 0000000000000..aff038fcda25f --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_get_mangled_object_vars.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: get_mangled_object_vars does not initialize object +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump(get_mangled_object_vars($obj)); + + $obj->a = 2; + var_dump(get_mangled_object_vars($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} +# Proxy: +array(0) { +} +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt new file mode 100644 index 0000000000000..ca14328377488 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_get_object_vars.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: get_object_vars initializes object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(get_object_vars($obj)); + +$obj->a = 2; +var_dump(get_object_vars($obj)); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(get_object_vars($obj)); + +$obj->a = 2; +var_dump(get_object_vars($obj)); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["a"]=> + int(2) +} +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/init_trigger_json_encode.phpt b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt new file mode 100644 index 0000000000000..c7c7aed99f1ce --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_json_encode.phpt @@ -0,0 +1,42 @@ +--TEST-- +Lazy objects: json_encode initializes object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(json_encode($obj)); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(json_encode($obj)); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(7) "{"a":1}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(7) "{"a":1}" diff --git a/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt b/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt new file mode 100644 index 0000000000000..c754d030e4305 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_json_encode_hooks.phpt @@ -0,0 +1,80 @@ +--TEST-- +Lazy objects: json_encode initializes object +--FILE-- +b; } + set(int $value) { $this->b = $value; } + } + public int $c { + get { return $this->a + 2; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + $this->b = 2; + $this->d = 4; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(json_encode($obj)); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(json_encode($obj)); + +print "# Ghost (init exception):\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy (init exception):\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception(); +}); + +try { + var_dump(json_encode($obj)); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(25) "{"a":1,"b":2,"c":3,"d":4}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(25) "{"a":1,"b":2,"c":3,"d":4}" +# Ghost (init exception): +Exception: +# Proxy (init exception): +Exception: diff --git a/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt new file mode 100644 index 0000000000000..7f0cc6e4ff543 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_reflection_object_toString.phpt @@ -0,0 +1,45 @@ +--TEST-- +Lazy objects: ReflectionObject::__toString() does not trigger initialization +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + (new ReflectionObject($obj))->__toString(); + + printf("Initialized:\n"); + var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost +Initialized: +bool(false) +# Proxy +Initialized: +bool(false) diff --git a/Zend/tests/lazy_objects/init_trigger_serialize.phpt b/Zend/tests/lazy_objects/init_trigger_serialize.phpt new file mode 100644 index 0000000000000..5a5e2f78f66b7 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_serialize.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: serialize initializes object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump(serialize($obj)); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump(serialize($obj)); + + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt new file mode 100644 index 0000000000000..17dbe62cae6eb --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_var_dump.phpt @@ -0,0 +1,63 @@ +--TEST-- +Lazy objects: var_dump does not initialize object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +$reflector->initializeLazyObject($obj); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +$reflector->initializeLazyObject($obj); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt new file mode 100644 index 0000000000000..0fbcaf826e305 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_001.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: var_dump may not initialize object with __debugInfo() method +--FILE-- +a = 1; + } + public function __debugInfo() { + return ['hello']; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s\n", $name); + + var_dump($obj); + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost +lazy ghost object(C)#%d (1) { + [0]=> + string(5) "hello" +} +Initialized: +bool(false) +# Proxy +lazy proxy object(C)#%d (1) { + [0]=> + string(5) "hello" +} +Initialized: +bool(false) diff --git a/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt new file mode 100644 index 0000000000000..54ebf1a80aaa3 --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_var_dump_debug_info_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: var_dump may initialize object with __debugInfo() method +--FILE-- +a = 1; + } + public function __debugInfo() { + return [$this->a]; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + printf("# %s\n", $name); + + var_dump($obj); + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + [0]=> + int(1) +} +Initialized: +bool(true) +# Proxy +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + [0]=> + int(1) +} +Initialized: +bool(true) diff --git a/Zend/tests/lazy_objects/init_trigger_var_export.phpt b/Zend/tests/lazy_objects/init_trigger_var_export.phpt new file mode 100644 index 0000000000000..55d45063646dd --- /dev/null +++ b/Zend/tests/lazy_objects/init_trigger_var_export.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: var_export initializes object +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_export($obj); +print "\n"; + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_export($obj); +print "\n"; +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +\C::__set_state(array( + 'a' => 1, +)) +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +\C::__set_state(array( + 'a' => 1, +)) diff --git a/Zend/tests/lazy_objects/initializeLazyObject.phpt b/Zend/tests/lazy_objects/initializeLazyObject.phpt new file mode 100644 index 0000000000000..b53858a76a207 --- /dev/null +++ b/Zend/tests/lazy_objects/initializeLazyObject.phpt @@ -0,0 +1,62 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() +--FILE-- +isUninitializedLazyObject($obj)); + + var_dump($reflector?->initializeLazyObject($obj)); + + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +Initialized: +bool(false) +string(11) "initializer" +object(C)#%d (1) { + ["a"]=> + int(1) +} +Initialized: +bool(true) +# Proxy: +Initialized: +bool(false) +string(11) "initializer" +object(C)#%d (1) { + ["a"]=> + int(1) +} +Initialized: +bool(true) diff --git a/Zend/tests/lazy_objects/initializeLazyObject_error.phpt b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt new file mode 100644 index 0000000000000..541d6a8c491f1 --- /dev/null +++ b/Zend/tests/lazy_objects/initializeLazyObject_error.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() error +--FILE-- +isUninitializedLazyObject($obj)); + + try { + var_dump($reflector?->initializeLazyObject($obj)); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + throw new \Exception('initializer exception'); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +bool(false) +string(11) "initializer" +initializer exception +bool(false) +# Proxy: +bool(false) +string(11) "initializer" +initializer exception +bool(false) diff --git a/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt new file mode 100644 index 0000000000000..c424d2ecd396d --- /dev/null +++ b/Zend/tests/lazy_objects/initializeLazyObject_noop_on_initialized_object.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: ReflectionClass::initializeLazyObject() on an initialized object is a no-op +--FILE-- +a); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($reflector?->initializeLazyObject($obj)); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +int(1) +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(true) +# Proxy: +string(11) "initializer" +int(1) +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(true) diff --git a/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt new file mode 100644 index 0000000000000..7f796684e1bd8 --- /dev/null +++ b/Zend/tests/lazy_objects/initializer_must_return_the_right_type.phpt @@ -0,0 +1,164 @@ +--TEST-- +Lazy objects: initializer must return the right type +--FILE-- +b = 1; + } + public function __destruct() { + } +} + +class C extends B { +} + +class D extends C { + public int $b; // override +} + +class E extends B { + public function __destruct() { // override + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost initializer must return NULL or no value:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + return new stdClass; +}); + +var_dump($obj); +try { + var_dump($obj->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +var_dump($obj); + +print "# Proxy initializer must return an instance of a compatible class:\n"; +print "## Valid cases:\n"; + +$tests = [ + [C::class, new C()], + [C::class, new B()], + [D::class, new B()], +]; + +foreach ($tests as [$class, $instance]) { + $obj = (new ReflectionClass($class))->newLazyProxy(function ($obj) use ($instance) { + var_dump("initializer"); + $instance->b = 1; + return $instance; + }); + + printf("## %s vs %s\n", get_class($obj), is_object($instance) ? get_class($instance) : gettype($instance)); + var_dump($obj->b); + var_dump($obj); +} + +print "## Invalid cases:\n"; + +$tests = [ + [C::class, new stdClass], + [C::class, new DateTime()], + [C::class, null], + [C::class, new D()], + [E::class, new B()], +]; + +foreach ($tests as [$class, $instance]) { + $obj = (new ReflectionClass($class))->newLazyProxy(function ($obj) use ($instance) { + var_dump("initializer"); + return $instance; + }); + + try { + printf("## %s vs %s\n", get_class($obj), is_object($instance) ? get_class($instance) : gettype($instance)); + var_dump($obj->a); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return $obj; +}); + +try { + printf("## %s vs itself\n", get_class($obj)); + var_dump($obj->a); +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost initializer must return NULL or no value: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +TypeError: Lazy object initializer must return NULL or no value +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Proxy initializer must return an instance of a compatible class: +## Valid cases: +## C vs C +string(11) "initializer" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(1) + } +} +## C vs B +string(11) "initializer" +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(B)#%d (1) { + ["b"]=> + int(1) + } +} +## D vs B +string(11) "initializer" +int(1) +lazy proxy object(D)#%d (1) { + ["instance"]=> + object(B)#%d (1) { + ["b"]=> + int(1) + } +} +## Invalid cases: +## C vs stdClass +string(11) "initializer" +TypeError: The real instance class stdClass is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs DateTime +string(11) "initializer" +TypeError: The real instance class DateTime is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs NULL +string(11) "initializer" +TypeError: Lazy proxy factory must return an instance of a class compatible with C, null returned +## C vs D +string(11) "initializer" +TypeError: The real instance class D is not compatible with the proxy class C. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## E vs B +string(11) "initializer" +TypeError: The real instance class B is not compatible with the proxy class E. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods. +## C vs itself +string(11) "initializer" +Error: Lazy proxy factory must return a non-lazy object diff --git a/Zend/tests/lazy_objects/invalid_options.phpt b/Zend/tests/lazy_objects/invalid_options.phpt new file mode 100644 index 0000000000000..96c965ec4175d --- /dev/null +++ b/Zend/tests/lazy_objects/invalid_options.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: invalid options +--FILE-- +newLazyGhost(function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +try { + $obj = $reflector->newLazyProxy(function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +try { + // SKIP_DESTRUCTOR is only allowed on resetAsLazyProxy() + $obj = $reflector->newLazyGhost(function ($obj) { }, ReflectionClass::SKIP_DESTRUCTOR); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +$obj = new C(); + +try { + $reflector->resetAsLazyGhost($obj, function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +try { + $reflector->resetAsLazyProxy($obj, function ($obj) { }, -1); +} catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECT-- +ReflectionException: ReflectionClass::newLazyGhost(): Argument #2 ($options) contains invalid flags +ReflectionException: ReflectionClass::newLazyProxy(): Argument #2 ($options) contains invalid flags +ReflectionException: ReflectionClass::newLazyGhost(): Argument #2 ($options) does not accept ReflectionClass::SKIP_DESTRUCTOR +ReflectionException: ReflectionClass::resetAsLazyGhost(): Argument #3 ($options) contains invalid flags +ReflectionException: ReflectionClass::resetAsLazyProxy(): Argument #3 ($options) contains invalid flags diff --git a/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt b/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt new file mode 100644 index 0000000000000..82989b78409be --- /dev/null +++ b/Zend/tests/lazy_objects/isUninitializedLazyObject.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: ReflectionClass::isUninitializedLazyObject() +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj->a); + var_dump($reflector->isUninitializedLazyObject($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj = new C(); + $obj->a = 1; + return $obj; +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +bool(true) +string(11) "initializer" +int(1) +bool(false) +# Proxy +bool(true) +string(11) "initializer" +int(1) +bool(false) diff --git a/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt new file mode 100644 index 0000000000000..3bdb63c3166b9 --- /dev/null +++ b/Zend/tests/lazy_objects/isset_hooked_may_initialize.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: hooked property isset initializes object if hook observes object state +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt new file mode 100644 index 0000000000000..35f15be1007c3 --- /dev/null +++ b/Zend/tests/lazy_objects/isset_hooked_may_not_initialize.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: hooked property isset may does not initialize object if hook does not observe object state +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +bool(true) +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +bool(true) +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/isset_initializes.phpt b/Zend/tests/lazy_objects/isset_initializes.phpt new file mode 100644 index 0000000000000..1478bb054fce2 --- /dev/null +++ b/Zend/tests/lazy_objects/isset_initializes.phpt @@ -0,0 +1,72 @@ +--TEST-- +Lazy objects: property isset initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + var_dump(isset($obj->a)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt b/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt new file mode 100644 index 0000000000000..d49fb585cecc9 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_dynamic.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with dynamic prop +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt new file mode 100644 index 0000000000000..cdf639815e3bb --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_dynamic.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with dynamic prop +--FILE-- +a = 1; + $this->b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a += 1; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["b"]=> + int(1) + ["a"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + int(3) + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt new file mode 100644 index 0000000000000..31689723c202c --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_prop_info.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with known prop_info +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a += 1; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt new file mode 100644 index 0000000000000..7c812514eb2e9 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with unknown prop info +--FILE-- +a = 1; + $this->b = 2; + } + function test(object $obj) { + $obj->a += 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt new file mode 100644 index 0000000000000..211090110245a --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_op_unknown_prop_info_untyped.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ_OP with unknown prop info untyped +--FILE-- +a = 1; + $this->b = 2; + } + function test(object $obj) { + $obj->a += 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +?> +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(2) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt new file mode 100644 index 0000000000000..631ba647e8859 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_prop_info.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with known prop_info +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt new file mode 100644 index 0000000000000..6d48cbd2861c1 --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info.phpt @@ -0,0 +1,46 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with unknown prop info +--FILE-- +b = 2; + } + function test(object $obj) { + $obj->a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt new file mode 100644 index 0000000000000..f3c2d7dbe722a --- /dev/null +++ b/Zend/tests/lazy_objects/jit_assign_obj_unknown_prop_info_untyped.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: JIT: ASSIGN_OBJ with unknown prop info untyped +--FILE-- +b = 2; + } + function test(object $obj) { + $obj->a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 2; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); + // Call via reflection to avoid inlining. + // - test() handlers are executed once, and prime the runtime cache + // - On subsequent calls, the JIT'ed code is used, and we enter the valid runtime cache path + $reflector->getMethod('test')->invoke($obj, $obj); + var_dump($obj); +} + +?> +--EXPECTF-- +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} +string(11) "initializer" +object(C)#%d (2) { + ["a":"C":private]=> + int(1) + ["b"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt b/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt new file mode 100644 index 0000000000000..19b4e7c86005a --- /dev/null +++ b/Zend/tests/lazy_objects/json_encode_dynamic_props.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: json_encode with dynamic props on initialized object +--FILE-- +newLazyGhost(function ($obj) { + $obj->dyn = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + $c = new C(); + $c->dyn = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost +object(stdClass)#%d (2) { + ["a"]=> + int(1) + ["dyn"]=> + int(1) +} +# Proxy +object(stdClass)#%d (2) { + ["a"]=> + int(1) + ["dyn"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt new file mode 100644 index 0000000000000..691cba7f34f4a --- /dev/null +++ b/Zend/tests/lazy_objects/markLazyObjectAsInitialized.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: markLazyObjectAsInitialized() initializes properties to their default value and skips initializer +--FILE-- +isUninitializedLazyObject($obj)); + + printf("markLazyObjectAsInitialized(true) returns \$obj:\n"); + var_dump($reflector?->markLazyObjectAsInitialized($obj) === $obj); + + printf("Initialized:\n"); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +Initialized: +bool(false) +markLazyObjectAsInitialized(true) returns $obj: +bool(true) +Initialized: +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +Initialized: +bool(false) +markLazyObjectAsInitialized(true) returns $obj: +bool(true) +Initialized: +bool(true) +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/realize.phpt b/Zend/tests/lazy_objects/realize.phpt new file mode 100644 index 0000000000000..988b8114bde6f --- /dev/null +++ b/Zend/tests/lazy_objects/realize.phpt @@ -0,0 +1,96 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been assigned a value +--FILE-- +b = 'b'; + } +} + +#[AllowDynamicProperties] +class C extends B { + public string $a; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s:\n", $name); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a2'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Should not count a prop initialization + //$reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, 'dynamic B'); + //var_dump(!$reflector->isUninitializedLazyObject($obj)); + + (new ReflectionProperty(B::class, 'b'))->setRawValueWithoutLazyInitialization($obj, 'b'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b":"B":private]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} +# Proxy: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b":"B":private]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} diff --git a/Zend/tests/lazy_objects/realize_no_props.phpt b/Zend/tests/lazy_objects/realize_no_props.phpt new file mode 100644 index 0000000000000..0344c560c8a65 --- /dev/null +++ b/Zend/tests/lazy_objects/realize_no_props.phpt @@ -0,0 +1,78 @@ +--TEST-- +Lazy objects: Object with no props is never lazy +--FILE-- +isUninitializedLazyObject($obj)); + var_dump($obj); + + var_dump((new ReflectionClass($obj2::class))->isUninitializedLazyObject($obj2)); + var_dump($obj2); + + var_dump((new ReflectionClass($obj3::class))->isUninitializedLazyObject($obj3)); + var_dump($obj3); +} + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); +}); + +$obj2 = new D(); +$obj2->dynamic = 'value'; +(new ReflectionClass($obj2))->resetAsLazyGhost($obj2, function ($obj2) { + var_dump("initializer"); +}); + +$obj3 = (new ReflectionClass(C::class))->newLazyGhost(function () { + var_dump("initializer"); +}); + +test('Ghost', $obj, $obj2, $obj3); + +$obj = new C(); +(new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); +}); + +$obj2 = new D(); +$obj2->dynamic = 'value'; +(new ReflectionClass($obj2))->resetAsLazyProxy($obj2, function ($obj2) { + var_dump("initializer"); +}); + +$obj3 = (new ReflectionClass(C::class))->newLazyGhost(function () { + var_dump("initializer"); +}); + +test('Proxy', $obj, $obj2, $obj3); + +--EXPECTF-- +# Ghost: +bool(false) +object(C)#%d (0) { +} +bool(false) +object(D)#%d (0) { +} +bool(false) +object(C)#%d (0) { +} +# Proxy: +bool(false) +object(C)#%d (0) { +} +bool(false) +object(D)#%d (0) { +} +bool(false) +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/realize_proxy_overridden.phpt b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt new file mode 100644 index 0000000000000..7443c7f0a66a3 --- /dev/null +++ b/Zend/tests/lazy_objects/realize_proxy_overridden.phpt @@ -0,0 +1,91 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been assigned a value (overridden prop) +--FILE-- +b = 'b'; + } +} + +class C extends B { + public string $a; + public readonly string $b; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s:\n", $name); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a1'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'a2'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + (new ReflectionProperty(B::class, 'b'))->setRawValueWithoutLazyInitialization($obj, 'b'); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b"]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} +# Proxy: +bool(false) +bool(false) +bool(false) +TypeError: Cannot assign stdClass to property C::$a of type string +bool(true) +object(C)#%d (2) { + ["b"]=> + string(1) "b" + ["a"]=> + string(2) "a2" +} diff --git a/Zend/tests/lazy_objects/realize_skipped.phpt b/Zend/tests/lazy_objects/realize_skipped.phpt new file mode 100644 index 0000000000000..711ccfa93c000 --- /dev/null +++ b/Zend/tests/lazy_objects/realize_skipped.phpt @@ -0,0 +1,101 @@ +--TEST-- +Lazy objects: Object is not lazy anymore if all props have been skipped +--FILE-- +b = 'b'; + } +} + +#[AllowDynamicProperties] +class C extends B { + public string $a; + + public function __construct() { + parent::__construct(); + $this->a = 'a'; + } +} + +function test(string $name, object $obj) { + $reflector = new ReflectionClass(C::class); + + printf("# %s:\n", $name); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + $reflector->getProperty('a')->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + // Should not count a second prop initialization + $reflector->getProperty('a')->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + try { + // Should not count a prop initialization + $reflector->getProperty('xxx')->skipLazyInitialization($obj); + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + // Should not count a prop initialization + $reflector->getProperty('b')->skipLazyInitialization($obj); + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + (new ReflectionProperty(B::class, 'b'))->skipLazyInitialization($obj); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +bool(false) +bool(false) +bool(false) +ReflectionException: Property C::$xxx does not exist +ReflectionException: Property C::$b does not exist +bool(true) +object(C)#%d (0) { + ["b":"B":private]=> + uninitialized(string) + ["a"]=> + uninitialized(string) +} +# Proxy: +bool(false) +bool(false) +bool(false) +ReflectionException: Property C::$xxx does not exist +ReflectionException: Property C::$b does not exist +bool(true) +object(C)#%d (0) { + ["b":"B":private]=> + uninitialized(string) + ["a"]=> + uninitialized(string) +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt b/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt new file mode 100644 index 0000000000000..b836fbfea58d7 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_accepts_sub_classes.phpt @@ -0,0 +1,28 @@ +--TEST-- +Lazy objects: resetAsLazy*() accept a sub-class of the reflected class +--FILE-- +resetAsLazyGhost(new A(), function () {}); +$reflector->resetAsLazyGhost(new B(), function () {}); + +try { + $reflector->resetAsLazyGhost(new C(), function () {}); +} catch (TypeError $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +==DONE== +--EXPECT-- +TypeError: ReflectionClass::resetAsLazyGhost(): Argument #1 ($object) must be of type A, C given +==DONE== diff --git a/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt new file mode 100644 index 0000000000000..708855d312609 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_already_exception.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: resetAsLazy*() on already lazy object is not allowed +--FILE-- +resetAsLazyGhost($obj, function () {}); + +try { + $reflector->resetAsLazyGhost($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +printf("# Proxy:\n"); + +$obj = new C(); +$reflector->resetAsLazyProxy($obj, function () {}); + +try { + $reflector->resetAsLazyProxy($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +$obj = new C(); +$reflector->resetAsLazyProxy($obj, function () { + return new C(); +}); +$reflector->initializeLazyObject($obj); + +try { + $reflector->resetAsLazyProxy($obj, function ($obj) { + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +==DONE== +--EXPECT-- +# Ghost: +ReflectionException: Object is already lazy +# Proxy: +ReflectionException: Object is already lazy +==DONE== diff --git a/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt new file mode 100644 index 0000000000000..733da55a5cbc5 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_calls_destructor.phpt @@ -0,0 +1,61 @@ +--TEST-- +Lazy objects: resetAsLazy*() calls destructor of pre-existing object +--FILE-- +a = 1; + } + + public function __destruct() { + var_dump(__METHOD__); + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = new C(); +print "In makeLazy\n"; +$reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +print "# Proxy:\n"; + +$obj = new C(); +print "In makeLazy\n"; +$reflector->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +?> +--EXPECT-- +# Ghost: +In makeLazy +string(13) "C::__destruct" +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +# Proxy: +In makeLazy +string(13) "C::__destruct" +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" diff --git a/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt b/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt new file mode 100644 index 0000000000000..0ac167724c7da --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_can_reset_initialized_proxies.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: resetAsLazyProxy() can reset initialized proxies +--FILE-- +newLazyProxy(function ($proxy) { + return new A(1, $proxy); +}); + +print "Init\n"; + +$reflector->initializeLazyObject($proxy); + +var_dump($proxy); + +print "Reset\n"; + +$proxy = $reflector->resetAsLazyProxy($proxy, function () { + return new A(2); +}); + +?> +--EXPECTF-- +Init +lazy proxy object(A)#%d (1) { + ["instance"]=> + object(A)#%d (2) { + ["a"]=> + int(1) + ["proxy"]=> + *RECURSION* + } +} +Reset +string(13) "A::__destruct" +object(A)#%d (2) { + ["a"]=> + int(1) + ["proxy"]=> + object(A)#%d (0) { + } +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt new file mode 100644 index 0000000000000..583d5ccc881e5 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_deletes_reference_source_type.phpt @@ -0,0 +1,83 @@ +--TEST-- +Lazy objects: resetAsLazy deletes reference source type +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = new C(); +$ref = &$obj->a; +try { + $ref = 'string'; +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +$reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +$ref = 'string'; +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = new C(); +$ref = &$obj->a; +try { + $ref = 'string'; +} catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} +$reflector->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +$ret = 'string'; +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +TypeError: Cannot assign string to reference held by property C::$a of type int +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +TypeError: Cannot assign string to reference held by property C::$a of type int +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt new file mode 100644 index 0000000000000..67a79ab6e8ac9 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_destructor_exception.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: Destructor exception in resetAsLazy*() +--FILE-- +a = 1; + } + + public function __destruct() { + throw new \Exception(__METHOD__); + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = new C(); +try { + $reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +// Object was not made lazy +var_dump(!$reflector->isUninitializedLazyObject($obj)); + +print "# Proxy:\n"; + +$obj = new C(); +try { + (new ReflectionClass($obj))->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); + }); +} catch (\Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +// Object was not made lazy +var_dump(!(new ReflectionClass($obj))->isUninitializedLazyObject($obj)); + +?> +--EXPECT-- +# Ghost: +Exception: C::__destruct +bool(true) +# Proxy: +Exception: C::__destruct +bool(true) diff --git a/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt b/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt new file mode 100644 index 0000000000000..0aa542474a9fd --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_ignores_additional_props.phpt @@ -0,0 +1,103 @@ +--TEST-- +Lazy objects: resetAsLazy() ignores additional props +--FILE-- +d = 1; + } + } +} + +$reflector = new ReflectionClass(A::class); + +printf("# B\n"); + +$obj = new B(); +$obj->a = 1; +$obj->b = 2; +$reflector->resetAsLazyGhost($obj, function () {}); +var_dump($obj->b); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +printf("# C\n"); + +$obj = new C(); +$obj->a = 1; +$obj->c = 2; +$reflector->resetAsLazyGhost($obj, function () {}); +var_dump($obj->c); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +printf("# D\n"); + +$obj = new D(); +$obj->a = 1; +$reflector->resetAsLazyGhost($obj, function ($obj) { + $obj->__construct(true); +}); +var_dump($obj->d ?? 'undef'); +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# B +int(2) +lazy ghost object(B)#%d (1) { + ["b"]=> + int(2) +} +NULL +object(B)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(2) +} +# C +int(2) +lazy ghost object(C)#%d (1) { + ["c"]=> + int(2) +} +NULL +object(C)#%d (2) { + ["a"]=> + NULL + ["c"]=> + int(2) +} +# D +string(5) "undef" +lazy ghost object(D)#%d (0) { + ["d"]=> + uninitialized(int) +} +NULL +object(D)#%d (2) { + ["a"]=> + NULL + ["d"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt b/Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt new file mode 100644 index 0000000000000..d277a4e247d6c --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_initialized_proxy.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: resetAsLazy*() can reset initialized proxy +--FILE-- +resetAsLazyProxy($obj, function () { + return new Obj('obj2'); +}); +$r->initializeLazyObject($obj); +var_dump($obj); +$r->resetAsLazyProxy($obj, function () { + return new Obj('obj3'); +}); +var_dump($obj); +$r->initializeLazyObject($obj); +var_dump($obj); + +?> +==DONE== +--EXPECTF-- +object(Obj)#%d (1) { + ["name"]=> + string(4) "obj1" +} +lazy proxy object(Obj)#%d (1) { + ["instance"]=> + object(Obj)#%d (1) { + ["name"]=> + string(4) "obj2" + } +} +lazy proxy object(Obj)#%d (0) { + ["name"]=> + uninitialized(string) +} +lazy proxy object(Obj)#%d (1) { + ["instance"]=> + object(Obj)#%d (1) { + ["name"]=> + string(4) "obj3" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/reset_as_lazy_may_call_nested_destructors.phpt b/Zend/tests/lazy_objects/reset_as_lazy_may_call_nested_destructors.phpt new file mode 100644 index 0000000000000..39f8683d54e50 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_may_call_nested_destructors.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: resetAsLazy*() may call destructors of reset properties +--FILE-- +foo = new Foo(); + +$reflector = new ReflectionClass(Bar::class); + +print "Reset\n"; + +$reflector->resetAsLazyProxy($bar, function (Bar $bar) { + $result = new Bar(); + $result->foo = null; + $result->s = 'init'; + return $result; +}); + +print "Dump\n"; + +var_dump($bar->s); + +print "Done\n"; + +?> +--EXPECT-- +Reset +Bar::__destruct +Foo::__destruct +Dump +string(4) "init" +Done +Bar::__destruct diff --git a/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt b/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt new file mode 100644 index 0000000000000..d0c22a0333ff2 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_may_skip_destructor.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: resetAsLazy*() calls destructor of pre-existing object, unless SKIP_DESTRUCTOR flag is used +--FILE-- +a = 1; + } + + public function __destruct() { + var_dump(__METHOD__); + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = new C(); +print "In makeLazy\n"; +$reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}, ReflectionClass::SKIP_DESTRUCTOR); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +print "# Proxy:\n"; + +$obj = new C(); +print "In makeLazy\n"; +$reflector->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}, ReflectionClass::SKIP_DESTRUCTOR); +print "After makeLazy\n"; + +var_dump($obj->a); +$obj = null; + +?> +--EXPECT-- +# Ghost: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" +# Proxy: +In makeLazy +After makeLazy +string(11) "initializer" +int(1) +string(13) "C::__destruct" diff --git a/Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt b/Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt new file mode 100644 index 0000000000000..128e825e539a7 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_readonly.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: resetAsLazy*() preserves readonly semantics +--FILE-- +a = $value; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if ($setB) { + $this->b = $value; + } + try { + $this->c = $value; + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + } +} + +final class C extends B { +} + + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass($obj::class); + + $reflector->resetAsLazyGhost($obj, function ($obj) { + $obj->__construct(2, setB: true); + }); + + $reflector->initializeLazyObject($obj); + + var_dump($obj); +} + +$obj = new B(1); +test('B', $obj); + +$obj = new C(1); +test('C', $obj); + +--EXPECTF-- +# B +object(B)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} +# C +Error: Cannot modify readonly property B::$a +object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/reset_as_lazy_real_instance.phpt b/Zend/tests/lazy_objects/reset_as_lazy_real_instance.phpt new file mode 100644 index 0000000000000..8bfc582d2c066 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_real_instance.phpt @@ -0,0 +1,29 @@ +--TEST-- +Lazy objects: resetAsLazy*() can make a real instance lazy +--FILE-- +resetAsLazyProxy($obj1, function () use (&$obj2) { + $obj2 = new Obj('obj2'); + return $obj2; +}); +$r->initializeLazyObject($obj1); +$r->resetAsLazyProxy($obj2, function () { + return new Obj('obj3'); +}); +var_dump($obj1->name); + +?> +==DONE== +--EXPECT-- +string(4) "obj3" +==DONE== diff --git a/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt b/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt new file mode 100644 index 0000000000000..d99a30b3c1164 --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_resets_dynamic_props.phpt @@ -0,0 +1,82 @@ +--TEST-- +Lazy objects: resetAsLazy resets dynamic props +--FILE-- +a = new Canary(); + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = new C(); +$reflector->resetAsLazyGhost($obj, function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = new C(); +$reflector->resetAsLazyProxy($obj, function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +string(18) "Canary::__destruct" +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +object(Canary)#%d (0) { +} +object(C)#%d (2) { + ["b"]=> + NULL + ["a"]=> + object(Canary)#%d (0) { + } +} +# Proxy: +string(18) "Canary::__destruct" +string(18) "Canary::__destruct" +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +object(Canary)#%d (0) { +} +object(Canary)#%d (0) { +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["b"]=> + NULL + ["a"]=> + object(Canary)#%d (0) { + } + } +} +string(18) "Canary::__destruct" diff --git a/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt b/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt new file mode 100644 index 0000000000000..756bad70621da --- /dev/null +++ b/Zend/tests/lazy_objects/reset_as_lazy_while_init_exception.phpt @@ -0,0 +1,57 @@ +--TEST-- +Lazy objects: resetAsLazy*() on object being initialized +--FILE-- +resetAsLazyGhost($obj, function ($obj) use ($reflector) { + try { + $reflector->resetAsLazyGhost($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + try { + $reflector->resetAsLazyProxy($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + +}); +$reflector->initializeLazyObject($obj); + +printf("# Proxy:\n"); + +$obj = new C(); +$reflector->resetAsLazyProxy($obj, function ($obj) use ($reflector) { + try { + $reflector->resetAsLazyProxy($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + try { + $reflector->resetAsLazyGhost($obj, function () { }); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + return new C(); +}); +$reflector->initializeLazyObject($obj); + +?> +==DONE== +--EXPECT-- +# Ghost: +Error: Can not reset an object while it is being initialized +Error: Can not reset an object while it is being initialized +# Proxy: +Error: Can not reset an object while it is being initialized +Error: Can not reset an object while it is being initialized +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_001.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_001.phpt new file mode 100644 index 0000000000000..187aa61540cb1 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_001.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: RFC example 001 +--FILE-- +foo; + } +} + +$initializer = static function (MyClass $ghost): void { + $ghost->__construct(123); +}; + +$reflector = new ReflectionClass(MyClass::class); +$object = $reflector->newLazyGhost($initializer); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +--EXPECTF-- +lazy ghost object(MyClass)#%d (0) { + ["foo":"MyClass":private]=> + uninitialized(int) +} +int(123) +object(MyClass)#%d (1) { + ["foo":"MyClass":private]=> + int(123) +} diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_002.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_002.phpt new file mode 100644 index 0000000000000..e86a25df88718 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_002.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: RFC example 002 +--FILE-- +foo; + } +} + +$reflector = new ReflectionClass(MyClass::class); + +$initializer = static function (MyClass $proxy): MyClass { + return new MyClass(123); +}; + +$object = $reflector->newLazyProxy($initializer); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +--EXPECTF-- +lazy proxy object(MyClass)#%d (0) { + ["foo":"MyClass":private]=> + uninitialized(int) +} +int(123) +lazy proxy object(MyClass)#%d (1) { + ["instance"]=> + object(MyClass)#%d (1) { + ["foo":"MyClass":private]=> + int(123) + } +} diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_003.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_003.phpt new file mode 100644 index 0000000000000..0463b745d4eed --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_003.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: RFC example 003 +--FILE-- +resetAsLazyGhost($this, $this->initialize(...), ReflectionClass::SKIP_DESTRUCTOR); + } + + public function initialize() + { + $this->foo = 123; + } + + public function getFoo() + { + return $this->foo; + } + + public function __destruct() + { + var_dump(__METHOD__); + } +} + +$object = new MyLazyClass(); + +var_dump($object); +var_dump($object->getFoo()); +var_dump($object); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyLazyClass)#%d (0) { + ["foo":"MyLazyClass":private]=> + uninitialized(int) +} +int(123) +object(MyLazyClass)#%d (1) { + ["foo":"MyLazyClass":private]=> + int(123) +} +==DONE== +string(23) "MyLazyClass::__destruct" diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_004.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_004.phpt new file mode 100644 index 0000000000000..f2459d9aa6383 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_004.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: RFC example 004 +--FILE-- + 'Title', + 'content' => 'Content', + ]; +} + +$reflector = new ReflectionClass(BlogPost::class); +// Callable that retrieves the title and content from the database. +$initializer = function ($blogPost) { + var_dump("initialization"); + $data = loadFromDB(); + $blogPost->title = $data['title']; + $blogPost->content = $data['content']; +}; +$post = $reflector->newLazyGhost($initializer); + +// Without this line, the following call to ReflectionProperty::setValue() would trigger initialization. +$reflector->getProperty('id')->skipLazyInitialization($post); +$reflector->getProperty('id')->setValue($post, 123); + +// Alternatively, one can use this directly: +$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123); + +var_dump($post); +var_dump($post->id); +var_dump($post->title); +var_dump($post->content); +var_dump($post); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(BlogPost)#%d (1) { + ["id"]=> + int(123) + ["title"]=> + uninitialized(string) + ["content"]=> + uninitialized(string) +} +int(123) +string(14) "initialization" +string(5) "Title" +string(7) "Content" +object(BlogPost)#%d (3) { + ["id"]=> + int(123) + ["title"]=> + string(5) "Title" + ["content"]=> + string(7) "Content" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_005.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_005.phpt new file mode 100644 index 0000000000000..f8548f36b700d --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_005.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: RFC example 005 +--FILE-- + 'Title', + 'content' => 'Content', + ]; +} + +$reflector = new ReflectionClass(BlogPost::class); +// Callable that retrieves the title and content from the database. +$initializer = function ($blogPost) { + var_dump("initialization"); + $data = loadFromDB(); + return new BlogPost($blogPost->id, $data['title'], $data['content']); +}; +$post = $reflector->newLazyProxy($initializer); + +// Without this line, the following call to ReflectionProperty::setValue() would trigger initialization. +$reflector->getProperty('id')->skipLazyInitialization($post); +$reflector->getProperty('id')->setValue($post, 123); + +// Alternatively, one can use this directly: +$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123); + +var_dump($post); +var_dump($post->id); +var_dump($post->title); +var_dump($post->content); +var_dump($post); + +?> +==DONE== +--EXPECTF-- +lazy proxy object(BlogPost)#%d (1) { + ["id"]=> + int(123) + ["title"]=> + uninitialized(string) + ["content"]=> + uninitialized(string) +} +int(123) +string(14) "initialization" +string(5) "Title" +string(7) "Content" +lazy proxy object(BlogPost)#%d (1) { + ["instance"]=> + object(BlogPost)#%d (3) { + ["id"]=> + int(123) + ["title"]=> + string(5) "Title" + ["content"]=> + string(7) "Content" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_006.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_006.phpt new file mode 100644 index 0000000000000..c467567186495 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_006.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: RFC example 006 +--FILE-- +newLazyGhost(function ($object2) { + $object2->propB = 'value'; + throw new \Exception('initializer exception'); +}); +$reflector->getProperty('propA')->setRawValueWithoutLazyInitialization($object2, 'object-2'); + +$object1 = $reflector->newLazyGhost(function ($object1) use ($object2) { + $object1->propB = 'updated'; + $object1->propB = $object2->propB; +}); +$reflector->getProperty('propA')->setRawValueWithoutLazyInitialization($object1, 'object-1'); + +// Both objects are uninitalized at this point + +var_dump($object1); +var_dump($object2); + +try { + var_dump($object1->propB); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +// The state of both objects is unchanged + +var_dump($object1); +var_dump($object2); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-1" +} +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-2" +} +initializer exception +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-1" +} +lazy ghost object(MyClass)#%d (1) { + ["propA"]=> + string(8) "object-2" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_007.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_007.phpt new file mode 100644 index 0000000000000..5310345428556 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_007.phpt @@ -0,0 +1,31 @@ +--TEST-- +Lazy objects: RFC example 007 +--FILE-- +resetAsLazyGhost($object, function () {}); +var_dump($id === spl_object_id($object)); +var_dump($ref->get() === $object); + +$reflector->initializeLazyObject($object); +var_dump($id === spl_object_id($object)); +var_dump($ref->get() === $object); + +?> +==DONE== +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_008.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_008.phpt new file mode 100644 index 0000000000000..7cbbcb21c5811 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_008.phpt @@ -0,0 +1,25 @@ +--TEST-- +Lazy objects: RFC example 008 +--FILE-- +newLazyGhost(function () { + throw new \Exception('initialization'); +}); + +$reflector->getProperty('id')->skipLazyInitialization($object); + +$object->id = 1; +var_dump($object->id); + +?> +==DONE== +--EXPECT-- +int(1) +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_009.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_009.phpt new file mode 100644 index 0000000000000..ccf7f53e6b260 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_009.phpt @@ -0,0 +1,40 @@ +--TEST-- +Lazy objects: RFC example 009 +--FILE-- +connect(); + } + public function __destruct() { + var_dump(__METHOD__); + $this->close(); + } + public function connect() { + } + public function close() { + } +} + +$connection = new Connection(); + +$reflector = new ReflectionClass(Connection::class); + +print "Reset non-lazy\n"; +// Calls destructor +$reflector->resetAsLazyGhost($connection, function () { + var_dump("initialization"); +}); + +print "Release non-initialized\n"; +$connection = null; // Does not call destructor (object is not initialized) + +?> +==DONE== +--EXPECT-- +Reset non-lazy +string(22) "Connection::__destruct" +Release non-initialized +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_010.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_010.phpt new file mode 100644 index 0000000000000..3c578a883ea90 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_010.phpt @@ -0,0 +1,25 @@ +--TEST-- +Lazy objects: RFC example 010 +--FILE-- +newLazyGhost(function () {}); + +$reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'value'); + +var_dump($obj); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(MyClass)#%d (1) { + ["a"]=> + string(5) "value" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_011.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_011.phpt new file mode 100644 index 0000000000000..2dc50b1a33ff3 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_011.phpt @@ -0,0 +1,81 @@ +--TEST-- +Lazy objects: RFC example 011 +--FILE-- +name; + } + + public function getEmail() + { + return $this->email; + } +} + +// ORM code + +class EntityManager +{ + public function getReference(string $class, int $id) + { + // The ReflectionClass and ReflectionProperty instances are cached in practice + $reflector = new ReflectionClass($class); + + $entity = $reflector->newLazyGhost(function ($entity) use ($class, $id, $reflector) { + $data = $this->loadFromDatabase($class, $id); + $reflector->getProperty('name')->setValue($entity, $data['name']); + $reflector->getProperty('email')->setValue($entity, $data['email']); + }); + + // id is already known and can be accessed without triggering initialization + $reflector->getProperty('id')->setRawValueWithoutLazyInitialization($entity, $id); + + return $entity; + } + + public function loadFromDatabase($id) + { + return [ + 'name' => 'Example', + 'email' => 'example@example.com', + ]; + } +} + +$em = new EntityManager(); +$blogPost = $em->getReference(BlogPost::class, 123); +var_dump($blogPost); +var_dump($blogPost->getName()); +var_dump($blogPost); + +?> +==DONE== +--EXPECTF-- +lazy ghost object(BlogPost)#%d (1) { + ["id":"BlogPost":private]=> + int(123) + ["name":"BlogPost":private]=> + uninitialized(string) + ["email":"BlogPost":private]=> + uninitialized(string) +} +string(7) "Example" +object(BlogPost)#%d (3) { + ["id":"BlogPost":private]=> + int(123) + ["name":"BlogPost":private]=> + string(7) "Example" + ["email":"BlogPost":private]=> + string(19) "example@example.com" +} +==DONE== diff --git a/Zend/tests/lazy_objects/rfc/rfc_example_012.phpt b/Zend/tests/lazy_objects/rfc/rfc_example_012.phpt new file mode 100644 index 0000000000000..14b07d3bd65e4 --- /dev/null +++ b/Zend/tests/lazy_objects/rfc/rfc_example_012.phpt @@ -0,0 +1,80 @@ +--TEST-- +Lazy objects: RFC example 012 +--FILE-- +hostname, $this->credentials); + } +} + +class Client +{ + public function __construct( + private string $hostname, + private string $credentials, + ) {} + + public function doSomething() + { + printf("doSomething() (hostname: %s)\n", $this->hostname); + } +} + +// Symfony code + +class Container +{ + public function getClientFactoryService(): ClientFactory + { + return new ClientFactory('127.0.0.1', 'secret'); + } + + public function getClientService(): Client + { + $reflector = new ReflectionClass(Client::class); + + $client = $reflector->newLazyProxy(function () { + $clientFactory = $this->getClientFactoryService(); + return $clientFactory->createClient(); + }); + + return $client; + } +} + +$container = new Container(); +$service = $container->getClientService(); +var_dump($service); +$service->doSomething(); +var_dump($service); + +?> +==DONE== +--EXPECTF-- +lazy proxy object(Client)#%d (0) { + ["hostname":"Client":private]=> + uninitialized(string) + ["credentials":"Client":private]=> + uninitialized(string) +} +doSomething() (hostname: 127.0.0.1) +lazy proxy object(Client)#%d (1) { + ["instance"]=> + object(Client)#%d (2) { + ["hostname":"Client":private]=> + string(9) "127.0.0.1" + ["credentials":"Client":private]=> + string(6) "secret" + } +} +==DONE== diff --git a/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt new file mode 100644 index 0000000000000..632f6e9780880 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___serialize_may_initialize.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: serialize() initializes object if __serialize observes object state +--FILE-- + $this->a]; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new c(); + $c->a = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt new file mode 100644 index 0000000000000..404a35ee10442 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___serialize_may_not_initialize.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: serialize() does not initialize object if __serialize does observe object state +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt new file mode 100644 index 0000000000000..ec7657afc6916 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___sleep_initializes.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: serialize initializes object by default if the __sleep method is used +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt new file mode 100644 index 0000000000000..4641fb2a49ac3 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag.phpt @@ -0,0 +1,49 @@ +--TEST-- +Lazy objects: serialize does not initializes object with __sleep method if flag is set +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +string(12) "O:1:"C":0:{}" +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt new file mode 100644 index 0000000000000..ed909a875de47 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___sleep_skip_flag_may_initialize.phpt @@ -0,0 +1,56 @@ +--TEST-- +Lazy objects: __sleep initializes object if it observes object state, even with SKIP_INITIALIZATION_ON_SERIALIZE +--FILE-- +a); + return ['a']; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->a = 1; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $c = new C(); + $c->a = 1; + return $c; +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(11) "initializer" +int(1) +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +string(11) "initializer" +int(1) +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_dynamic_props.phpt b/Zend/tests/lazy_objects/serialize_dynamic_props.phpt new file mode 100644 index 0000000000000..b2465ded4f4b5 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_dynamic_props.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: serialize() with dynamic props on initialized object +--FILE-- +newLazyGhost(function ($obj) { + $obj->dyn = 1; +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + $c = new C(); + $c->dyn = 1; + return $c; +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["dyn"]=> + int(1) +} +# Proxy +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["dyn"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt b/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt new file mode 100644 index 0000000000000..7fdf8fb771652 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_failed_lazy_object.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: serialize() a lazy object that previously failed to initialize +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + var_dump(unserialize(serialize($obj))); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('Initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('Initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +Exception: Initializer +Exception: Initializer +# Proxy +Exception: Initializer +Exception: Initializer diff --git a/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt b/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt new file mode 100644 index 0000000000000..4fbda267d52a4 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_failed_lazy_object_skip_init_on_serialize.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: serialize() a lazy object that previously failed to initialize, with SKIP_INITIALIZATION_ON_SERIALIZE +--FILE-- +initializeLazyObject($obj); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + try { + var_dump(unserialize(serialize($obj))); + } catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('Initializer'); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('Initializer'); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Exception: Initializer +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + NULL +} +# Proxy +Exception: Initializer +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + NULL +} diff --git a/Zend/tests/lazy_objects/serialize_hook.phpt b/Zend/tests/lazy_objects/serialize_hook.phpt new file mode 100644 index 0000000000000..f2094db2e9a0a --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_hook.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: serialize during hook initializes object by default +--FILE-- +a = $value; } + } + public function __construct() { + var_dump(__METHOD__); + $this->a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj->a); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_initializes.phpt b/Zend/tests/lazy_objects/serialize_initializes.phpt new file mode 100644 index 0000000000000..eacb6a985df39 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_initializes.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: serialize initializes object by default +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump(serialize($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_props_ht.phpt b/Zend/tests/lazy_objects/serialize_props_ht.phpt new file mode 100644 index 0000000000000..e8b8834b008de --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_props_ht.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: serialize initializes object by default (properties hashtable) +--FILE-- +a = 1; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + // Builds properties hashtable + get_object_vars($obj); + + var_dump(serialize($obj)); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECT-- +# Ghost: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" +# Proxy: +string(11) "initializer" +string(14) "C::__construct" +string(24) "O:1:"C":1:{s:1:"a";i:1;}" diff --git a/Zend/tests/lazy_objects/serialize_skip_flag.phpt b/Zend/tests/lazy_objects/serialize_skip_flag.phpt new file mode 100644 index 0000000000000..b7f75320fd51c --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_skip_flag.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: serialize does not initializes object if flag is set +--FILE-- +setRawValueWithoutLazyInitialization($obj, 1); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} +# Proxy: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt new file mode 100644 index 0000000000000..b54f7846eb86d --- /dev/null +++ b/Zend/tests/lazy_objects/serialize_skip_flag_props_ht.phpt @@ -0,0 +1,55 @@ +--TEST-- +Lazy objects: serialize does not initializes object if flag is set (properties hashtable) +--FILE-- +setRawValueWithoutLazyInitialization($obj, 1); + + // Builds properties hashtable + get_mangled_object_vars($obj); + + $serialized = serialize($obj); + $unserialized = unserialize($serialized); + var_dump($serialized, $unserialized); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); +}, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} +# Proxy: +string(24) "O:1:"C":1:{s:1:"b";i:1;}" +object(C)#%d (1) { + ["a"]=> + uninitialized(int) + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization.phpt new file mode 100644 index 0000000000000..807476d70729a --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization.phpt @@ -0,0 +1,47 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() sets value +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_001.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_001.phpt new file mode 100644 index 0000000000000..d6eb417a15760 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_001.phpt @@ -0,0 +1,67 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() leaves property as lazy if exception prevents update +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Prop is still lazy: This triggers initialization + $obj->a = 1; + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +TypeError: Cannot assign stdClass to property C::$a of type int +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +TypeError: Cannot assign stdClass to property C::$a of type int +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt new file mode 100644 index 0000000000000..40221269893bd --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_exception_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() leaves non-lazy properties as non-lazy in case of exception +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + try { + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + // Prop is still non-lazy: This does not trigger initialization + $obj->a = 1; + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + throw new Exception('Unreachable'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new Exception('Unreachable'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +TypeError: Cannot assign stdClass to property C::$a of type int +bool(true) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) + ["b"]=> + uninitialized(int) +} +# Proxy +TypeError: Cannot assign stdClass to property C::$a of type int +bool(true) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt new file mode 100644 index 0000000000000..caa5211f371a5 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() is allowed on initialized objects +--FILE-- +initializeLazyObject($obj); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + NULL +} +# Proxy +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt new file mode 100644 index 0000000000000..9151e58f3fc65 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_no_dynamic_prop.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() can not be called on dynamic properties +--FILE-- +dyn = 1; + $propReflector = new ReflectionProperty($c, 'dyn'); + + try { + $propReflector->setRawValueWithoutLazyInitialization($obj, 'test'); + } catch (\ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +ReflectionException: Can not use setRawValueWithoutLazyInitialization on dynamic property C::$dyn +# Proxy +ReflectionException: Can not use setRawValueWithoutLazyInitialization on dynamic property C::$dyn diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly.phpt new file mode 100644 index 0000000000000..1e4a7ade935ad --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() preserves readonly semantics +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 1); + try { + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 2); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Error: Cannot modify readonly property C::$a +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +Error: Cannot modify readonly property C::$a +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly_variant.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly_variant.phpt new file mode 100644 index 0000000000000..cdb1b66543d65 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_readonly_variant.phpt @@ -0,0 +1,76 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() preserves readonly semantics +--FILE-- +a = 1; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + } + public readonly int $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 2); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + + $reflector->initializeLazyObject($obj); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(2) +} +Error: Cannot modify readonly property C::$a +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL +} +# Proxy +int(2) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(2) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_realize.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_realize.phpt new file mode 100644 index 0000000000000..a3f0002c9cd6f --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_realize.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may realize object if last lazy prop +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + $reflector->getProperty('b')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(true) +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + string(4) "test" +} +# Proxy +bool(true) +object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_destruct.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_destruct.phpt new file mode 100644 index 0000000000000..96bc8054ed49b --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_destruct.phpt @@ -0,0 +1,71 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may trigger initialization via side effects (__destruct()) +--FILE-- +a = 'a'; + $this->b = 'b'; + } + public $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + + $value = new class($obj) { + function __construct(public object $obj) {} + function __destruct() { + $this->obj->b = ''; + } + }; + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $value); + $value = null; + + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, new stdClass); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(0) "" +} +# Proxy +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(0) "" + } +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_toString.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_toString.phpt new file mode 100644 index 0000000000000..1c8eac82880c0 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_side_effect_toString.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() may trigger initialization via side effects (__toString()) +--FILE-- +a = 'a'; + $this->b = 'b'; + } + public string $a; + public string $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + + $value = new class($obj) { + function __construct(public object $obj) {} + function __toString() { + return $this->obj->b; + } + }; + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $value); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +C::__construct +bool(true) +object(C)#%d (2) { + ["a"]=> + string(1) "b" + ["b"]=> + string(1) "b" +} +# Proxy +C::__construct +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + string(1) "a" + ["b"]=> + string(1) "b" + } +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips___set.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips___set.phpt new file mode 100644 index 0000000000000..10a335f8fe5f0 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips___set.phpt @@ -0,0 +1,51 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() does not call __set() +--FILE-- +getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips_hook.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips_hook.phpt new file mode 100644 index 0000000000000..7bd6261519ec8 --- /dev/null +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_skips_hook.phpt @@ -0,0 +1,50 @@ +--TEST-- +Lazy objects: setRawValueWithoutLazyInitialization() skips hooks +--FILE-- +a = $value; } + get { return $this->a; } + } + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + string(4) "test" +} +# Proxy +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + string(4) "test" +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization.phpt b/Zend/tests/lazy_objects/skipLazyInitialization.phpt new file mode 100644 index 0000000000000..faff902d0e418 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization.phpt @@ -0,0 +1,349 @@ +--TEST-- +Lazy objects: ReflectionProperty::skipLazyInitialization() prevent properties from triggering initializer +--FILE-- +hooked; } + set ($value) { $this->hooked = strtoupper($value); } + } + + public $virtual { + get { return 'virtual'; } + set ($value) { } + } +} + +class B extends A { + private $priv = 'privB'; + public $pubB = 'pubB'; + + private readonly string $readonly; +} + +set_error_handler(function ($errno, $errstr) { + throw new Error($errstr); +}); + +function testProperty(callable $makeObj, $propReflector) { + + $reflector = new ReflectionClass(B::class); + + $getValue = function ($obj, $propReflector) { + $name = $propReflector->getName(); + return $obj->$name; + }; + + printf("\n## %s", $propReflector); + + printf("\nskipInitializerForProperty():\n"); + $obj = $makeObj(); + $skept = false; + try { + $propReflector->skipLazyInitialization($obj); + $skept = true; + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + if ($skept) { + try { + printf("getValue(): "); + var_dump($getValue($obj, $propReflector)); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$propReflector->isStatic()) { + $propReflector->setValue($obj, ''); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + } + + printf("\nsetRawValueWithoutLazyInitialization():\n"); + $obj = $makeObj(); + $skept = false; + try { + $propReflector->setRawValueWithoutLazyInitialization($obj, 'value'); + $skept = true; + } catch (ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + if ($skept) { + try { + printf("getValue(): "); + var_dump($getValue($obj, $propReflector)); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + if (!$reflector->isUninitializedLazyObject($obj)) { + printf("Object was unexpectedly initialized (1)\n"); + } + } +} + +function test(string $name, callable $makeObj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass(B::class); + + foreach ($reflector->getProperties() as $propReflector) { + testProperty($makeObj, $propReflector); + } + + testProperty($makeObj, new class { + function getName() { + return 'dynamicProp'; + } + function setValue($obj, $value) { + $obj->dynamicProp = $value; + } + function isStatic() { + return false; + } + // TODO: refactor this test + function skipLazyInitialization(object $object) { + throw new \ReflectionException(); + } + function setRawValueWithoutLazyInitialization(object $object) { + throw new \ReflectionException(); + } + function __toString() { + return "Property [ \$dynamicProp ]\n"; + } + }); +} + +$reflector = new ReflectionClass(B::class); + +$factory = function () use ($reflector) { + return $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); + }); +}; + +test('Ghost', $factory); + +$factory = function () use ($reflector) { + return $reflector->newLazyGhost(function ($obj) { + throw new \Exception('initializer'); + }); +}; + +test('Proxy', $factory); + +?> +--EXPECT-- +# Ghost: + +## Property [ private $priv = 'privB' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$priv + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$priv + +## Property [ public $pubB = 'pubB' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubB" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ private readonly string $readonly ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$readonly + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$readonly + +## Property [ protected $prot = 'prot' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access protected property B::$prot + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access protected property B::$prot + +## Property [ public $pubA = 'pubA' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubA" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public static $static = 'static' ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on static property B::$static + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on static property B::$static + +## Property [ public $noDefault = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public string $noDefaultTyped ] + +skipInitializerForProperty(): +getValue(): Error: Typed property A::$noDefaultTyped must not be accessed before initialization + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $initialized = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $hooked = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $virtual ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on virtual property B::$virtual + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on virtual property B::$virtual + +## Property [ $dynamicProp ] + +skipInitializerForProperty(): +ReflectionException: + +setRawValueWithoutLazyInitialization(): +ReflectionException: +# Proxy: + +## Property [ private $priv = 'privB' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$priv + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$priv + +## Property [ public $pubB = 'pubB' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubB" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ private readonly string $readonly ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access private property B::$readonly + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access private property B::$readonly + +## Property [ protected $prot = 'prot' ] + +skipInitializerForProperty(): +getValue(): Error: Cannot access protected property B::$prot + +setRawValueWithoutLazyInitialization(): +getValue(): Error: Cannot access protected property B::$prot + +## Property [ public $pubA = 'pubA' ] + +skipInitializerForProperty(): +getValue(): string(4) "pubA" + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public static $static = 'static' ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on static property B::$static + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on static property B::$static + +## Property [ public $noDefault = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public string $noDefaultTyped ] + +skipInitializerForProperty(): +getValue(): Error: Typed property A::$noDefaultTyped must not be accessed before initialization + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $initialized = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $hooked = NULL ] + +skipInitializerForProperty(): +getValue(): NULL + +setRawValueWithoutLazyInitialization(): +getValue(): string(5) "value" + +## Property [ public $virtual ] + +skipInitializerForProperty(): +ReflectionException: Can not use skipLazyInitialization on virtual property B::$virtual + +setRawValueWithoutLazyInitialization(): +ReflectionException: Can not use setRawValueWithoutLazyInitialization on virtual property B::$virtual + +## Property [ $dynamicProp ] + +skipInitializerForProperty(): +ReflectionException: + +setRawValueWithoutLazyInitialization(): +ReflectionException: diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_default.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_default.phpt new file mode 100644 index 0000000000000..15859a79e74a4 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_default.phpt @@ -0,0 +1,59 @@ +--TEST-- +Lazy objects: skipLazyInitialization() marks property as non-lazy and sets default value if any +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump($obj->b); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +NULL +int(1) +bool(false) +lazy ghost object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) +} +# Proxy +NULL +int(1) +bool(false) +lazy proxy object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt new file mode 100644 index 0000000000000..bf8ff2094ca15 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt @@ -0,0 +1,61 @@ +--TEST-- +Lazy objects: skipLazyInitialization() has no effect on initialized objects +--FILE-- +a = 2; + } + public $a = 1; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->initializeLazyObject($obj); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(true) +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL +} +# Proxy +int(1) +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_no_dynamic_prop.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_no_dynamic_prop.phpt new file mode 100644 index 0000000000000..74e12cb3629f8 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_no_dynamic_prop.phpt @@ -0,0 +1,43 @@ +--TEST-- +Lazy objects: skipLazyInitialization() can not be used on dynamic properties +--FILE-- +dyn = 1; + $propReflector = new ReflectionProperty($c, 'dyn'); + + try { + $propReflector->skipLazyInitialization($obj); + } catch (\ReflectionException $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECT-- +# Ghost +ReflectionException: Can not use skipLazyInitialization on dynamic property C::$dyn +# Proxy +ReflectionException: Can not use skipLazyInitialization on dynamic property C::$dyn diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_readonly.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_readonly.phpt new file mode 100644 index 0000000000000..dcb94f90b82ac --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_readonly.phpt @@ -0,0 +1,75 @@ +--TEST-- +Lazy objects: skipLazyInitialization() preserves readonly semantics +--FILE-- +a = 1; + } + public readonly int $a; + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + try { + var_dump($obj->a); + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + + $reflector->initializeLazyObject($obj); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function ($obj) { + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +Error: Typed property C::$a must not be accessed before initialization +bool(false) +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +Error: Typed property C::$a must not be accessed before initialization +bool(false) +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_realize.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_realize.phpt new file mode 100644 index 0000000000000..084a3993876f4 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_realize.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: skipLazyInitialization() may realize object if last lazy prop +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} +# Proxy +bool(true) +object(C)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + NULL +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_skips___set.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_skips___set.phpt new file mode 100644 index 0000000000000..761a2923e69a2 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_skips___set.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: skipLazyInitialization() does not call __set() +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(1) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +int(1) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_skips_hooks.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_skips_hooks.phpt new file mode 100644 index 0000000000000..779e931773b06 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_skips_hooks.phpt @@ -0,0 +1,53 @@ +--TEST-- +Lazy objects: skipLazyInitialization() skips hooks +--FILE-- +a = $value; } + get { return $this->a; } + } + public $b; +} + +function test(string $name, object $obj) { + printf("# %s\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(1) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy +int(1) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(1) +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_skips_non_lazy_prop.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_skips_non_lazy_prop.phpt new file mode 100644 index 0000000000000..2244020fb6100 --- /dev/null +++ b/Zend/tests/lazy_objects/skipLazyInitialization_skips_non_lazy_prop.phpt @@ -0,0 +1,54 @@ +--TEST-- +Lazy objects: skipLazyInitialization() has no effect on non-lazy properties +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + + $obj->a = 2; + + $reflector->getProperty('a')->skipLazyInitialization($obj); + + var_dump($obj->a); + var_dump(!$reflector->isUninitializedLazyObject($obj)); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyGhost(function () { + throw new \Exception('initializer'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function () { + throw new \Exception('initializer'); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost +int(2) +bool(false) +lazy ghost object(C)#%d (1) { + ["a"]=> + int(2) +} +# Proxy +int(2) +bool(false) +lazy proxy object(C)#%d (1) { + ["a"]=> + int(2) +} diff --git a/Zend/tests/lazy_objects/support_no_internal_classes.phpt b/Zend/tests/lazy_objects/support_no_internal_classes.phpt new file mode 100644 index 0000000000000..f5c8cd1e06738 --- /dev/null +++ b/Zend/tests/lazy_objects/support_no_internal_classes.phpt @@ -0,0 +1,34 @@ +--TEST-- +Lazy objects: internal classes can not be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy:\n"; + +try { + $obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost: +Error: Cannot make instance of internal class lazy: DateTime is internal +# Proxy: +Error: Cannot make instance of internal class lazy: DateTime is internal diff --git a/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt new file mode 100644 index 0000000000000..47a8214626048 --- /dev/null +++ b/Zend/tests/lazy_objects/support_no_internal_sub_classes.phpt @@ -0,0 +1,37 @@ +--TEST-- +Lazy objects: sub-classes of internal classes can not be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +print "# Proxy:\n"; + +try { + $obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); + }); +} catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +--EXPECTF-- +# Ghost: +Error: Cannot make instance of internal class lazy: C inherits internal class DateTime +# Proxy: +Error: Cannot make instance of internal class lazy: C inherits internal class DateTime diff --git a/Zend/tests/lazy_objects/support_readonly_class.phpt b/Zend/tests/lazy_objects/support_readonly_class.phpt new file mode 100644 index 0000000000000..cdd420cc121b8 --- /dev/null +++ b/Zend/tests/lazy_objects/support_readonly_class.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: readonly classes can be lazily initialized +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/support_readonly_prop.phpt b/Zend/tests/lazy_objects/support_readonly_prop.phpt new file mode 100644 index 0000000000000..2aabc3a6d18c4 --- /dev/null +++ b/Zend/tests/lazy_objects/support_readonly_prop.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: readonly properties can be lazily initialized +--FILE-- +a = 1; + } +} + +$reflector = new ReflectionClass(C::class); + +print "# Ghost:\n"; + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +var_dump($obj); +var_dump($obj->a); +var_dump($obj->a); +var_dump($obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +object(C)#%d (1) { + ["a"]=> + int(1) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +string(11) "initializer" +int(1) +int(1) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} diff --git a/Zend/tests/lazy_objects/support_stdClass.phpt b/Zend/tests/lazy_objects/support_stdClass.phpt new file mode 100644 index 0000000000000..dac4884584133 --- /dev/null +++ b/Zend/tests/lazy_objects/support_stdClass.phpt @@ -0,0 +1,30 @@ +--TEST-- +Lazy objects: stdClass can be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +--EXPECTF-- +# Ghost: +object(stdClass)#%d (0) { +} +# Proxy: +object(stdClass)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt new file mode 100644 index 0000000000000..bb73b2a54ec0f --- /dev/null +++ b/Zend/tests/lazy_objects/support_stdClass_sub_classes.phpt @@ -0,0 +1,33 @@ +--TEST-- +Lazy objects: sub-classes of stdClass can be initialized lazily +--FILE-- +newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +print "# Proxy:\n"; + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); +var_dump($obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (0) { +} +# Proxy: +object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/unclean_shutdown.phpt b/Zend/tests/lazy_objects/unclean_shutdown.phpt new file mode 100644 index 0000000000000..9ec02b5a7c4d7 --- /dev/null +++ b/Zend/tests/lazy_objects/unclean_shutdown.phpt @@ -0,0 +1,19 @@ +--TEST-- +Lazy objects: unclean shutdown +--FILE-- +newLazyGhost(function ($obj) { + // Trigger a fatal error to get an unclean shutdown + class bool {} +}); + +var_dump($obj->a); +--EXPECTF-- +Fatal error: Cannot use 'bool' as class name%s on line %d diff --git a/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt new file mode 100644 index 0000000000000..7f09504564d2b --- /dev/null +++ b/Zend/tests/lazy_objects/unset_defined_no_initialize.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of defined property does not initialize object +--FILE-- +a = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + (new ReflectionProperty($obj, 'a'))->setRawValueWithoutLazyInitialization($obj, 1); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (1) { + ["a"]=> + int(1) +} +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} +# Proxy: +object(C)#%d (1) { + ["a"]=> + int(1) +} +object(C)#%d (0) { + ["a"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_hook.phpt b/Zend/tests/lazy_objects/unset_hook.phpt new file mode 100644 index 0000000000000..e174b22f2cdc4 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_hook.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: cannot unset hooked property +--FILE-- +a; } + set($value) { $this->a = $value; } + } + public int $b = 1; + + public function __construct(int $a) { + var_dump(__METHOD__); + $this->a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + try { + unset($obj->a); + } catch (\Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +Error: Cannot unset hooked property C::$a +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +Error: Cannot unset hooked property C::$a +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt new file mode 100644 index 0000000000000..0705db85fad9a --- /dev/null +++ b/Zend/tests/lazy_objects/unset_magic_circular_may_initialize.phpt @@ -0,0 +1,68 @@ +--TEST-- +Lazy objects: circular unset of magic property may initialize object +--FILE-- +b = 2; + } + + public function __unset($name) { + unset($this->a); + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt new file mode 100644 index 0000000000000..4b0cf95763109 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_magic_may_initialize.phpt @@ -0,0 +1,70 @@ +--TEST-- +Lazy objects: unset of magic property initializes object if method observes object state +--FILE-- +b = 2; + } + + public function __unset($name) { + var_dump($this->b); + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +int(2) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt new file mode 100644 index 0000000000000..8d22cb4a3cdc9 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_magic_may_not_initialize.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of magic property may not initialize object if method does not observe object state +--FILE-- +b = 2; + } + + public function __unset($name) { + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt new file mode 100644 index 0000000000000..d990b696c24fc --- /dev/null +++ b/Zend/tests/lazy_objects/unset_skipped_no_initialize.phpt @@ -0,0 +1,78 @@ +--TEST-- +Lazy objects: unset of undefined skipped property initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + $reflector = new ReflectionClass(C::class); + $reflector->getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + unset($obj->a); + unset($obj->b); + unset($obj->c); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} +# Proxy: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (0) { + ["b"]=> + uninitialized(int) + ["c"]=> + uninitialized(int) +} diff --git a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt new file mode 100644 index 0000000000000..792ca9c1cf7b7 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes.phpt @@ -0,0 +1,65 @@ +--TEST-- +Lazy objects: unset of undefined dynamic property initializes object +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt new file mode 100644 index 0000000000000..c27198f3f1968 --- /dev/null +++ b/Zend/tests/lazy_objects/unset_undefined_dynamic_initializes_no_props_ht.phpt @@ -0,0 +1,60 @@ +--TEST-- +Lazy objects: unset of undefined dynamic property initializes object (2) +--FILE-- +b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + // no var_dump($obj), so that properties ht is not initialized + var_dump('before unset'); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +string(12) "before unset" +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Proxy: +string(12) "before unset" +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/unset_undefined_initializes.phpt b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt new file mode 100644 index 0000000000000..59fc95f902e8f --- /dev/null +++ b/Zend/tests/lazy_objects/unset_undefined_initializes.phpt @@ -0,0 +1,66 @@ +--TEST-- +Lazy objects: unset of undefined property initializes object +--FILE-- +a = $a; + $this->b = 2; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + unset($obj->a); + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(1); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(1); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["b"]=> + int(2) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["b"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/use_case_001.phpt b/Zend/tests/lazy_objects/use_case_001.phpt new file mode 100644 index 0000000000000..c2be34bfebc28 --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_001.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: Lazy service initialization in dependency injection container +--FILE-- +newLazyGhost(function ($obj) { + $obj->__construct(); + }); + return $obj; + } + + public function getApplicationService(): Application { + return new Application($this->getEntityManagerService()); + } +} + +$container = new Container(); + +printf("Service can be fetched without initializing dependencies\n"); +$application = $container->getApplicationService(); +--EXPECTF-- +Service can be fetched without initializing dependencies +string(24) "Application::__construct" diff --git a/Zend/tests/lazy_objects/use_case_001b.phpt b/Zend/tests/lazy_objects/use_case_001b.phpt new file mode 100644 index 0000000000000..f2491942d6e87 --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_001b.phpt @@ -0,0 +1,44 @@ +--TEST-- +Lazy objects: Lazy service initialization in dependency injection container via factory +--FILE-- +newLazyProxy(function ($obj) { + return new EntityManager(); + }); + return $obj; + } + + public function getApplicationService(): Application { + return new Application($this->getEntityManagerService()); + } +} + +$container = new Container(); + +printf("Service can be fetched without initializing dependencies\n"); +$application = $container->getApplicationService(); +--EXPECTF-- +Service can be fetched without initializing dependencies +string(24) "Application::__construct" diff --git a/Zend/tests/lazy_objects/use_case_002.phpt b/Zend/tests/lazy_objects/use_case_002.phpt new file mode 100644 index 0000000000000..3a87acdfb8db3 --- /dev/null +++ b/Zend/tests/lazy_objects/use_case_002.phpt @@ -0,0 +1,52 @@ +--TEST-- +Lazy objects: Lazy entity loading +--FILE-- +id; + } + + public function getName(): string { + return $this->name; + } +} + +class EntityManager { + public function lazyLoad(string $fqcn, int $id): object { + $reflector = new ReflectionClass($fqcn); + $entity = $reflector->newLazyGhost(function ($obj) { + var_dump('initializer'); + $prop = new ReflectionProperty($obj::class, 'name'); + $prop->setValue($obj, 'John Doe'); + }); + + (new ReflectionProperty($fqcn, 'id'))->setRawValueWithoutLazyInitialization($entity, $id); + + return $entity; + } +} + +$em = new EntityManager(); +$user = $em->lazyLoad(User::class, 123); + +printf("Fetching identifier does not trigger initializer\n"); +var_dump($user->getId()); + +printf("Fetching anything else triggers initializer\n"); +var_dump($user->getName()); +--EXPECTF-- +Fetching identifier does not trigger initializer +int(123) +Fetching anything else triggers initializer +string(11) "initializer" +string(8) "John Doe" diff --git a/Zend/tests/lazy_objects/write_dynamic_initializes.phpt b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt new file mode 100644 index 0000000000000..7864426463456 --- /dev/null +++ b/Zend/tests/lazy_objects/write_dynamic_initializes.phpt @@ -0,0 +1,74 @@ +--TEST-- +Lazy objects: property write to dynamic property initializes object +--FILE-- +a = 1; + $this->b = 2; + } +} +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->custom = 3; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["custom"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["custom"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_initializer_exception.phpt b/Zend/tests/lazy_objects/write_initializer_exception.phpt new file mode 100644 index 0000000000000..2445da55d21d6 --- /dev/null +++ b/Zend/tests/lazy_objects/write_initializer_exception.phpt @@ -0,0 +1,48 @@ +--TEST-- +Lazy objects: property write with initializer exception +--FILE-- +a = 1; + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + throw new \Exception('init exception'); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + throw new \Exception('init exception'); +}); + +test('Ghost', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +init exception +lazy ghost object(C)#%d (0) { +} +# Ghost: +lazy proxy object(C)#%d (0) { +} +init exception +lazy proxy object(C)#%d (0) { +} diff --git a/Zend/tests/lazy_objects/write_initializes.phpt b/Zend/tests/lazy_objects/write_initializes.phpt new file mode 100644 index 0000000000000..2505352308719 --- /dev/null +++ b/Zend/tests/lazy_objects/write_initializes.phpt @@ -0,0 +1,69 @@ +--TEST-- +Lazy objects: property write initializes object +--FILE-- +b = 3; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { + ["b"]=> + uninitialized(int) +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt new file mode 100644 index 0000000000000..52a7ae90cbde0 --- /dev/null +++ b/Zend/tests/lazy_objects/write_magic_circular_may_initialize.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: circular property write to magic property initializes object +--FILE-- +a = 1; + } + + public function __set($name, $value) { + $this->a = $value; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->a = 3; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_magic_may_initialize.phpt b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt new file mode 100644 index 0000000000000..b90bb3cbc57b1 --- /dev/null +++ b/Zend/tests/lazy_objects/write_magic_may_initialize.phpt @@ -0,0 +1,64 @@ +--TEST-- +Lazy objects: property write to magic property initializes object if method updates object state +--FILE-- +a = 1; + } + + public function __set($name, $value) { + $this->a = $value; + } +} + +function test(string $name, object $obj) { + printf("# %s:\n", $name); + + var_dump($obj); + $obj->magic = 3; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +lazy ghost object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +object(C)#%d (1) { + ["a"]=> + int(3) +} +# Proxy: +lazy proxy object(C)#%d (0) { +} +string(11) "initializer" +string(14) "C::__construct" +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(3) + } +} diff --git a/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt new file mode 100644 index 0000000000000..387b1a1cd8fed --- /dev/null +++ b/Zend/tests/lazy_objects/write_skipped_no_initialize.phpt @@ -0,0 +1,81 @@ +--TEST-- +Lazy objects: write to skipped property does not initialize object +--FILE-- +getProperty('a')->skipLazyInitialization($obj); + $reflector->getProperty('b')->skipLazyInitialization($obj); + $reflector->getProperty('c')->skipLazyInitialization($obj); + + var_dump($obj); + $obj->a = 2; + $obj->b = 2; + $obj->c = 2; + var_dump($obj); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +--EXPECTF-- +# Ghost: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} +# Proxy: +object(C)#%d (2) { + ["a"]=> + NULL + ["b"]=> + int(1) + ["c"]=> + uninitialized(int) +} +object(C)#%d (3) { + ["a"]=> + int(2) + ["b"]=> + int(2) + ["c"]=> + int(2) +} diff --git a/Zend/tests/property_hooks/abstract_get_set_readonly.phpt b/Zend/tests/property_hooks/abstract_get_set_readonly.phpt new file mode 100644 index 0000000000000..644ffb474960b --- /dev/null +++ b/Zend/tests/property_hooks/abstract_get_set_readonly.phpt @@ -0,0 +1,13 @@ +--TEST-- +readonly property does not satisfy get/set abstract property +--FILE-- + +--EXPECTF-- +Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (P::$prop::set) in %s on line %d diff --git a/Zend/tests/property_hooks/foreach.phpt b/Zend/tests/property_hooks/foreach.phpt index c217bf6ac0e28..c6073b50ed990 100644 --- a/Zend/tests/property_hooks/foreach.phpt +++ b/Zend/tests/property_hooks/foreach.phpt @@ -17,6 +17,11 @@ class ByRef { $this->_virtualByRef = $value; } } + public $virtualSetOnly { + set { + echo __METHOD__, "\n"; + } + } public function __construct() { $this->dynamic = 'dynamic'; } diff --git a/Zend/tests/property_hooks/gh15187_1.phpt b/Zend/tests/property_hooks/gh15187_1.phpt new file mode 100644 index 0000000000000..13b729620517a --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_1.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-15187: Crash in hooked iterators on properties array without dynamic properties +--FILE-- + $value; } +} + +$test = new Test(); +var_dump($test); +foreach ($test as $key => $value) { + var_dump($key, $value); +} + +?> +--EXPECTF-- +object(Test)#%d (1) { + ["prop"]=> + NULL +} +string(4) "prop" +NULL diff --git a/Zend/tests/property_hooks/gh15187_2.phpt b/Zend/tests/property_hooks/gh15187_2.phpt new file mode 100644 index 0000000000000..bf8a14fd8f9d0 --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_2.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-15187: Crash in hooked iterators on properties array without dynamic properties +--FILE-- + $value; } +} + +$test = new Test(); +var_dump($test); +foreach ($test as $key => $value) { + var_dump($key, $value); +} + +?> +--EXPECTF-- +object(Test)#%d (0) { + ["prop"]=> + uninitialized(int) +} diff --git a/Zend/tests/property_hooks/gh15187_3.phpt b/Zend/tests/property_hooks/gh15187_3.phpt new file mode 100644 index 0000000000000..d82e6002f82bf --- /dev/null +++ b/Zend/tests/property_hooks/gh15187_3.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-15187: Hooked iterator typed property ref tracking +--FILE-- + &$v) { + var_dump($v); + if ($k === 'c') { + try { + $v = 'foo'; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + } + if ($k === 'd') { + $v = 'foo'; + } +} + +var_dump($c); + +?> +--EXPECTF-- +int(1) +Cannot assign string to reference held by property C::$c of type int +int(2) +object(C)#%d (2) { + ["b"]=> + uninitialized(int) + ["c"]=> + int(1) + ["d"]=> + &string(3) "foo" +} diff --git a/Zend/tests/property_hooks/gh15419_1.phpt b/Zend/tests/property_hooks/gh15419_1.phpt new file mode 100644 index 0000000000000..41a45154f1fde --- /dev/null +++ b/Zend/tests/property_hooks/gh15419_1.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-15419: Readonly classes may not declare properties with hooks +--FILE-- + $value; } +} + +?> +--EXPECTF-- +Fatal error: Hooked properties cannot be readonly in %s on line %d diff --git a/Zend/tests/property_hooks/gh15419_2.phpt b/Zend/tests/property_hooks/gh15419_2.phpt new file mode 100644 index 0000000000000..dfa6490fdc0cd --- /dev/null +++ b/Zend/tests/property_hooks/gh15419_2.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-15419: Readonly classes may not declare promoted properties with hooks +--FILE-- + $value; }, + ) {} +} + +?> +--EXPECTF-- +Fatal error: Hooked properties cannot be readonly in %s on line %d diff --git a/Zend/tests/property_hooks/gh15438_1.phpt b/Zend/tests/property_hooks/gh15438_1.phpt new file mode 100644 index 0000000000000..2d06196f6b742 --- /dev/null +++ b/Zend/tests/property_hooks/gh15438_1.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15438: Promoted properties with hooks but no visibility +--FILE-- + $value * 2; } + ) {} +} + +$c = new C(42); +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + int(84) +} diff --git a/Zend/tests/property_hooks/gh15438_2.phpt b/Zend/tests/property_hooks/gh15438_2.phpt new file mode 100644 index 0000000000000..63175e5ecac70 --- /dev/null +++ b/Zend/tests/property_hooks/gh15438_2.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15438: Untyped promoted, hooked properties with no default value default to null +--FILE-- + $value * 2; } + ) {} +} + +$c = new ReflectionClass(C::class)->newInstanceWithoutConstructor(); +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + NULL +} diff --git a/Zend/tests/property_hooks/gh15456.phpt b/Zend/tests/property_hooks/gh15456.phpt new file mode 100644 index 0000000000000..10a7dbbfb04e0 --- /dev/null +++ b/Zend/tests/property_hooks/gh15456.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-15456: Crash in get_class_vars() on virtual properties +--FILE-- + $this->b * 2; } + public $c { get => 42; } +} +var_dump(get_class_vars(C::class)); + +?> +--EXPECT-- +array(2) { + ["a"]=> + int(42) + ["b"]=> + int(42) +} diff --git a/Zend/tests/property_hooks/interface_get_set_readonly.phpt b/Zend/tests/property_hooks/interface_get_set_readonly.phpt index 685eb4ee8bd0f..692a0bc7e7879 100644 --- a/Zend/tests/property_hooks/interface_get_set_readonly.phpt +++ b/Zend/tests/property_hooks/interface_get_set_readonly.phpt @@ -1,5 +1,7 @@ --TEST-- readonly property does not satisfy get/set interface property +--DESCRIPTION-- +The error message should be improved, the set access level comes from readonly. --FILE-- --EXPECTF-- -Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (I::$prop::set) in %s on line %d +Fatal error: Set access level of C::$prop must be omitted (as in class I) in %s on line %d diff --git a/Zend/tests/property_hooks/invalid_empty_hooks.phpt b/Zend/tests/property_hooks/invalid_empty_hooks.phpt index c549536b4d61e..c380622d06edd 100644 --- a/Zend/tests/property_hooks/invalid_empty_hooks.phpt +++ b/Zend/tests/property_hooks/invalid_empty_hooks.phpt @@ -1,5 +1,5 @@ --TEST-- -Property hook list cannot be empty +Property hook list must not be empty --FILE-- --EXPECTF-- -Fatal error: Property hook list cannot be empty in %s on line %d +Fatal error: Property hook list must not be empty in %s on line %d diff --git a/Zend/tests/property_hooks/unserialize.phpt b/Zend/tests/property_hooks/unserialize.phpt index 2461817a08814..b8834e1d39ff4 100644 --- a/Zend/tests/property_hooks/unserialize.phpt +++ b/Zend/tests/property_hooks/unserialize.phpt @@ -54,7 +54,7 @@ object(Test)#2 (1) { Test::$prop3::get Test::$prop3::set -Warning: unserialize(): Cannot unserialize value for hooked property Test::$prop3 in %s on line %d +Warning: unserialize(): Cannot unserialize value for virtual property Test::$prop3 in %s on line %d Warning: unserialize(): Error at offset 26 of 32 bytes in %s on line %d bool(false) diff --git a/Zend/tests/readonly_props/initialization_scope.phpt b/Zend/tests/readonly_props/initialization_scope.phpt index b01dacf2d42f4..f3e87efb2dfa3 100644 --- a/Zend/tests/readonly_props/initialization_scope.phpt +++ b/Zend/tests/readonly_props/initialization_scope.phpt @@ -22,12 +22,10 @@ try { } catch (Error $e) { echo $e->getMessage(), "\n"; } -try { - $test->initProtected(); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +$test->initProtected(); +var_dump($test); +$test = new B; $test->initPrivate(); var_dump($test->prop); @@ -56,17 +54,20 @@ class Y extends X { } $test = new Y; -try { - $test->initFromParent(); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +$test->initFromParent(); +var_dump($test); ?> ---EXPECT-- -Cannot initialize readonly property A::$prop from global scope -Cannot initialize readonly property A::$prop from scope B +--EXPECTF-- +Cannot modify protected(set) property A::$prop from global scope +object(B)#%d (1) { + ["prop"]=> + int(2) +} int(3) int(1) int(3) -Cannot initialize readonly property Y::$prop from scope X +object(Y)#%d (1) { + ["prop"]=> + int(1) +} diff --git a/Zend/tests/readonly_props/magic_get_set.phpt b/Zend/tests/readonly_props/magic_get_set.phpt index 201c4e3bfe2f8..2ce24cf2f1116 100644 --- a/Zend/tests/readonly_props/magic_get_set.phpt +++ b/Zend/tests/readonly_props/magic_get_set.phpt @@ -64,8 +64,8 @@ try { --EXPECT-- bool(false) Typed property Test::$prop must not be accessed before initialization -Cannot initialize readonly property Test::$prop from global scope -Cannot unset readonly property Test::$prop from global scope +Cannot modify protected(set) property Test::$prop from global scope +Cannot unset protected(set) property Test::$prop from global scope Test::__isset(prop) bool(true) Test::__get(prop) diff --git a/Zend/tests/readonly_props/public_set_non_readonly.phpt b/Zend/tests/readonly_props/public_set_non_readonly.phpt new file mode 100644 index 0000000000000..05bb1c0db32fa --- /dev/null +++ b/Zend/tests/readonly_props/public_set_non_readonly.phpt @@ -0,0 +1,13 @@ +--TEST-- +public(set) is allowed on non-readonly +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/readonly_props/unset.phpt b/Zend/tests/readonly_props/unset.phpt index 5bf2107a09be7..d6c3f1edf5479 100644 --- a/Zend/tests/readonly_props/unset.phpt +++ b/Zend/tests/readonly_props/unset.phpt @@ -61,4 +61,4 @@ Test2::__get int(1) int(1) Cannot unset readonly property Test2::$prop -Cannot unset readonly property Test3::$prop from global scope +Cannot unset protected(set) property Test3::$prop from global scope diff --git a/Zend/tests/readonly_props/variation.phpt b/Zend/tests/readonly_props/variation.phpt index 1c93f3f6f5994..12d4b41ed9fc2 100644 --- a/Zend/tests/readonly_props/variation.phpt +++ b/Zend/tests/readonly_props/variation.phpt @@ -5,9 +5,11 @@ Readonly variations class Test { public readonly int $prop; + public readonly array $array; public function init() { $this->prop = 1; + $this->array = []; } public function r() { @@ -37,6 +39,11 @@ class Test { unset($this->prop); echo 'done'; } + + public function us_dim() { + unset($this->array[0]); + echo 'done'; + } } function r($test) { @@ -67,9 +74,14 @@ function us($test) { echo 'done'; } +function us_dim($test) { + unset($test->array[0]); + echo 'done'; +} + foreach ([true, false] as $init) { foreach ([true, false] as $scope) { - foreach (['r', 'w', 'rw', 'im', 'is', 'us'] as $op) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { $test = new Test(); if ($init) { $test->init(); @@ -98,21 +110,25 @@ Init: 1, scope: 1, op: rw: Cannot modify readonly property Test::$prop Init: 1, scope: 1, op: im: Cannot indirectly modify readonly property Test::$prop Init: 1, scope: 1, op: is: 1 Init: 1, scope: 1, op: us: Cannot unset readonly property Test::$prop +Init: 1, scope: 1, op: us_dim: Cannot indirectly modify readonly property Test::$array Init: 1, scope: 0, op: r: 1 Init: 1, scope: 0, op: w: Cannot modify readonly property Test::$prop Init: 1, scope: 0, op: rw: Cannot modify readonly property Test::$prop Init: 1, scope: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 1, scope: 0, op: is: 1 Init: 1, scope: 0, op: us: Cannot unset readonly property Test::$prop +Init: 1, scope: 0, op: us_dim: Cannot indirectly modify readonly property Test::$array Init: 0, scope: 1, op: r: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 1, op: w: done Init: 0, scope: 1, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 1, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, scope: 1, op: is: 0 Init: 0, scope: 1, op: us: done +Init: 0, scope: 1, op: us_dim: done Init: 0, scope: 0, op: r: Typed property Test::$prop must not be accessed before initialization -Init: 0, scope: 0, op: w: Cannot initialize readonly property Test::$prop from global scope +Init: 0, scope: 0, op: w: Cannot modify protected(set) property Test::$prop from global scope Init: 0, scope: 0, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, scope: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, scope: 0, op: is: 0 -Init: 0, scope: 0, op: us: Cannot unset readonly property Test::$prop from global scope +Init: 0, scope: 0, op: us: Cannot unset protected(set) property Test::$prop from global scope +Init: 0, scope: 0, op: us_dim: done diff --git a/Zend/tests/readonly_props/variation_nested.phpt b/Zend/tests/readonly_props/variation_nested.phpt index 72a7925da9905..31608afcc2cea 100644 --- a/Zend/tests/readonly_props/variation_nested.phpt +++ b/Zend/tests/readonly_props/variation_nested.phpt @@ -44,8 +44,13 @@ function us($test) { echo 'done'; } +function us_dim($test) { + unset($test->prop->array[0]); + echo 'done'; +} + foreach ([true, false] as $init) { - foreach (['r', 'w', 'rw', 'im', 'is', 'us'] as $op) { + foreach (['r', 'w', 'rw', 'im', 'is', 'us', 'us_dim'] as $op) { $test = new Test(); if ($init) { $test->init(); @@ -69,9 +74,11 @@ Init: 1, op: rw: done Init: 1, op: im: done Init: 1, op: is: 1 Init: 1, op: us: done +Init: 1, op: us_dim: done Init: 0, op: r: Typed property Test::$prop must not be accessed before initialization Init: 0, op: w: Cannot indirectly modify readonly property Test::$prop Init: 0, op: rw: Typed property Test::$prop must not be accessed before initialization Init: 0, op: im: Cannot indirectly modify readonly property Test::$prop Init: 0, op: is: 0 Init: 0, op: us: done +Init: 0, op: us_dim: done diff --git a/Zend/zend.c b/Zend/zend.c index ef5ea8cebc78b..9f6e709efbecf 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1410,7 +1410,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zval retval; zval orig_user_error_handler; bool in_compilation; - zend_class_entry *saved_class_entry; + zend_class_entry *saved_class_entry = NULL; zend_stack loop_var_stack; zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index daa98a89253d8..b4f13bedecc56 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -439,6 +439,11 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * } /* }}} */ +ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num) +{ + zend_argument_value_error(arg_num, "must not be empty"); +} + ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce) { if (old_ce->type == ZEND_INTERNAL_CLASS) { @@ -1790,7 +1795,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) * calling zend_merge_properties(). */ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties) /* {{{ */ { - if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) { + if (UNEXPECTED(class_type->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { if (class_type->ce_flags & ZEND_ACC_INTERFACE) { zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(class_type->name)); } else if (class_type->ce_flags & ZEND_ACC_TRAIT) { @@ -1798,6 +1803,7 @@ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zen } else if (class_type->ce_flags & ZEND_ACC_ENUM) { zend_throw_error(NULL, "Cannot instantiate enum %s", ZSTR_VAL(class_type->name)); } else { + ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(class_type->name)); } ZVAL_NULL(arg); @@ -3488,9 +3494,16 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class */ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */ { - zend_class_entry *register_class; + return zend_register_internal_class_with_flags(class_entry, parent_ce, 0); +} +/* }}} */ - register_class = zend_register_internal_class(class_entry); +ZEND_API zend_class_entry *zend_register_internal_class_with_flags( + zend_class_entry *class_entry, + zend_class_entry *parent_ce, + uint32_t ce_flags +) { + zend_class_entry *register_class = do_register_internal_class(class_entry, ce_flags); if (parent_ce) { zend_do_inheritance(register_class, parent_ce); @@ -3499,7 +3512,6 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla return register_class; } -/* }}} */ ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...) /* {{{ */ { @@ -3605,6 +3617,13 @@ ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t static void zend_disable_function(const char *function_name, size_t function_name_length) { + if (UNEXPECTED( + (function_name_length == strlen("exit") && !memcmp(function_name, "exit", strlen("exit"))) + || (function_name_length == strlen("die") && !memcmp(function_name, "die", strlen("die"))) + )) { + zend_error(E_WARNING, "Cannot disable function %s()", function_name); + return; + } zend_hash_str_del(CG(function_table), function_name, function_name_length); } @@ -4505,6 +4524,33 @@ ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, z if (!(access_type & ZEND_ACC_PPP_MASK)) { access_type |= ZEND_ACC_PUBLIC; } + /* Add the protected(set) bit for public readonly properties with no set visibility. */ + if ((access_type & (ZEND_ACC_PUBLIC|ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) == (ZEND_ACC_PUBLIC|ZEND_ACC_READONLY)) { + access_type |= ZEND_ACC_PROTECTED_SET; + } else if (UNEXPECTED(access_type & ZEND_ACC_PPP_SET_MASK)) { + if (!ZEND_TYPE_IS_SET(type)) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "Property with asymmetric visibility %s::$%s must have type", + ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + uint32_t get_visibility = zend_visibility_to_set_visibility(access_type & ZEND_ACC_PPP_MASK); + uint32_t set_visibility = access_type & ZEND_ACC_PPP_SET_MASK; + if (get_visibility > set_visibility) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "Visibility of property %s::$%s must not be weaker than set visibility", + ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + /* Remove equivalent set visibility. */ + if (((access_type & (ZEND_ACC_PUBLIC|ZEND_ACC_PUBLIC_SET)) == (ZEND_ACC_PUBLIC|ZEND_ACC_PUBLIC_SET)) + || ((access_type & (ZEND_ACC_PROTECTED|ZEND_ACC_PROTECTED_SET)) == (ZEND_ACC_PROTECTED|ZEND_ACC_PROTECTED_SET)) + || ((access_type & (ZEND_ACC_PRIVATE|ZEND_ACC_PRIVATE_SET)) == (ZEND_ACC_PRIVATE|ZEND_ACC_PRIVATE_SET))) { + access_type &= ~ZEND_ACC_PPP_SET_MASK; + } + /* private(set) properties are implicitly final. */ + if (access_type & ZEND_ACC_PRIVATE_SET) { + access_type |= ZEND_ACC_FINAL; + } + } /* Virtual properties have no backing storage, the offset should never be used. However, the * virtual flag cannot be definitively determined at compile time. Allow using default values diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ab67dd5717e69..f9fe81d50dd4f 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -390,6 +390,7 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry); ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce); +ZEND_API zend_class_entry *zend_register_internal_class_with_flags(zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t flags); ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry); ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...); @@ -1564,6 +1565,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); +ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num); ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce); ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce); diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 5ecda76870452..d33747412ef0a 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1697,7 +1697,7 @@ static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, } } -static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags) { +static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags, zend_modifier_target target) { if (flags & ZEND_ACC_PUBLIC) { smart_str_appends(str, "public "); } else if (flags & ZEND_ACC_PROTECTED) { @@ -1705,6 +1705,16 @@ static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags) } else if (flags & ZEND_ACC_PRIVATE) { smart_str_appends(str, "private "); } + + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + if (flags & ZEND_ACC_PRIVATE_SET) { + smart_str_appends(str, "private(set) "); + } else if (flags & ZEND_ACC_PROTECTED_SET) { + smart_str_appends(str, "protected(set) "); + } else if (flags & ZEND_ACC_PUBLIC_SET) { + smart_str_appends(str, "public(set) "); + } + } } static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) { @@ -1815,7 +1825,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, decl->child[4], indent, newlines); } - zend_ast_export_visibility(str, decl->flags); + zend_ast_export_visibility(str, decl->flags, ZEND_MODIFIER_TARGET_METHOD); if (decl->flags & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); @@ -1941,7 +1951,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, ast->child[2], indent, 1); } - zend_ast_export_visibility(str, ast->attr); + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_PROPERTY); if (ast->attr & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); @@ -1967,7 +1977,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, ast->child[1], indent, 1); } - zend_ast_export_visibility(str, ast->attr); + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CONSTANT); smart_str_appends(str, "const "); if (ast->child[2]) { zend_ast_export_type(str, ast->child[2], indent); @@ -2388,7 +2398,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio for (uint32_t i = 0; i < hook_list->children; i++) { zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; - zend_ast_export_visibility(str, hook->flags); + zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); } diff --git a/Zend/zend_attributes_arginfo.h b/Zend/zend_attributes_arginfo.h index 2a8022d0bd181..817dacbd44d50 100644 --- a/Zend/zend_attributes_arginfo.h +++ b/Zend/zend_attributes_arginfo.h @@ -81,8 +81,7 @@ static zend_class_entry *register_class_Attribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Attribute", class_Attribute_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval const_TARGET_CLASS_value; ZVAL_LONG(&const_TARGET_CLASS_value, ZEND_ATTRIBUTE_TARGET_CLASS); @@ -153,8 +152,7 @@ static zend_class_entry *register_class_ReturnTypeWillChange(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReturnTypeWillChange", class_ReturnTypeWillChange_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_string *attribute_name_Attribute_class_ReturnTypeWillChange_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ReturnTypeWillChange_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ReturnTypeWillChange_0, 1); @@ -171,8 +169,7 @@ static zend_class_entry *register_class_AllowDynamicProperties(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AllowDynamicProperties", class_AllowDynamicProperties_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_string *attribute_name_Attribute_class_AllowDynamicProperties_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_AllowDynamicProperties_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_AllowDynamicProperties_0, 1); @@ -189,8 +186,7 @@ static zend_class_entry *register_class_SensitiveParameter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SensitiveParameter", class_SensitiveParameter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_string *attribute_name_Attribute_class_SensitiveParameter_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_SensitiveParameter_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_SensitiveParameter_0, 1); @@ -207,8 +203,7 @@ static zend_class_entry *register_class_SensitiveParameterValue(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SensitiveParameterValue", class_SensitiveParameterValue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); @@ -224,8 +219,7 @@ static zend_class_entry *register_class_Override(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Override", class_Override_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_Override_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Override_0, 1); @@ -242,8 +236,7 @@ static zend_class_entry *register_class_Deprecated(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Deprecated", class_Deprecated_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval property_message_default_value; ZVAL_UNDEF(&property_message_default_value); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 23bc5f7a3cd57..654ba7e7ea129 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -69,6 +69,33 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ } /* }}} */ +ZEND_FUNCTION(exit) +{ + zend_string *str = NULL; + zend_long status = 0; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_LONG(str, status) + ZEND_PARSE_PARAMETERS_END(); + + if (str) { + size_t len = ZSTR_LEN(str); + if (len != 0) { + /* An exception might be emitted by an output handler */ + zend_write(ZSTR_VAL(str), len); + if (EG(exception)) { + RETURN_THROWS(); + } + } + } else { + EG(exit_status) = status; + } + + ZEND_ASSERT(!EG(exception)); + zend_throw_unwind_exit(); +} + /* {{{ Get the version of the Zend Engine */ ZEND_FUNCTION(zend_version) { @@ -697,7 +724,8 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool s if (((prop_info->flags & ZEND_ACC_PROTECTED) && !zend_check_protected(prop_info->ce, scope)) || ((prop_info->flags & ZEND_ACC_PRIVATE) && - prop_info->ce != scope)) { + prop_info->ce != scope) || + (prop_info->flags & ZEND_ACC_VIRTUAL)) { continue; } prop = NULL; @@ -857,7 +885,7 @@ ZEND_FUNCTION(get_mangled_object_vars) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); - properties = obj->handlers->get_properties(obj); + properties = zend_get_properties_no_lazy_init(obj); if (!properties) { ZVAL_EMPTY_ARRAY(return_value); return; diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index b92b80b917c54..f7009c4ffba6e 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -7,6 +7,11 @@ class stdClass { } +function exit(string|int $status = 0): never {} + +/** @alias exit */ +function die(string|int $status = 0): never {} + /** @refcount 1 */ function zend_version(): string {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 20e6f0f9b48a3..612fd1d275d55 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c3bec3b17079456ef17e5c992995dcfbe62c6fe0 */ + * Stub hash: 3dbc84896823c9aaa9ac8aeef8841266920c3e50 */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) + ZEND_ARG_TYPE_MASK(0, status, MAY_BE_STRING|MAY_BE_LONG, "0") +ZEND_END_ARG_INFO() + +#define arginfo_die arginfo_exit ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -232,6 +238,7 @@ static const zend_frameless_function_info frameless_function_infos_class_exists[ { 0 }, }; +ZEND_FUNCTION(exit); ZEND_FUNCTION(zend_version); ZEND_FUNCTION(func_num_args); ZEND_FUNCTION(func_get_arg); @@ -292,6 +299,8 @@ ZEND_FUNCTION(gc_disable); ZEND_FUNCTION(gc_status); static const zend_function_entry ext_functions[] = { + ZEND_FE(exit, arginfo_exit) + ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL) ZEND_FE(zend_version, arginfo_zend_version) ZEND_FE(func_num_args, arginfo_func_num_args) ZEND_FE(func_get_arg, arginfo_func_get_arg) @@ -364,8 +373,7 @@ static zend_class_entry *register_class_stdClass(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "stdClass", class_stdClass_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); zend_string *attribute_name_AllowDynamicProperties_class_stdClass_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class_stdClass_0, 0); diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index f12323d0d9cd3..ac12b8b7d8716 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -64,10 +64,12 @@ typedef int boolean_t; #include #endif #ifdef __sun -#define _STRUCTURED_PROC 1 -#include -#include -#include +# include +# ifdef HAVE_LIBPROC_H +# define _STRUCTURED_PROC 1 +# include +# include +# endif #include #endif @@ -620,7 +622,6 @@ static bool zend_call_stack_get_netbsd_vm(zend_call_stack *stack, void **ptr) char *start, *end; struct kinfo_vmentry *entry; size_t len, max_size; - char buffer[4096]; uintptr_t addr_on_stack = (uintptr_t) zend_call_stack_position(); int mib[5] = { CTL_VM, VM_PROC, VM_PROC_MAP, getpid(), sizeof(struct kinfo_vmentry) }; bool found = false; @@ -699,9 +700,9 @@ static bool zend_call_stack_get_solaris_pthread(zend_call_stack *stack) return true; } +#ifdef HAVE_LIBPROC_H static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack) { - char buffer[4096]; uintptr_t addr_on_stack = (uintptr_t) zend_call_stack_position(); bool found = false, r = false; struct ps_prochandle *proc; @@ -771,12 +772,15 @@ static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack) close(fd); return r; } +#endif static bool zend_call_stack_get_solaris(zend_call_stack *stack) { +#ifdef HAVE_LIBPROC_H if (_lwp_self() == 1) { return zend_call_stack_get_solaris_proc_maps(stack); } +#endif return zend_call_stack_get_solaris_pthread(stack); } #else diff --git a/Zend/zend_closures_arginfo.h b/Zend/zend_closures_arginfo.h index dfd70418620bd..57066078a8821 100644 --- a/Zend/zend_closures_arginfo.h +++ b/Zend/zend_closures_arginfo.h @@ -44,8 +44,7 @@ static zend_class_entry *register_class_Closure(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Closure", class_Closure_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index cfd97e59b7ebd..36231a5610f32 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -860,6 +860,12 @@ static char *zend_modifier_token_to_string(uint32_t token) return "readonly"; case T_ABSTRACT: return "abstract"; + case T_PUBLIC_SET: + return "public(set)"; + case T_PROTECTED_SET: + return "protected(set)"; + case T_PRIVATE_SET: + return "private(set)"; EMPTY_SWITCH_DEFAULT_CASE() } } @@ -905,6 +911,21 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token return ZEND_ACC_STATIC; } break; + case T_PUBLIC_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PUBLIC_SET; + } + break; + case T_PROTECTED_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PROTECTED_SET; + } + break; + case T_PRIVATE_SET: + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + return ZEND_ACC_PRIVATE_SET; + } + break; } char *member; @@ -1020,6 +1041,13 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag, zend_modifi "Cannot use the final modifier on an abstract method", 0); return 0; } + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + if ((flags & ZEND_ACC_PPP_SET_MASK) && (new_flag & ZEND_ACC_PPP_SET_MASK)) { + zend_throw_exception(zend_ce_compile_error, + "Multiple access type modifiers are not allowed", 0); + return 0; + } + } return new_flags; } /* }}} */ @@ -7569,7 +7597,8 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast)); bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0; - uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); + uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY); + bool is_promoted = property_flags || hooks_ast; znode var_node, default_node; uint8_t opcode; @@ -7626,14 +7655,14 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 if (attributes_ast) { zend_compile_attributes( &op_array->attributes, attributes_ast, i + 1, ZEND_ATTRIBUTE_TARGET_PARAMETER, - property_flags ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0 + is_promoted ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0 ); } bool forced_allow_nullable = false; if (type_ast) { uint32_t default_type = *default_ast_ptr ? Z_TYPE(default_node.u.constant) : IS_UNDEF; - bool force_nullable = default_type == IS_NULL && !property_flags; + bool force_nullable = default_type == IS_NULL && !is_promoted; op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; arg_info->type = zend_compile_typename_ex(type_ast, force_nullable, &forced_allow_nullable); @@ -7696,14 +7725,14 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 } uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, /* is_tentative */ 0) - | (property_flags ? _ZEND_IS_PROMOTED_BIT : 0); + | (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0); ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags; if (opcode == ZEND_RECV) { opline->op2.num = type_ast ? ZEND_TYPE_FULL_MASK(arg_info->type) : MAY_BE_ANY; } - if (property_flags) { + if (is_promoted) { zend_op_array *op_array = CG(active_op_array); zend_class_entry *scope = op_array->scope; @@ -7790,9 +7819,11 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 for (i = 0; i < list->children; i++) { zend_ast *param_ast = list->child[i]; + zend_ast *hooks_ast = param_ast->child[5]; bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; - uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_READONLY); - if (!flags) { + uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY); + bool is_promoted = flags || hooks_ast; + if (!is_promoted) { continue; } @@ -8382,8 +8413,12 @@ static void zend_compile_property_hooks( { zend_class_entry *ce = CG(active_class_entry); + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_error_noreturn(E_COMPILE_ERROR, "Hooked properties cannot be readonly"); + } + if (hooks->children == 0) { - zend_error_noreturn(E_COMPILE_ERROR, "Property hook list cannot be empty"); + zend_error_noreturn(E_COMPILE_ERROR, "Property hook list must not be empty"); } for (uint32_t i = 0; i < hooks->children; i++) { @@ -8543,6 +8578,10 @@ static void zend_compile_property_hooks( /* Will be removed again, in case of Iterator or IteratorAggregate. */ ce->get_iterator = zend_hooked_object_get_iterator; } + + if (!prop_info->ce->parent_name) { + zend_verify_hooked_property(ce, prop_info, prop_name); + } } static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags, zend_ast *attr_ast) /* {{{ */ @@ -8601,11 +8640,6 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } - if (hooks_ast && (flags & ZEND_ACC_READONLY)) { - zend_error_noreturn(E_COMPILE_ERROR, - "Hooked properties cannot be readonly"); - } - if (type_ast) { type = zend_compile_typename(type_ast); @@ -8679,10 +8713,6 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (hooks_ast) { zend_compile_property_hooks(info, name, type_ast, zend_ast_get_list(hooks_ast)); - - if (!ce->parent_name) { - zend_verify_hooked_property(ce, info, name); - } } if (attr_ast) { @@ -10376,27 +10406,6 @@ static void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *expr_ast = ast->child[0]; - znode expr_node; - - if (expr_ast) { - zend_compile_expr(&expr_node, expr_ast); - } else { - expr_node.op_type = IS_UNUSED; - } - - zend_op *opline = zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL); - if (result) { - /* Mark this as an "expression throw" for opcache. */ - opline->extended_value = ZEND_THROW_IS_EXPR; - result->op_type = IS_CONST; - ZVAL_TRUE(&result->u.constant); - } -} -/* }}} */ - static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *value_ast = ast->child[0]; @@ -11366,7 +11375,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_halt_compiler(ast); break; case ZEND_AST_THROW: - case ZEND_AST_EXIT: zend_compile_expr(NULL, ast); break; default: @@ -11469,9 +11477,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_PRINT: zend_compile_print(result, ast); return; - case ZEND_AST_EXIT: - zend_compile_exit(result, ast); - return; case ZEND_AST_YIELD: zend_compile_yield(result, ast); return; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c7e31877b5cd2..0f7c39676c614 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -253,7 +253,7 @@ typedef struct _zend_oparray_context { /* or IS_CONSTANT_VISITED_MARK | | | */ #define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ /* | | | */ -/* Property Flags (unused: 10...) | | | */ +/* Property Flags (unused: 13...) | | | */ /* =========== | | | */ /* | | | */ /* Promoted property / parameter | | | */ @@ -262,6 +262,11 @@ typedef struct _zend_oparray_context { /* Virtual property without backing storage | | | */ #define ZEND_ACC_VIRTUAL (1 << 9) /* | | X | */ /* | | | */ +/* Asymmetric visibility | | | */ +#define ZEND_ACC_PUBLIC_SET (1 << 10) /* | | X | */ +#define ZEND_ACC_PROTECTED_SET (1 << 11) /* | | X | */ +#define ZEND_ACC_PRIVATE_SET (1 << 12) /* | | X | */ +/* | | | */ /* Class Flags (unused: 30,31) | | | */ /* =========== | | | */ /* | | | */ @@ -393,12 +398,33 @@ typedef struct _zend_oparray_context { /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ - #define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE) +#define ZEND_ACC_PPP_SET_MASK (ZEND_ACC_PUBLIC_SET | ZEND_ACC_PROTECTED_SET | ZEND_ACC_PRIVATE_SET) + +static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t visibility) +{ + switch (visibility) { + case ZEND_ACC_PUBLIC: + return ZEND_ACC_PUBLIC_SET; + case ZEND_ACC_PROTECTED: + return ZEND_ACC_PROTECTED_SET; + case ZEND_ACC_PRIVATE: + return ZEND_ACC_PRIVATE_SET; + EMPTY_SWITCH_DEFAULT_CASE(); + } +} /* call through internal function handler. e.g. Closure::invoke() */ #define ZEND_ACC_CALL_VIA_HANDLER ZEND_ACC_CALL_VIA_TRAMPOLINE +#define ZEND_ACC_UNINSTANTIABLE ( \ + ZEND_ACC_INTERFACE | \ + ZEND_ACC_TRAIT | \ + ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | \ + ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | \ + ZEND_ACC_ENUM \ +) + #define ZEND_SHORT_CIRCUITING_CHAIN_MASK 0x3 #define ZEND_SHORT_CIRCUITING_CHAIN_EXPR 0 #define ZEND_SHORT_CIRCUITING_CHAIN_ISSET 1 @@ -1001,7 +1027,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_FETCH_CLASS_ALLOW_UNLINKED 0x0400 #define ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED 0x0800 -/* These should not clash with ZEND_ACC_(PUBLIC|PROTECTED|PRIVATE) */ +/* These should not clash with ZEND_ACC_PPP_MASK and ZEND_ACC_PPP_SET_MASK */ #define ZEND_PARAM_REF (1<<3) #define ZEND_PARAM_VARIADIC (1<<4) diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index 7899877f53046..5dc7d7ac3f45f 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -194,7 +194,7 @@ static zend_class_entry *register_class_Exception(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Throwable); zval property_message_default_value; @@ -248,7 +248,7 @@ static zend_class_entry *register_class_ErrorException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); zval property_severity_default_value; ZVAL_LONG(&property_severity_default_value, E_ERROR); @@ -264,7 +264,7 @@ static zend_class_entry *register_class_Error(zend_class_entry *class_entry_Thro zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Error", class_Error_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Throwable); zval property_message_default_value; @@ -318,7 +318,7 @@ static zend_class_entry *register_class_CompileError(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -328,7 +328,7 @@ static zend_class_entry *register_class_ParseError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CompileError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CompileError, 0); return class_entry; } @@ -338,7 +338,7 @@ static zend_class_entry *register_class_TypeError(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -348,7 +348,7 @@ static zend_class_entry *register_class_ArgumentCountError(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_TypeError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_TypeError, 0); return class_entry; } @@ -358,7 +358,7 @@ static zend_class_entry *register_class_ValueError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -368,7 +368,7 @@ static zend_class_entry *register_class_ArithmeticError(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -378,7 +378,7 @@ static zend_class_entry *register_class_DivisionByZeroError(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ArithmeticError); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ArithmeticError, 0); return class_entry; } @@ -388,7 +388,7 @@ static zend_class_entry *register_class_UnhandledMatchError(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnhandledMatchError", class_UnhandledMatchError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -398,7 +398,7 @@ static zend_class_entry *register_class_RequestParseBodyException(zend_class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RequestParseBodyException", class_RequestParseBodyException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 602bb3b0e79f5..95fa9f1c01a14 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -915,6 +915,32 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_pr ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( + const zend_property_info *prop_info, const char *operation +) { + zend_class_entry *scope; + if (EG(fake_scope)) { + scope = EG(fake_scope); + } else { + scope = zend_get_called_scope(EG(current_execute_data)); + } + + const char *visibility; + if (prop_info->flags & ZEND_ACC_PRIVATE_SET) { + visibility = "private(set)"; + } else { + ZEND_ASSERT(prop_info->flags & ZEND_ACC_PROTECTED_SET); + visibility = "protected(set)"; + } + + zend_throw_error(NULL, "Cannot %s %s property %s::$%s from %s%s", + operation, + visibility, + ZSTR_VAL(prop_info->ce->name), + ZSTR_VAL(prop_info->name), + scope ? "scope " : "global scope", scope ? ZSTR_VAL(scope->name) : ""); +} + static const zend_class_entry *resolve_single_class_type(zend_string *name, const zend_class_entry *self_ce) { if (zend_string_equals_literal_ci(name, "self")) { return self_ce; @@ -1028,9 +1054,15 @@ static zend_never_inline zval* zend_assign_to_typed_prop(zend_property_info *inf { zval tmp; - if (UNEXPECTED((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(info); - return &EG(uninitialized_zval); + if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { + zend_readonly_property_modification_error(info); + return &EG(uninitialized_zval); + } + if (info->flags & ZEND_ACC_PPP_SET_MASK && !zend_asymmetric_property_has_set_access(info)) { + zend_asymmetric_visibility_property_modification_error(info, "modify"); + return &EG(uninitialized_zval); + } } ZVAL_DEREF(value); @@ -3357,7 +3389,8 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c ZVAL_INDIRECT(result, ptr); zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); if (prop_info) { - if (UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { + if (UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) + && ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info))) { /* For objects, W/RW/UNSET fetch modes might not actually modify object. * Similar as with magic __get() allow them, but return the value as a copy * to make sure no actual modification is possible. */ @@ -3365,7 +3398,11 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c if (Z_TYPE_P(ptr) == IS_OBJECT) { ZVAL_COPY(result, ptr); } else { - zend_readonly_property_indirect_modification_error(prop_info); + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_readonly_property_indirect_modification_error(prop_info); + } else { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + } ZVAL_ERROR(result); } return; @@ -4716,7 +4753,20 @@ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield) { - if (!EX(func) || !ZEND_USER_CODE(EX(func)->common.type)) { + if (!EX(func)) { + return NULL; + } + + if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) { + zend_get_gc_buffer_add_obj(gc_buffer, Z_OBJ(execute_data->This)); + } + + if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { + zend_get_gc_buffer_add_obj(gc_buffer, ZEND_CLOSURE_OBJECT(EX(func))); + } + + if (!ZEND_USER_CODE(EX(func)->common.type)) { + ZEND_ASSERT(!(EX_CALL_INFO() & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS))); return NULL; } @@ -4737,12 +4787,6 @@ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_d } } - if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) { - zend_get_gc_buffer_add_obj(gc_buffer, Z_OBJ(execute_data->This)); - } - if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { - zend_get_gc_buffer_add_obj(gc_buffer, ZEND_CLOSURE_OBJECT(EX(func))); - } if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { zval extra_named_params; ZVAL_ARR(&extra_named_params, EX(extra_named_params)); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index fe854f305150c..190d67f82a598 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -92,6 +92,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_pr ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *info, const char *operation); + ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); ZEND_API ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *value); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f1f5bfc84516f..21e17fe8c666b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -171,6 +171,7 @@ void init_executor(void) /* {{{ */ zend_stack_init(&EG(user_exception_handlers), sizeof(zval)); zend_objects_store_init(&EG(objects_store), 1024); + zend_lazy_objects_init(&EG(lazy_objects_store)); EG(full_tables_cleanup) = 0; ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false); @@ -492,6 +493,7 @@ void shutdown_executor(void) /* {{{ */ zend_stack_destroy(&EG(user_error_handlers_error_reporting)); zend_stack_destroy(&EG(user_error_handlers)); zend_stack_destroy(&EG(user_exception_handlers)); + zend_lazy_objects_destroy(&EG(lazy_objects_store)); zend_objects_store_destroy(&EG(objects_store)); if (EG(in_autoload)) { zend_hash_destroy(EG(in_autoload)); diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 273647692d824..97b7cdcc911b7 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -19,6 +19,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_gc.h" #include "zend_ini.h" #include "zend_variables.h" #include "zend_vm.h" @@ -28,6 +29,7 @@ #include "zend_mmap.h" #include "zend_compile.h" #include "zend_closures.h" +#include "zend_generators.h" #include "zend_fibers.h" #include "zend_fibers_arginfo.h" @@ -824,7 +826,25 @@ static HashTable *zend_fiber_object_gc(zend_object *object, zval **table, int *n HashTable *lastSymTable = NULL; zend_execute_data *ex = fiber->execute_data; for (; ex; ex = ex->prev_execute_data) { - HashTable *symTable = zend_unfinished_execution_gc_ex(ex, ex->func && ZEND_USER_CODE(ex->func->type) ? ex->call : NULL, buf, false); + HashTable *symTable; + if (ZEND_CALL_INFO(ex) & ZEND_CALL_GENERATOR) { + /* The generator object is stored in ex->return_value */ + zend_generator *generator = (zend_generator*)ex->return_value; + /* There are two cases to consider: + * - If the generator is currently running, the Generator's GC + * handler will ignore it because it is not collectable. However, + * in this context the generator is suspended in Fiber::suspend() + * and may be collectable, so we can inspect it. + * - If the generator is not running, the Generator's GC handler + * will inspect it. In this case we have to skip the frame. + */ + if (!(generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING)) { + continue; + } + symTable = zend_generator_frame_gc(buf, generator); + } else { + symTable = zend_unfinished_execution_gc_ex(ex, ex->func && ZEND_USER_CODE(ex->func->type) ? ex->call : NULL, buf, false); + } if (symTable) { if (lastSymTable) { zval *val; diff --git a/Zend/zend_fibers_arginfo.h b/Zend/zend_fibers_arginfo.h index 950dbd26ed60f..9db4db8d802af 100644 --- a/Zend/zend_fibers_arginfo.h +++ b/Zend/zend_fibers_arginfo.h @@ -75,8 +75,7 @@ static zend_class_entry *register_class_Fiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Fiber", class_Fiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -86,8 +85,7 @@ static zend_class_entry *register_class_FiberError(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FiberError", class_FiberError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_FINAL); return class_entry; } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 3ec308246c7c1..d600c662f9387 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -395,11 +395,38 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */ } /* }}} */ +HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator *generator) +{ + zend_execute_data *execute_data = generator->execute_data; + zend_execute_data *call = NULL; + + zend_get_gc_buffer_add_zval(gc_buffer, &generator->value); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->key); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->retval); + zend_get_gc_buffer_add_zval(gc_buffer, &generator->values); + + if (UNEXPECTED(generator->frozen_call_stack)) { + /* The frozen stack is linked in reverse order */ + call = zend_generator_revert_call_stack(generator->frozen_call_stack); + } + + HashTable *ht = zend_unfinished_execution_gc_ex(execute_data, call, gc_buffer, true); + + if (UNEXPECTED(generator->frozen_call_stack)) { + zend_generator_revert_call_stack(call); + } + + if (generator->node.parent) { + zend_get_gc_buffer_add_obj(gc_buffer, &generator->node.parent->std); + } + + return ht; +} + static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *n) /* {{{ */ { zend_generator *generator = (zend_generator*)object; zend_execute_data *execute_data = generator->execute_data; - zend_execute_data *call = NULL; if (!execute_data) { if (UNEXPECTED(generator->func->common.fn_flags & ZEND_ACC_CLOSURE)) { @@ -428,34 +455,11 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int * return NULL; } - zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); - zend_get_gc_buffer_add_zval(gc_buffer, &generator->value); - zend_get_gc_buffer_add_zval(gc_buffer, &generator->key); - zend_get_gc_buffer_add_zval(gc_buffer, &generator->retval); - zend_get_gc_buffer_add_zval(gc_buffer, &generator->values); - - if (UNEXPECTED(generator->frozen_call_stack)) { - /* The frozen stack is linked in reverse order */ - call = zend_generator_revert_call_stack(generator->frozen_call_stack); - } - - zend_unfinished_execution_gc_ex(execute_data, call, gc_buffer, true); - - if (UNEXPECTED(generator->frozen_call_stack)) { - zend_generator_revert_call_stack(call); - } - - if (generator->node.parent) { - zend_get_gc_buffer_add_obj(gc_buffer, &generator->node.parent->std); - } - + HashTable *ht = zend_generator_frame_gc(gc_buffer, generator); zend_get_gc_buffer_use(gc_buffer, table, n); - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - return execute_data->symbol_table; - } else { - return NULL; - } + + return ht; } /* }}} */ diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index a38f0952c5fb2..9e3e534073435 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -135,6 +135,8 @@ static zend_always_inline zend_generator *zend_generator_get_current(zend_genera return zend_generator_update_current(generator); } +HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator *generator); + END_EXTERN_C() #endif diff --git a/Zend/zend_generators_arginfo.h b/Zend/zend_generators_arginfo.h index be7131fc8ff26..dd8200d4719af 100644 --- a/Zend/zend_generators_arginfo.h +++ b/Zend/zend_generators_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_Generator(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Generator", class_Generator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; @@ -71,7 +70,7 @@ static zend_class_entry *register_class_ClosedGeneratorException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ClosedGeneratorException", class_ClosedGeneratorException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 3aa967b8dd6bb..539793c8325a6 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -42,6 +42,7 @@ #include "zend_call_stack.h" #include "zend_max_execution_timer.h" #include "zend_strtod.h" +#include "zend_lazy_objects.h" /* Define ZTS if you want a thread-safe Zend */ /*#undef ZTS*/ @@ -246,6 +247,7 @@ struct _zend_executor_globals { zend_ini_entry *error_reporting_ini_entry; zend_objects_store objects_store; + zend_lazy_objects_store lazy_objects_store; zend_object *exception, *prev_exception; const zend_op *opline_before_exception; zend_op exception_op[3]; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b43544766b848..9d7c7f179de7d 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -212,6 +212,18 @@ char *zend_visibility_string(uint32_t fn_flags) /* {{{ */ } /* }}} */ +static const char *zend_asymmetric_visibility_string(uint32_t fn_flags) /* {{{ */ +{ + if (fn_flags & ZEND_ACC_PRIVATE_SET) { + return "private(set)"; + } else if (fn_flags & ZEND_ACC_PROTECTED_SET) { + return "protected(set)"; + } else { + ZEND_ASSERT(!(fn_flags & ZEND_ACC_PUBLIC_SET)); + return "omitted"; + } +} + static zend_string *resolve_class_name(zend_class_entry *scope, zend_string *name) { ZEND_ASSERT(scope); if (zend_string_equals_literal_ci(name, "parent") && scope->parent) { @@ -1396,7 +1408,7 @@ static void inherit_property_hook( } static prop_variance prop_get_variance(zend_property_info *prop_info) { - bool unbacked = prop_info->flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_VIRTUAL); + bool unbacked = prop_info->flags & ZEND_ACC_VIRTUAL; if (unbacked && prop_info->hooks) { if (!prop_info->hooks[ZEND_PROPERTY_HOOK_SET]) { return PROP_COVARIANT; @@ -1442,6 +1454,25 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke ZSTR_VAL(ce->name), ZSTR_VAL(key)); } } + if (UNEXPECTED((child_info->flags & ZEND_ACC_PPP_SET_MASK)) + /* Get-only virtual properties have no set visibility, so any child visibility is fine. */ + && !(parent_info->hooks && (parent_info->flags & ZEND_ACC_VIRTUAL) && !parent_info->hooks[ZEND_PROPERTY_HOOK_SET])) { + uint32_t parent_set_visibility = parent_info->flags & ZEND_ACC_PPP_SET_MASK; + /* Adding set protection is fine if it's the same or weaker than + * the parents full property visibility. */ + if (!parent_set_visibility) { + parent_set_visibility = zend_visibility_to_set_visibility(parent_info->flags & ZEND_ACC_PPP_MASK); + } + uint32_t child_set_visibility = child_info->flags & ZEND_ACC_PPP_SET_MASK; + if (child_set_visibility > parent_set_visibility) { + zend_error_noreturn( + E_COMPILE_ERROR, + "Set access level of %s::$%s must be %s (as in class %s)%s", + ZSTR_VAL(ce->name), ZSTR_VAL(key), + zend_asymmetric_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), + !(parent_info->flags & ZEND_ACC_PPP_SET_MASK) ? "" : " or weaker"); + } + } if (UNEXPECTED((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK))) { zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ZSTR_VAL(ce->name), ZSTR_VAL(key), zend_visibility_string(parent_info->flags), ZSTR_VAL(parent_info->ce->name), (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); diff --git a/Zend/zend_interfaces_arginfo.h b/Zend/zend_interfaces_arginfo.h index bcdc8dd87c473..27af62825f90a 100644 --- a/Zend/zend_interfaces_arginfo.h +++ b/Zend/zend_interfaces_arginfo.h @@ -198,8 +198,7 @@ static zend_class_entry *register_class_InternalIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InternalIterator", class_InternalIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f7822caa88dc3..d2a29e670d8bf 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -154,6 +154,9 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_PRIVATE "'private'" %token T_PROTECTED "'protected'" %token T_PUBLIC "'public'" +%token T_PRIVATE_SET "'private(set)'" +%token T_PROTECTED_SET "'protected(set)'" +%token T_PUBLIC_SET "'public(set)'" %token T_READONLY "'readonly'" %token T_VAR "'var'" %token T_UNSET "'unset'" @@ -258,7 +261,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type absolute_trait_method_reference trait_method_reference property echo_expr %type new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable %type internal_functions_in_yacc -%type exit_expr scalar backticks_expr lexical_var function_call member_name property_name +%type scalar backticks_expr lexical_var function_call member_name property_name %type variable_class_name dereferenceable_scalar constant class_constant %type fully_dereferenceable array_object_dereferenceable %type callable_expr callable_variable static_member new_variable @@ -1066,6 +1069,9 @@ member_modifier: T_PUBLIC { $$ = T_PUBLIC; } | T_PROTECTED { $$ = T_PROTECTED; } | T_PRIVATE { $$ = T_PRIVATE; } + | T_PUBLIC_SET { $$ = T_PUBLIC_SET; } + | T_PROTECTED_SET { $$ = T_PROTECTED_SET; } + | T_PRIVATE_SET { $$ = T_PRIVATE_SET; } | T_STATIC { $$ = T_STATIC; } | T_ABSTRACT { $$ = T_ABSTRACT; } | T_FINAL { $$ = T_FINAL; } @@ -1304,7 +1310,11 @@ expr: | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); } | T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); } | T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); } - | T_EXIT exit_expr { $$ = zend_ast_create(ZEND_AST_EXIT, $2); } + | T_EXIT ctor_arguments { + zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_EXIT)); + name->attr = ZEND_NAME_FQ; + $$ = zend_ast_create(ZEND_AST_CALL, name, $2); + } | '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); } | scalar { $$ = $1; } | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); } @@ -1407,11 +1417,6 @@ class_name_reference: | '(' expr ')' { $$ = $2; } ; -exit_expr: - %empty { $$ = NULL; } - | '(' optional_expr ')' { $$ = $2; } -; - backticks_expr: %empty { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 4551d26a17e79..194f5a995fbce 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1725,6 +1725,18 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN_WITH_IDENT(T_PROTECTED); } +"public(set)" { + RETURN_TOKEN_WITH_IDENT(T_PUBLIC_SET); +} + +"protected(set)" { + RETURN_TOKEN_WITH_IDENT(T_PROTECTED_SET); +} + +"private(set)" { + RETURN_TOKEN_WITH_IDENT(T_PRIVATE_SET); +} + "public" { RETURN_TOKEN_WITH_IDENT(T_PUBLIC); } diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c new file mode 100644 index 0000000000000..357150bc63876 --- /dev/null +++ b/Zend/zend_lazy_objects.c @@ -0,0 +1,736 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +/* Lazy objects are standard zend_object whose initialization is defered until + * one of their properties backing store is accessed for the first time. + * + * This is implemented by using the same fallback mechanism as __get and __set + * magic methods that is triggered when an undefined property is accessed. + * + * Execution of methods or virtual property hooks do not trigger initialization + * until they access properties. + * + * A lazy object can be created via the Reflection API. The user specifies an + * initializer function that is called when initialization is required. + * + * There are two kinds of lazy objects: + * + * - Ghosts: These are initialized in-place by the initializer function + * - Proxy: The initializer returns a new instance. After initialization, + * interaction with the proxy object are proxied to the instance. + * + * Internal objects are not supported. + */ + +#include "zend_API.h" +#include "zend_compile.h" +#include "zend_execute.h" +#include "zend_gc.h" +#include "zend_hash.h" +#include "zend_object_handlers.h" +#include "zend_objects_API.h" +#include "zend_operators.h" +#include "zend_types.h" +#include "zend_variables.h" +#include "zend_lazy_objects.h" + +/** + * Information about each lazy object is stored outside of zend_objects, in + * EG(lazy_objects_store). For ghost objects, we can release this after the + * object is initialized. + */ +typedef struct _zend_lazy_object_info { + union { + struct { + zend_fcall_info_cache fcc; + zval zv; /* ReflectionClass::getLazyInitializer() */ + } initializer; + zend_object *instance; /* For initialized lazy proxy objects */ + } u; + zend_lazy_object_flags_t flags; + int lazy_properties_count; +} zend_lazy_object_info; + +/* zend_hash dtor_func_t for zend_lazy_objects_store.infos */ +static void zend_lazy_object_info_dtor_func(zval *pElement) +{ + zend_lazy_object_info *info = (zend_lazy_object_info*) Z_PTR_P(pElement); + + if (info->flags & ZEND_LAZY_OBJECT_INITIALIZED) { + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_STRATEGY_PROXY); + zend_object_release(info->u.instance); + } else { + zval_ptr_dtor(&info->u.initializer.zv); + zend_fcc_dtor(&info->u.initializer.fcc); + } + + efree(info); +} + +void zend_lazy_objects_init(zend_lazy_objects_store *store) +{ + zend_hash_init(&store->infos, 8, NULL, zend_lazy_object_info_dtor_func, false); +} + +void zend_lazy_objects_destroy(zend_lazy_objects_store *store) +{ + ZEND_ASSERT(zend_hash_num_elements(&store->infos) == 0 || CG(unclean_shutdown)); + zend_hash_destroy(&store->infos); +} + +static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + + zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); + ZEND_ASSERT(zv); + (void)zv; +} + +static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + + zend_lazy_object_info *info = zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(info); + + return info; +} + +static bool zend_lazy_object_has_stale_info(zend_object *obj) +{ + return zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle); +} + +zval* zend_lazy_object_get_initializer_zv(zend_object *obj) +{ + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(!(info->flags & ZEND_LAZY_OBJECT_INITIALIZED)); + + return &info->u.initializer.zv; +} + +static zend_fcall_info_cache* zend_lazy_object_get_initializer_fcc(zend_object *obj) +{ + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(!(info->flags & ZEND_LAZY_OBJECT_INITIALIZED)); + + return &info->u.initializer.fcc; +} + +zend_object* zend_lazy_object_get_instance(zend_object *obj) +{ + ZEND_ASSERT(zend_lazy_object_initialized(obj)); + + if (zend_object_is_lazy_proxy(obj)) { + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_INITIALIZED); + + return info->u.instance; + } + + return obj; +} + +zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj) +{ + return zend_lazy_object_get_info(obj)->flags; +} + +void zend_lazy_object_del_info(zend_object *obj) +{ + zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(res == SUCCESS); +} + +bool zend_lazy_object_decr_lazy_props(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + ZEND_ASSERT(info->lazy_properties_count > 0); + + info->lazy_properties_count--; + + return info->lazy_properties_count == 0; +} + +/** + * Making objects lazy + */ + +ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce) +{ + /* Internal classes are not supported */ + if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) { + return false; + } + + for (zend_class_entry *parent = ce->parent; parent; parent = parent->parent) { + if (UNEXPECTED(parent->type == ZEND_INTERNAL_CLASS && parent != zend_standard_class_def)) { + return false; + } + } + + return true; +} + +/* Make object 'obj' lazy. If 'obj' is NULL, create a lazy instance of + * class 'reflection_ce' */ +ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, + zend_class_entry *reflection_ce, zval *initializer_zv, + zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags) +{ + ZEND_ASSERT(!(flags & ~(ZEND_LAZY_OBJECT_USER_MASK|ZEND_LAZY_OBJECT_STRATEGY_MASK))); + ZEND_ASSERT((flags & ZEND_LAZY_OBJECT_STRATEGY_MASK) == ZEND_LAZY_OBJECT_STRATEGY_GHOST + || (flags & ZEND_LAZY_OBJECT_STRATEGY_MASK) == ZEND_LAZY_OBJECT_STRATEGY_PROXY); + + ZEND_ASSERT(!obj || (!zend_object_is_lazy(obj) || zend_lazy_object_initialized(obj))); + ZEND_ASSERT(!obj || instanceof_function(obj->ce, reflection_ce)); + + /* Internal classes are not supported */ + if (UNEXPECTED(reflection_ce->type == ZEND_INTERNAL_CLASS && reflection_ce != zend_standard_class_def)) { + zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s is internal", ZSTR_VAL(reflection_ce->name)); + return NULL; + } + + for (zend_class_entry *parent = reflection_ce->parent; parent; parent = parent->parent) { + if (UNEXPECTED(parent->type == ZEND_INTERNAL_CLASS && parent != zend_standard_class_def)) { + zend_throw_error(NULL, "Cannot make instance of internal class lazy: %s inherits internal class %s", + ZSTR_VAL(reflection_ce->name), ZSTR_VAL(parent->name)); + return NULL; + } + } + + int lazy_properties_count = 0; + + if (!obj) { + if (UNEXPECTED(reflection_ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) { + zval zobj; + /* Call object_init_ex() for the generated exception */ + zend_result result = object_init_ex(&zobj, reflection_ce); + ZEND_ASSERT(result == FAILURE && EG(exception)); + (void)result; + return NULL; + } + + obj = zend_objects_new(reflection_ce); + + for (int i = 0; i < obj->ce->default_properties_count; i++) { + zval *p = &obj->properties_table[i]; + ZVAL_UNDEF(p); + if (EXPECTED(obj->ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + lazy_properties_count++; + } else { + Z_PROP_FLAG_P(p) = 0; + } + } + } else { + if (zend_object_is_lazy(obj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(obj) && zend_lazy_object_initialized(obj)); + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); + zend_lazy_object_del_info(obj); + } else { + if (zend_lazy_object_has_stale_info(obj)) { + zend_throw_error(NULL, "Can not reset an object while it is being initialized"); + return NULL; + } + + if (!(flags & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR) + && !(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { + if (obj->handlers->dtor_obj != zend_objects_destroy_object + || obj->ce->destructor) { + GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); + GC_ADDREF(obj); + obj->handlers->dtor_obj(obj); + GC_DELREF(obj); + if (EG(exception)) { + return NULL; + } + } + } + } + + GC_DEL_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); + + /* unset() dynamic properties */ + zend_object_dtor_dynamic_properties(obj); + obj->properties = NULL; + + /* unset() declared properties */ + for (int i = 0; i < reflection_ce->default_properties_count; i++) { + zend_property_info *prop_info = obj->ce->properties_info_table[i]; + if (EXPECTED(prop_info)) { + zval *p = &obj->properties_table[i]; + if (Z_TYPE_P(p) != IS_UNDEF) { + if ((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(p) & IS_PROP_REINITABLE) + /* TODO: test final property */ + && ((obj->ce->ce_flags & ZEND_ACC_FINAL) || (prop_info->flags & ZEND_ACC_FINAL))) { + continue; + } + zend_object_dtor_property(obj, p); + ZVAL_UNDEF(p); + } + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + lazy_properties_count++; + } + } + } + + /* Objects become non-lazy if all properties are made non-lazy before + * initialization is triggerd. If the object has no properties to begin + * with, this happens immediately. */ + if (UNEXPECTED(!lazy_properties_count)) { + return obj; + } + + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED; + + if (flags & ZEND_LAZY_OBJECT_STRATEGY_PROXY) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_PROXY; + } else { + ZEND_ASSERT(flags & ZEND_LAZY_OBJECT_STRATEGY_GHOST); + } + + zend_lazy_object_info *info = emalloc(sizeof(*info)); + zend_fcc_dup(&info->u.initializer.fcc, initializer_fcc); + ZVAL_COPY(&info->u.initializer.zv, initializer_zv); + info->flags = flags; + info->lazy_properties_count = lazy_properties_count; + zend_lazy_object_set_info(obj, info); + + return obj; +} + +/** + * Initialization of lazy objects + */ + +/* Mark object as initialized. Lazy properties are initialized to their default + * value and the initializer is not called. */ +ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_class_entry *ce = obj->ce; + + if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + ZEND_ASSERT(EG(exception)); + return NULL; + } + } + + zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce); + zval *properties_table = obj->properties_table; + + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); + + for (int i = 0; i < ce->default_properties_count; i++) { + if (Z_PROP_FLAG_P(&properties_table[i]) & IS_PROP_LAZY) { + ZVAL_COPY_PROP(&properties_table[i], &default_properties_table[i]); + } + } + + zend_lazy_object_del_info(obj); + + return obj; +} + +/* Revert initializer effects */ +static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_table_snapshot, HashTable *properties_snapshot) +{ + zend_class_entry *ce = obj->ce; + + if (ce->default_properties_count) { + ZEND_ASSERT(properties_table_snapshot); + zval *properties_table = obj->properties_table; + + for (int i = 0; i < ce->default_properties_count; i++) { + zval *p = &properties_table[i]; + zend_object_dtor_property(obj, p); + ZVAL_COPY_VALUE_PROP(p, &properties_table_snapshot[i]); + + zend_property_info *prop_info = ce->properties_info_table[i]; + if (Z_ISREF_P(p) && prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(p), prop_info); + } + } + + efree(properties_table_snapshot); + } + if (properties_snapshot) { + if (obj->properties != properties_snapshot) { + ZEND_ASSERT((GC_FLAGS(properties_snapshot) & IS_ARRAY_IMMUTABLE) || GC_REFCOUNT(properties_snapshot) >= 1); + zend_release_properties(obj->properties); + obj->properties = properties_snapshot; + } else { + ZEND_ASSERT((GC_FLAGS(properties_snapshot) & IS_ARRAY_IMMUTABLE) || GC_REFCOUNT(properties_snapshot) > 1); + zend_release_properties(properties_snapshot); + } + } else if (obj->properties) { + zend_release_properties(obj->properties); + obj->properties = NULL; + } + + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED; +} + +static bool zend_lazy_object_compatible(zend_object *real_object, zend_object *lazy_object) +{ + if (EXPECTED(real_object->ce == lazy_object->ce)) { + return true; + } + + if (!instanceof_function(lazy_object->ce, real_object->ce)) { + return false; + } + + /* zend_hash_num_elements(ce.properties_info) reports the actual number of + * properties. ce.default_properties_count is off by the number of property + * overrides. */ + if (zend_hash_num_elements(&lazy_object->ce->properties_info) != zend_hash_num_elements(&real_object->ce->properties_info)) { + return false; + } + + return lazy_object->ce->destructor == real_object->ce->destructor + && lazy_object->ce->clone == real_object->ce->clone; +} + +/* Initialize a lazy proxy object */ +static zend_object *zend_lazy_object_init_proxy(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy_proxy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + + /* prevent reentrant initialization */ + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY); + + /* Call factory */ + zval retval; + int argc = 1; + zval zobj; + HashTable *named_params = NULL; + zend_fcall_info_cache *initializer = &info->u.initializer.fcc; + + ZVAL_OBJ(&zobj, obj); + + zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params); + + if (UNEXPECTED(EG(exception))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; + return NULL; + } + + if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT)) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; + zend_type_error("Lazy proxy factory must return an instance of a class compatible with %s, %s returned", + ZSTR_VAL(obj->ce->name), + zend_zval_value_name(&retval)); + zval_ptr_dtor(&retval); + return NULL; + + } + + if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT || !zend_lazy_object_compatible(Z_OBJ(retval), obj))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; + zend_type_error("The real instance class %s is not compatible with the proxy class %s. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.", + zend_zval_value_name(&retval), + ZSTR_VAL(obj->ce->name)); + zval_ptr_dtor(&retval); + return NULL; + } + + if (UNEXPECTED(Z_OBJ(retval) == obj || zend_object_is_lazy(Z_OBJ(retval)))) { + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY; + zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object"); + zval_ptr_dtor(&retval); + return NULL; + } + + zend_fcc_dtor(&info->u.initializer.fcc); + zval_ptr_dtor(&info->u.initializer.zv); + info->u.instance = Z_OBJ(retval); + info->flags |= ZEND_LAZY_OBJECT_INITIALIZED; + OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_PROXY; + + /* unset() properties of the proxy. This ensures that all accesses are be + * delegated to the backing instance from now on. */ + zend_object_dtor_dynamic_properties(obj); + obj->properties = NULL; + + for (int i = 0; i < Z_OBJ(retval)->ce->default_properties_count; i++) { + if (EXPECTED(Z_OBJ(retval)->ce->properties_info_table[i])) { + zend_object_dtor_property(obj, &obj->properties_table[i]); + ZVAL_UNDEF(&obj->properties_table[i]); + Z_PROP_FLAG_P(&obj->properties_table[i]) = IS_PROP_UNINIT | IS_PROP_LAZY; + } + } + + return Z_OBJ(retval); +} + +/* Initialize a lazy object. */ +ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + + /* If obj is an initialized lazy proxy, return the real instance. This + * supports the following pattern: + * if (zend_lazy_object_must_init(obj)) { + * instance = zend_lazy_object_init(obj); + * } + */ + if (zend_lazy_object_initialized(obj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(obj)); + zend_lazy_object_info *info = zend_lazy_object_get_info(obj); + ZEND_ASSERT(info->flags & ZEND_LAZY_OBJECT_INITIALIZED); + return info->u.instance; + } + + zend_class_entry *ce = obj->ce; + + if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + ZEND_ASSERT(EG(exception)); + return NULL; + } + } + + if (zend_object_is_lazy_proxy(obj)) { + return zend_lazy_object_init_proxy(obj); + } + + zend_fcall_info_cache *initializer = zend_lazy_object_get_initializer_fcc(obj); + + /* Prevent reentrant initialization */ + OBJ_EXTRA_FLAGS(obj) &= ~IS_OBJ_LAZY_UNINITIALIZED; + + /* Snapshot dynamic properties */ + HashTable *properties_snapshot = obj->properties; + if (properties_snapshot) { + GC_TRY_ADDREF(properties_snapshot); + } + + zval *properties_table_snapshot = NULL; + + /* Snapshot declared properties and initialize lazy properties to their + * default value */ + if (ce->default_properties_count) { + zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce); + zval *properties_table = obj->properties_table; + properties_table_snapshot = emalloc(sizeof(*properties_table_snapshot) * ce->default_properties_count); + + for (int i = 0; i < ce->default_properties_count; i++) { + ZVAL_COPY_PROP(&properties_table_snapshot[i], &properties_table[i]); + if (Z_PROP_FLAG_P(&properties_table[i]) & IS_PROP_LAZY) { + ZVAL_COPY_PROP(&properties_table[i], &default_properties_table[i]); + } + } + } + + /* Call initializer */ + zval retval; + int argc = 1; + zval zobj; + HashTable *named_params = NULL; + + ZVAL_OBJ(&zobj, obj); + + zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params); + + if (EG(exception)) { + zend_lazy_object_revert_init(obj, properties_table_snapshot, properties_snapshot); + return NULL; + } + + if (Z_TYPE(retval) != IS_NULL) { + zend_lazy_object_revert_init(obj, properties_table_snapshot, properties_snapshot); + zval_ptr_dtor(&retval); + zend_type_error("Lazy object initializer must return NULL or no value"); + return NULL; + } + + if (properties_table_snapshot) { + for (int i = 0; i < obj->ce->default_properties_count; i++) { + zval *p = &properties_table_snapshot[i]; + /* Use zval_ptr_dtor directly here (not zend_object_dtor_property), + * as any reference type_source will have already been deleted in + * case the prop is not bound to this value anymore. */ + i_zval_ptr_dtor(p); + } + efree(properties_table_snapshot); + } + + if (properties_snapshot) { + zend_release_properties(properties_snapshot); + } + + /* Must be very last in this function, for the + * zend_lazy_object_has_stale_info() check */ + zend_lazy_object_del_info(obj); + + return obj; +} + +/* Mark an object as non-lazy (after all properties were initialized) */ +void zend_lazy_object_realize(zend_object *obj) +{ + ZEND_ASSERT(zend_object_is_lazy(obj)); + ZEND_ASSERT(!zend_lazy_object_initialized(obj)); + + zend_lazy_object_del_info(obj); + +#if ZEND_DEBUG + for (int i = 0; i < obj->ce->default_properties_count; i++) { + ZEND_ASSERT(!(Z_PROP_FLAG_P(&obj->properties_table[i]) & IS_PROP_LAZY)); + } +#endif + + OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY); +} + +ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object) +{ + ZEND_ASSERT(zend_object_is_lazy(object)); + + zend_object *tmp = zend_lazy_object_init(object); + if (UNEXPECTED(!tmp)) { + ZEND_ASSERT(!object->properties || object->properties == &zend_empty_array); + return object->properties = (zend_array*) &zend_empty_array; + } + + object = tmp; + ZEND_ASSERT(!zend_lazy_object_must_init(object)); + + return zend_std_get_properties_ex(object); +} + +/* Initialize object and clone it. For proxies, we clone both the proxy and its + * real instance, and we don't call __clone() on the proxy. */ +zend_object *zend_lazy_object_clone(zend_object *old_obj) +{ + ZEND_ASSERT(zend_object_is_lazy(old_obj)); + + if (UNEXPECTED(!zend_lazy_object_initialized(old_obj) && !zend_lazy_object_init(old_obj))) { + ZEND_ASSERT(EG(exception)); + /* Clone handler must always return an object. It is discarded later due + * to the exception. */ + zval zv; + object_init_ex(&zv, old_obj->ce); + GC_ADD_FLAGS(Z_OBJ(zv), IS_OBJ_DESTRUCTOR_CALLED); + return Z_OBJ(zv); + } + + if (!zend_object_is_lazy_proxy(old_obj)) { + return zend_objects_clone_obj(old_obj); + } + + zend_lazy_object_info *info = zend_lazy_object_get_info(old_obj); + zend_class_entry *ce = old_obj->ce; + zend_object *new_proxy = zend_objects_new(ce); + + for (int i = 0; i < ce->default_properties_count; i++) { + zval *p = &new_proxy->properties_table[i]; + ZVAL_UNDEF(p); + if (EXPECTED(ce->properties_info_table[i])) { + Z_PROP_FLAG_P(p) = IS_PROP_UNINIT | IS_PROP_LAZY; + } else { + Z_PROP_FLAG_P(p) = 0; + } + } + + OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj); + + zend_lazy_object_info *new_info = emalloc(sizeof(*info)); + *new_info = *info; + new_info->u.instance = zend_objects_clone_obj(info->u.instance); + + zend_lazy_object_set_info(new_proxy, new_info); + + return new_proxy; +} + +HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp) +{ + ZEND_ASSERT(zend_object_is_lazy(object)); + + if (zend_object_is_lazy_proxy(object)) { + if (zend_lazy_object_initialized(object)) { + HashTable *properties = zend_new_array(0); + zval instance; + ZVAL_OBJ(&instance, zend_lazy_object_get_instance(object)); + Z_ADDREF(instance); + zend_hash_str_add(properties, "instance", strlen("instance"), &instance); + *is_temp = 1; + return properties; + } + } + + *is_temp = 0; + return zend_get_properties_no_lazy_init(object); +} + +HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n) +{ + ZEND_ASSERT(zend_object_is_lazy(zobj)); + + zend_lazy_object_info *info = zend_lazy_object_get_info(zobj); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + + if (zend_lazy_object_initialized(zobj)) { + ZEND_ASSERT(zend_object_is_lazy_proxy(zobj)); + zend_get_gc_buffer_add_obj(gc_buffer, info->u.instance); + zend_get_gc_buffer_use(gc_buffer, table, n); + /* Initialized proxy object can not have properties */ + return NULL; + } + + zend_fcall_info_cache *fcc = &info->u.initializer.fcc; + if (fcc->object) { + zend_get_gc_buffer_add_obj(gc_buffer, fcc->object); + } + if (fcc->closure) { + zend_get_gc_buffer_add_obj(gc_buffer, fcc->closure); + } + zend_get_gc_buffer_add_zval(gc_buffer, &info->u.initializer.zv); + + /* Uninitialized lazy objects can not have dynamic properties, so we can + * ignore zobj->properties. */ + zval *prop = zobj->properties_table; + zval *end = prop + zobj->ce->default_properties_count; + for ( ; prop < end; prop++) { + zend_get_gc_buffer_add_zval(gc_buffer, prop); + } + + zend_get_gc_buffer_use(gc_buffer, table, n); + return NULL; +} diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h new file mode 100644 index 0000000000000..addb07173c3f4 --- /dev/null +++ b/Zend/zend_lazy_objects.h @@ -0,0 +1,106 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_LAZY_OBJECT_H +#define ZEND_LAZY_OBJECT_H + +#include "Zend/zend_types.h" + +/* Lazy object is a lazy proxy object */ +#define ZEND_LAZY_OBJECT_STRATEGY_PROXY (1<<0) + +/* Lazy object is a lazy ghost object */ +#define ZEND_LAZY_OBJECT_STRATEGY_GHOST (1<<1) + +/* Lazy object is initialized (info.u is an instance) */ +#define ZEND_LAZY_OBJECT_INITIALIZED (1<<2) + +/* Serialization skips initialization */ +#define ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE (1<<3) + +/* Do not call destructor when making existing object lazy */ +#define ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR (1<<4) + +#define ZEND_LAZY_OBJECT_USER_MASK ( \ + ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE | \ + ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR \ +) + +#define ZEND_LAZY_OBJECT_STRATEGY_MASK ( \ + ZEND_LAZY_OBJECT_STRATEGY_PROXY | \ + ZEND_LAZY_OBJECT_STRATEGY_GHOST \ +) + +typedef uint8_t zend_lazy_object_flags_t; + +typedef struct _zend_lazy_objects_store { + /* object handle -> *zend_lazy_object_info */ + HashTable infos; +} zend_lazy_objects_store; + +typedef struct _zend_fcall_info zend_fcall_info; +typedef struct _zend_fcall_info_cache zend_fcall_info_cache; + +ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce); +ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, + zend_class_entry *class_type, zval *initializer_zv, + zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags); +ZEND_API zend_object *zend_lazy_object_init(zend_object *obj); +ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj); + +void zend_lazy_objects_init(zend_lazy_objects_store *store); +void zend_lazy_objects_destroy(zend_lazy_objects_store *store); +zval* zend_lazy_object_get_initializer_zv(zend_object *obj); +zend_object *zend_lazy_object_get_instance(zend_object *obj); +zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj); +void zend_lazy_object_del_info(zend_object *obj); +ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object); +zend_object *zend_lazy_object_clone(zend_object *old_obj); +HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); +HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n); +bool zend_lazy_object_decr_lazy_props(zend_object *obj); +void zend_lazy_object_realize(zend_object *obj); + +static zend_always_inline bool zend_object_is_lazy(zend_object *obj) +{ + return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY)); +} + +static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj) +{ + return (OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_PROXY); +} + +static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj) +{ + return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_UNINITIALIZED); +} + +/* True if accessing a lazy prop on obj mandates a call to + * zend_lazy_object_init() */ +static zend_always_inline bool zend_lazy_object_must_init(zend_object *obj) +{ + return zend_object_is_lazy(obj); +} + +static inline bool zend_lazy_object_initialize_on_serialize(zend_object *obj) +{ + return !(zend_lazy_object_get_flags(obj) & ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); +} + +#endif /* ZEND_LAZY_OBJECT_H */ diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c index 6f09d2fa22707..005ce14868a0a 100644 --- a/Zend/zend_max_execution_timer.c +++ b/Zend/zend_max_execution_timer.c @@ -29,6 +29,11 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_portability.h" + +#if __has_feature(memory_sanitizer) +# include +#endif // Musl Libc defines this macro, glibc does not // According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417 @@ -61,6 +66,12 @@ ZEND_API void zend_max_execution_timer_init(void) /* {{{ */ sev.sigev_notify_thread_id = (pid_t) syscall(SYS_gettid); # endif +#if __has_feature(memory_sanitizer) + /* MSan does not intercept timer_create() */ + __msan_unpoison(&EG(max_execution_timer_timer), + sizeof(EG(max_execution_timer_timer))); +#endif + // Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727 if (timer_create(ZEND_MAX_EXECUTION_TIMERS_CLOCK, &sev, &EG(max_execution_timer_timer)) != 0) { zend_strerror_noreturn(E_ERROR, errno, "Could not create timer"); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index b365189a11dd5..8a973f4fc0927 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -20,6 +20,7 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_lazy_objects.h" #include "zend_variables.h" #include "zend_API.h" #include "zend_objects.h" @@ -31,7 +32,6 @@ #include "zend_compile.h" #include "zend_hash.h" #include "zend_property_hooks.h" -#include "ext/reflection/php_reflection.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -93,6 +93,7 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj) /* {{{ } /* }}} */ +/* Implements the fast path for array cast */ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* {{{ */ { zend_property_info *prop_info; @@ -101,6 +102,7 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* zval* prop; int i; + ZEND_ASSERT(!(zend_object_is_lazy_proxy(zobj) && zend_lazy_object_initialized(zobj))); ZEND_ASSERT(!zobj->properties); ht = zend_new_array(ce->default_properties_count); if (ce->default_properties_count) { @@ -131,13 +133,31 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* ZEND_API HashTable *zend_std_get_properties(zend_object *zobj) /* {{{ */ { - if (!zobj->properties) { - return rebuild_object_properties_internal(zobj); - } - return zobj->properties; + return zend_std_get_properties_ex(zobj); } /* }}} */ +/* Fetch properties HashTable without triggering lazy initialization */ +ZEND_API HashTable *zend_get_properties_no_lazy_init(zend_object *zobj) +{ + if (zobj->handlers->get_properties == zend_std_get_properties) { + if (UNEXPECTED(zend_object_is_lazy_proxy(zobj) + && zend_lazy_object_initialized(zobj))) { + zend_object *instance = zend_lazy_object_get_instance(zobj); + return zend_get_properties_no_lazy_init(instance); + } + + if (!zobj->properties) { + rebuild_object_properties_internal(zobj); + } + return zobj->properties; + } + + ZEND_ASSERT(!zend_object_is_lazy(zobj)); + + return zobj->handlers->get_properties(zobj); +} + ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /* {{{ */ { if (zobj->handlers->get_properties != zend_std_get_properties) { @@ -145,7 +165,9 @@ ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /* *n = 0; return zobj->handlers->get_properties(zobj); } else { - if (zobj->properties) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + return zend_lazy_object_get_gc(zobj, table, n); + } else if (zobj->properties) { *table = NULL; *n = 0; return zobj->properties; @@ -165,6 +187,10 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) / HashTable *ht; if (!ce->__debugInfo) { + if (UNEXPECTED(zend_object_is_lazy(object))) { + return zend_lazy_object_debug_info(object, is_temp); + } + *is_temp = 0; return object->handlers->get_properties(object); } @@ -305,13 +331,6 @@ static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( return 1; } -static ZEND_COLD zend_never_inline void zend_readonly_property_modification_scope_error( - const zend_class_entry *ce, const zend_string *member, const zend_class_entry *scope, const char *operation) { - zend_throw_error(NULL, "Cannot %s readonly property %s::$%s from %s%s", - operation, ZSTR_VAL(ce->name), ZSTR_VAL(member), - scope ? "scope " : "global scope", scope ? ZSTR_VAL(scope->name) : ""); -} - static ZEND_COLD zend_never_inline void zend_readonly_property_unset_error( zend_class_entry *ce, zend_string *member) { zend_throw_error(NULL, "Cannot unset readonly property %s::$%s", @@ -548,6 +567,17 @@ ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_st } /* }}} */ +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info) { + ZEND_ASSERT(prop_info->flags & ZEND_ACC_PPP_SET_MASK); + ZEND_ASSERT(!(prop_info->flags & ZEND_ACC_PUBLIC_SET)); + zend_class_entry *scope = get_fake_or_executed_scope(); + if (prop_info->ce == scope) { + return true; + } + return EXPECTED((prop_info->flags & ZEND_ACC_PROTECTED_SET) + && is_protected_compatible_scope(prop_info->ce, scope)); +} + static void zend_property_guard_dtor(zval *el) /* {{{ */ { uint32_t *ptr = (uint32_t*)Z_PTR_P(el); if (EXPECTED(!(((uintptr_t)ptr) & 1))) { @@ -687,32 +717,31 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { try_again: retval = OBJ_PROP(zobj, property_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY) - && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) { - if (Z_TYPE_P(retval) == IS_OBJECT) { - /* For objects, W/RW/UNSET fetch modes might not actually modify object. - * Similar as with magic __get() allow them, but return the value as a copy - * to make sure no actual modification is possible. */ - ZVAL_COPY(rv, retval); - retval = rv; - } else { - zend_readonly_property_indirect_modification_error(prop_info); - retval = &EG(uninitialized_zval); - } + + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK)) + && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) + && ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info))) { + if (Z_TYPE_P(retval) == IS_OBJECT) { + /* For objects, W/RW/UNSET fetch modes might not actually modify object. + * Similar as with magic __get() allow them, but return the value as a copy + * to make sure no actual modification is possible. */ + ZVAL_COPY(rv, retval); + retval = rv; + goto exit; + } else if (Z_TYPE_P(retval) == IS_UNDEF && type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + goto exit; } - goto exit; - } else { - if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - if (type == BP_VAR_W || type == BP_VAR_RW) { - zend_readonly_property_indirect_modification_error(prop_info); - retval = &EG(uninitialized_zval); - goto exit; - } else if (type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - goto exit; - } + if (prop_info->flags & ZEND_ACC_READONLY) { + zend_readonly_property_indirect_modification_error(prop_info); + } else { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); } + retval = &EG(uninitialized_zval); + goto exit; + } + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + goto exit; } if (UNEXPECTED(Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT)) { /* Skip __get() for uninitialized typed properties */ @@ -824,6 +853,8 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int goto exit; } + retval = &EG(uninitialized_zval); + /* magic isset */ if ((type == BP_VAR_IS) && zobj->ce->__isset) { zval tmp_result; @@ -892,6 +923,17 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int } uninit_error: + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (!prop_info || (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY)) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + retval = &EG(uninitialized_zval); + goto exit; + } + + return zend_std_read_property(zobj, name, type, cache_slot, rv); + } + } if (type != BP_VAR_IS) { if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); @@ -913,36 +955,12 @@ static zend_always_inline bool property_uses_strict_types(void) { && ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)); } -static bool verify_readonly_initialization_access( - const zend_property_info *prop_info, const zend_class_entry *ce, - zend_string *name, const char *operation) { - zend_class_entry *scope = get_fake_or_executed_scope(); - if (prop_info->ce == scope) { - return true; - } - - /* We may have redeclared a parent property. In that case the parent should still be - * allowed to initialize it. */ - if (scope && is_derived_class(ce, scope)) { - const zend_property_info *prop_info = zend_hash_find_ptr(&scope->properties_info, name); - if (prop_info) { - /* This should be ensured by inheritance. */ - ZEND_ASSERT(prop_info->flags & ZEND_ACC_READONLY); - if (prop_info->ce == scope) { - return true; - } - } - } - - zend_readonly_property_modification_scope_error(prop_info->ce, name, scope, operation); - return false; -} - ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zval *value, void **cache_slot) /* {{{ */ { zval *variable_ptr, tmp; uintptr_t property_offset; const zend_property_info *prop_info = NULL; + uint32_t *guard = NULL; ZEND_ASSERT(!Z_ISREF_P(value)); property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__set != NULL), cache_slot, &prop_info); @@ -950,17 +968,35 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { try_again: variable_ptr = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { - Z_TRY_ADDREF_P(value); - if (prop_info) { - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(variable_ptr) & IS_PROP_REINITABLE))) { - Z_TRY_DELREF_P(value); + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + bool error; + if (Z_TYPE_P(variable_ptr) != IS_UNDEF || (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_UNINIT) || !zobj->ce->__set) { + error = true; + } else { + guard = zend_get_property_guard(zobj, name); + error = (*guard) & IN_SET; + } + if (error) { + if ((prop_info->flags & ZEND_ACC_READONLY) + && Z_TYPE_P(variable_ptr) != IS_UNDEF + && !(Z_PROP_FLAG_P(variable_ptr) & IS_PROP_REINITABLE)) { zend_readonly_property_modification_error(prop_info); variable_ptr = &EG(error_zval); goto exit; } + if ((prop_info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(prop_info)) { + zend_asymmetric_visibility_property_modification_error(prop_info, "modify"); + variable_ptr = &EG(error_zval); + goto exit; + } + } + } + if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { + Z_TRY_ADDREF_P(value); + + if (prop_info) { typed_property: ZVAL_COPY_VALUE(&tmp, value); // Increase refcount to prevent object from being released in __toString() @@ -1009,6 +1045,11 @@ found:; goto exit; } if (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_UNINIT) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (Z_PROP_FLAG_P(variable_ptr) & IS_PROP_LAZY) { + goto lazy_init; + } + } /* Writes to uninitialized typed properties bypass __set(). */ goto write_std_property; } @@ -1074,7 +1115,9 @@ found:; /* magic set */ if (zobj->ce->__set) { - uint32_t *guard = zend_get_property_guard(zobj, name); + if (!guard) { + guard = zend_get_property_guard(zobj, name); + } if (!((*guard) & IN_SET)) { GC_ADDREF(zobj); @@ -1084,6 +1127,10 @@ found:; OBJ_RELEASE(zobj); variable_ptr = value; } else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + goto lazy_init; + } + goto write_std_property; } else { /* Trigger the correct error */ @@ -1094,18 +1141,15 @@ found:; } } else { ZEND_ASSERT(!IS_WRONG_PROPERTY_OFFSET(property_offset)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + goto lazy_init; + } write_std_property: if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { variable_ptr = OBJ_PROP(zobj, property_offset); Z_TRY_ADDREF_P(value); if (prop_info) { - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) - && !verify_readonly_initialization_access(prop_info, zobj->ce, name, "initialize"))) { - Z_TRY_DELREF_P(value); - variable_ptr = &EG(error_zval); - goto exit; - } goto typed_property; } @@ -1124,12 +1168,20 @@ found:; } Z_TRY_ADDREF_P(value); - variable_ptr = zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + variable_ptr = zend_hash_add_new(zend_std_get_properties(zobj), name, value); } } exit: return variable_ptr; + +lazy_init: + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(!zobj)) { + variable_ptr = &EG(error_zval); + goto exit; + } + return zend_std_write_property(zobj, name, value, cache_slot); } /* }}} */ @@ -1260,6 +1312,14 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam if (EXPECTED(!zobj->ce->__get) || UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET) || UNEXPECTED(prop_info && (Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT))) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return &EG(error_zval); + } + + return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot); + } if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { if (prop_info) { zend_typed_property_uninitialized_access(prop_info, name); @@ -1271,9 +1331,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam ZVAL_NULL(retval); } } - } else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - /* Readonly property, delegate to read_property + write_property. */ - retval = NULL; + } else if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info)) { + retval = NULL; + } } else if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) { ZVAL_NULL(retval); } @@ -1281,9 +1342,10 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam /* we do have getter - fail and let it try again with usual get/set */ retval = NULL; } - } else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - /* Readonly property, delegate to read_property + write_property. */ - retval = NULL; + } else if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((prop_info->flags & ZEND_ACC_READONLY) || !zend_asymmetric_property_has_set_access(prop_info)) { + retval = NULL; + } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { if (EXPECTED(zobj->properties)) { @@ -1308,6 +1370,14 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam return &EG(error_zval); } } + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return &EG(error_zval); + } + + return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot); + } if (UNEXPECTED(!zobj->properties)) { rebuild_object_properties_internal(zobj); } @@ -1328,21 +1398,36 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void { uintptr_t property_offset; const zend_property_info *prop_info = NULL; + uint32_t *guard = NULL; property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__unset != NULL), cache_slot, &prop_info); if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { zval *slot = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(slot) != IS_UNDEF) { - if (UNEXPECTED(prop_info && (prop_info->flags & ZEND_ACC_READONLY))) { - if (Z_PROP_FLAG_P(slot) & IS_PROP_REINITABLE) { - Z_PROP_FLAG_P(slot) &= ~IS_PROP_REINITABLE; - } else { + if (prop_info && UNEXPECTED(prop_info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + bool error; + if (Z_TYPE_P(slot) != IS_UNDEF || Z_PROP_FLAG_P(slot) & IS_PROP_UNINIT || !zobj->ce->__unset) { + error = true; + } else { + guard = zend_get_property_guard(zobj, name); + error = (*guard) & IN_UNSET; + } + if (error) { + if ((prop_info->flags & ZEND_ACC_READONLY) + && Z_TYPE_P(slot) != IS_UNDEF + && !(Z_PROP_FLAG_P(slot) & IS_PROP_REINITABLE)) { zend_readonly_property_unset_error(prop_info->ce, name); return; } + if ((prop_info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(prop_info)) { + zend_asymmetric_visibility_property_modification_error(prop_info, "unset"); + return; + } } + } + + if (Z_TYPE_P(slot) != IS_UNDEF) { if (UNEXPECTED(Z_ISREF_P(slot)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(slot)))) { if (prop_info) { @@ -1359,8 +1444,12 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void return; } if (UNEXPECTED(Z_PROP_FLAG_P(slot) & IS_PROP_UNINIT)) { - if (UNEXPECTED(prop_info && (prop_info->flags & ZEND_ACC_READONLY) - && !verify_readonly_initialization_access(prop_info, zobj->ce, name, "unset"))) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(slot) & IS_PROP_LAZY))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return; + } + zend_std_unset_property(zobj, name, cache_slot); return; } @@ -1389,12 +1478,15 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void /* magic unset */ if (zobj->ce->__unset) { - uint32_t *guard = zend_get_property_guard(zobj, name); + if (!guard) { + guard = zend_get_property_guard(zobj, name); + } if (!((*guard) & IN_UNSET)) { /* have unsetter - try with it! */ (*guard) |= IN_UNSET; /* prevent circular unsetting */ zend_std_call_unsetter(zobj, name); (*guard) &= ~IN_UNSET; + return; } else if (UNEXPECTED(IS_WRONG_PROPERTY_OFFSET(property_offset))) { /* Trigger the correct error */ zend_wrong_offset(zobj->ce, name); @@ -1404,6 +1496,15 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void /* Nothing to do: The property already does not exist. */ } } + + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + return; + } + zend_std_unset_property(zobj, name, cache_slot); + return; + } } /* }}} */ @@ -1971,7 +2072,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ if (zobj1->ce != zobj2->ce) { return ZEND_UNCOMPARABLE; /* different classes */ } - if (!zobj1->properties && !zobj2->properties) { + if (!zobj1->properties && !zobj2->properties + && !zend_object_is_lazy(zobj1) && !zend_object_is_lazy(zobj2)) { zend_property_info *info; int i; @@ -2056,8 +2158,7 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has } if (UNEXPECTED(Z_PROP_FLAG_P(value) & IS_PROP_UNINIT)) { /* Skip __isset() for uninitialized typed properties */ - result = false; - goto exit; + goto lazy_init; } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { if (EXPECTED(zobj->properties != NULL)) { @@ -2140,6 +2241,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has goto exit; } + if (!zobj->ce->__isset) { + goto lazy_init; + } + result = false; if ((has_set_exists != ZEND_PROPERTY_EXISTS) && zobj->ce->__isset) { uint32_t *guard = zend_get_property_guard(zobj, name); @@ -2171,6 +2276,22 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has exit: return result; + +lazy_init: + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + if (!value || (Z_PROP_FLAG_P(value) & IS_PROP_LAZY)) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + result = 0; + goto exit; + } + + return zend_std_has_property(zobj, name, has_set_exists, cache_slot); + } + } + + result = 0; + goto exit; } /* }}} */ @@ -2253,14 +2374,29 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp if (obj->ce->num_hooked_props) { return zend_hooked_object_build_properties(obj); } - ZEND_FALLTHROUGH; - case ZEND_PROP_PURPOSE_ARRAY_CAST: - case ZEND_PROP_PURPOSE_SERIALIZE: ht = obj->handlers->get_properties(obj); if (ht) { GC_TRY_ADDREF(ht); } return ht; + case ZEND_PROP_PURPOSE_ARRAY_CAST: + ht = zend_get_properties_no_lazy_init(obj); + if (ht) { + GC_TRY_ADDREF(ht); + } + return ht; + case ZEND_PROP_PURPOSE_SERIALIZE: { + if (zend_object_is_lazy(obj) + && !zend_lazy_object_initialize_on_serialize(obj)) { + ht = zend_get_properties_no_lazy_init(obj); + } else { + ht = obj->handlers->get_properties(obj); + } + if (ht) { + GC_TRY_ADDREF(ht); + } + return ht; + } default: ZEND_UNREACHABLE(); return NULL; diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 730b110eccd37..f36eb765c24a5 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -22,8 +22,10 @@ #include +#include "zend_hash.h" #include "zend_types.h" #include "zend_property_hooks.h" +#include "zend_lazy_objects.h" struct _zend_property_info; @@ -251,6 +253,7 @@ ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zen ZEND_API zend_function *zend_std_get_constructor(zend_object *object); ZEND_API struct _zend_property_info *zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent); ZEND_API HashTable *zend_std_get_properties(zend_object *object); +ZEND_API HashTable *zend_get_properties_no_lazy_init(zend_object *zobj); ZEND_API HashTable *zend_std_get_gc(zend_object *object, zval **table, int *n); ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp); ZEND_API zend_result zend_std_cast_object_tostring(zend_object *object, zval *writeobj, int type); @@ -272,14 +275,31 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj); static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object) { + if (UNEXPECTED(zend_lazy_object_must_init(object))) { + return zend_lazy_object_get_properties(object); + } if (!object->properties) { return rebuild_object_properties_internal(object); } return object->properties; } +/* Implements the fast path for array cast */ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj); +#define ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(object) ( \ + /* We can use zend_std_build_object_properties_array() for objects \ + * without properties ht and with standard handlers */ \ + Z_OBJ_P(object)->properties == NULL \ + && Z_OBJ_HT_P(object)->get_properties_for == NULL \ + && Z_OBJ_HT_P(object)->get_properties == zend_std_get_properties \ + /* For initialized proxies we need to forward to the real instance */ \ + && ( \ + !zend_object_is_lazy_proxy(Z_OBJ_P(object)) \ + || !zend_lazy_object_initialized(Z_OBJ_P(object)) \ + ) \ +) + /* Handler for objects that cannot be meaningfully compared. * Only objects with the same identity will be considered equal. */ ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2); @@ -310,6 +330,8 @@ ZEND_API zend_function *zend_get_property_hook_trampoline( const zend_property_info *prop_info, zend_property_hook_kind kind, zend_string *prop_name); +ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); + #define zend_release_properties(ht) do { \ if ((ht) && !(GC_FLAGS(ht) & GC_IMMUTABLE) && !GC_DELREF(ht)) { \ zend_array_destroy(ht); \ diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index af4d1f265897a..348b3f3416b91 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -25,12 +25,14 @@ #include "zend_interfaces.h" #include "zend_exceptions.h" #include "zend_weakrefs.h" +#include "zend_lazy_objects.h" static zend_always_inline void _zend_object_std_init(zend_object *object, zend_class_entry *ce) { GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT; object->ce = ce; + object->extra_flags = 0; object->handlers = ce->default_object_handlers; object->properties = NULL; zend_objects_store_put(object); @@ -46,14 +48,8 @@ ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class _zend_object_std_init(object, ce); } -ZEND_API void zend_object_std_dtor(zend_object *object) +void zend_object_dtor_dynamic_properties(zend_object *object) { - zval *p, *end; - - if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { - zend_weakrefs_notify(object); - } - if (object->properties) { if (EXPECTED(!(GC_FLAGS(object->properties) & IS_ARRAY_IMMUTABLE))) { if (EXPECTED(GC_DELREF(object->properties) == 0) @@ -62,20 +58,41 @@ ZEND_API void zend_object_std_dtor(zend_object *object) } } } +} + +void zend_object_dtor_property(zend_object *object, zval *p) +{ + if (Z_REFCOUNTED_P(p)) { + if (UNEXPECTED(Z_ISREF_P(p)) && + (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { + zend_property_info *prop_info = zend_get_property_info_for_slot(object, p); + if (ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); + } + } + i_zval_ptr_dtor(p); + } +} + +ZEND_API void zend_object_std_dtor(zend_object *object) +{ + zval *p, *end; + + if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + zend_weakrefs_notify(object); + } + + if (UNEXPECTED(zend_object_is_lazy(object))) { + zend_lazy_object_del_info(object); + } + + zend_object_dtor_dynamic_properties(object); + p = object->properties_table; if (EXPECTED(object->ce->default_properties_count)) { end = p + object->ce->default_properties_count; do { - if (Z_REFCOUNTED_P(p)) { - if (UNEXPECTED(Z_ISREF_P(p)) && - (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { - zend_property_info *prop_info = zend_get_property_info_for_slot(object, p); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); - } - } - i_zval_ptr_dtor(p); - } + zend_object_dtor_property(object, p); p++; } while (p != end); } @@ -99,6 +116,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) zend_function *destructor = object->ce->destructor; if (destructor) { + if (UNEXPECTED(zend_object_is_lazy(object))) { + return; + } + zend_object *old_exception; const zend_op *old_opline_before_exception; @@ -286,6 +307,10 @@ ZEND_API zend_object *zend_objects_clone_obj(zend_object *old_object) { zend_object *new_object; + if (UNEXPECTED(zend_object_is_lazy(old_object))) { + return zend_lazy_object_clone(old_object); + } + /* assume that create isn't overwritten, so when clone depends on the * overwritten one then it must itself be overwritten */ new_object = zend_objects_new(old_object->ce); diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 91d388154dd13..41e3bcd9594b1 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -30,6 +30,10 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, ZEND_API void zend_object_std_dtor(zend_object *object); ZEND_API void zend_objects_destroy_object(zend_object *object); ZEND_API zend_object *zend_objects_clone_obj(zend_object *object); + +void zend_object_dtor_dynamic_properties(zend_object *object); +void zend_object_dtor_property(zend_object *object, zval *p); + END_EXTERN_C() #endif /* ZEND_OBJECTS_H */ diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 5331244731cac..ae75e95a71c1d 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -812,9 +812,7 @@ ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */ case IS_OBJECT: if (Z_OBJCE_P(op) == zend_ce_closure) { convert_scalar_to_array(op); - } else if (Z_OBJ_P(op)->properties == NULL - && Z_OBJ_HT_P(op)->get_properties_for == NULL - && Z_OBJ_HT_P(op)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(op)) { /* Optimized version without rebuilding properties HashTable */ HashTable *ht = zend_std_build_object_properties_array(Z_OBJ_P(op)); OBJ_RELEASE(Z_OBJ_P(op)); diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 5290d7aae4fe3..5be8d7e4f5ced 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -306,7 +306,7 @@ char *alloca(); # define ZEND_FASTCALL __attribute__((fastcall)) #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700 # define ZEND_FASTCALL __fastcall -#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__) +#elif defined(_MSC_VER) && _MSC_VER >= 1800 # define ZEND_FASTCALL __vectorcall #else # define ZEND_FASTCALL diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index d3ae945f1d81e..9cfa15ecafa4d 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -18,6 +18,8 @@ #include "zend.h" #include "zend_API.h" +#include "zend_hash.h" +#include "zend_lazy_objects.h" #include "zend_property_hooks.h" typedef struct { @@ -25,12 +27,14 @@ typedef struct { bool by_ref; bool declared_props_done; zval declared_props; + bool dynamic_props_done; uint32_t dynamic_prop_it; zval current_key; zval current_data; } zend_hooked_object_iterator; static zend_result zho_it_valid(zend_object_iterator *iter); +static void zho_it_move_forward(zend_object_iterator *iter); // FIXME: This should probably be stored on zend_class_entry somewhere (e.g. through num_virtual_props). static uint32_t zho_num_backed_props(zend_object *zobj) @@ -47,6 +51,13 @@ static uint32_t zho_num_backed_props(zend_object *zobj) static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access, bool include_dynamic_props) { + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(!zobj)) { + return (zend_array*) &zend_empty_array; + } + } + zend_class_entry *ce = zobj->ce; zend_array *properties = zend_new_array(ce->default_properties_count); zend_hash_real_init_mixed(properties); @@ -87,13 +98,16 @@ ZEND_API zend_array *zend_hooked_object_build_properties(zend_object *zobj) static bool zho_dynamic_it_init(zend_hooked_object_iterator *hooked_iter) { - zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); - if (!zobj->properties) { - return false; - } if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { return true; } + + zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); + if (!zobj->properties || zho_num_backed_props(zobj) == zobj->properties->nNumUsed) { + hooked_iter->dynamic_props_done = true; + return false; + } + hooked_iter->dynamic_prop_it = zend_hash_iterator_add(zobj->properties, zho_num_backed_props(zobj)); return true; } @@ -102,26 +116,17 @@ static void zho_it_get_current_key(zend_object_iterator *iter, zval *key); static void zho_declared_it_fetch_current(zend_object_iterator *iter) { - ZEND_ASSERT(zho_it_valid(iter) == SUCCESS); - zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - zval_ptr_dtor(&hooked_iter->current_data); - if (EG(exception)) { - return; - } - ZVAL_UNDEF(&hooked_iter->current_data); - zval_ptr_dtor(&hooked_iter->current_key); - ZVAL_UNDEF(&hooked_iter->current_key); zend_object *zobj = Z_OBJ_P(&iter->data); zend_array *properties = Z_ARR(hooked_iter->declared_props); - zval_ptr_dtor_nogc(&hooked_iter->current_key); - zend_hash_get_current_key_zval(properties, &hooked_iter->current_key); - zval *property = zend_hash_get_current_data(properties); if (Z_TYPE_P(property) == IS_PTR) { zend_property_info *prop_info = Z_PTR_P(property); zend_function *get = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + if (!get && (prop_info->flags & ZEND_ACC_VIRTUAL)) { + return; + } if (hooked_iter->by_ref && (get == NULL || !(get->common.fn_flags & ZEND_ACC_RETURN_REFERENCE))) { @@ -129,12 +134,26 @@ static void zho_declared_it_fetch_current(zend_object_iterator *iter) ZSTR_VAL(zobj->ce->name), zend_get_unmangled_property_name(prop_info->name)); return; } - zend_read_property_ex(prop_info->ce, zobj, prop_info->name, /* silent */ true, &hooked_iter->current_data); + zval *value = zend_read_property_ex(prop_info->ce, zobj, prop_info->name, /* silent */ true, &hooked_iter->current_data); + if (value == &EG(uninitialized_zval)) { + return; + } else if (value != &hooked_iter->current_data) { + ZVAL_COPY(&hooked_iter->current_data, value); + } } else { ZVAL_DEINDIRECT(property); - if (hooked_iter->by_ref && Z_TYPE_P(property) != IS_REFERENCE) { - ZEND_ASSERT(Z_TYPE_P(property) != IS_UNDEF); + if (Z_TYPE_P(property) == IS_UNDEF) { + return; + } + if (!hooked_iter->by_ref) { + ZVAL_DEREF(property); + } else if (Z_TYPE_P(property) != IS_REFERENCE) { ZVAL_MAKE_REF(property); + + zend_property_info *prop_info = zend_get_property_info_for_slot(zobj, property); + if (ZEND_TYPE_IS_SET(prop_info->type)) { + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(property), prop_info); + } } ZVAL_COPY(&hooked_iter->current_data, property); } @@ -154,10 +173,8 @@ static void zho_dynamic_it_fetch_current(zend_object_iterator *iter) ZEND_ASSERT(Z_TYPE(bucket->val) != IS_UNDEF); ZVAL_MAKE_REF(&bucket->val); } - zval_ptr_dtor(&hooked_iter->current_data); ZVAL_COPY(&hooked_iter->current_data, &bucket->val); - zval_ptr_dtor_nogc(&hooked_iter->current_key); if (bucket->key) { ZVAL_STR_COPY(&hooked_iter->current_key, bucket->key); } else { @@ -168,13 +185,22 @@ static void zho_dynamic_it_fetch_current(zend_object_iterator *iter) static void zho_it_fetch_current(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + if (Z_TYPE(hooked_iter->current_data) != IS_UNDEF) { + return; + } - if (!hooked_iter->declared_props_done) { - zho_declared_it_fetch_current(iter); - } else if (zho_dynamic_it_init(hooked_iter)) { - zho_dynamic_it_fetch_current(iter); - } else { - ZEND_UNREACHABLE(); + while (true) { + if (!hooked_iter->declared_props_done) { + zho_declared_it_fetch_current(iter); + } else if (!hooked_iter->dynamic_props_done && zho_dynamic_it_init(hooked_iter)) { + zho_dynamic_it_fetch_current(iter); + } else { + break; + } + if (Z_TYPE(hooked_iter->current_data) != IS_UNDEF || EG(exception)) { + break; + } + zho_it_move_forward(iter); } } @@ -185,7 +211,6 @@ static void zho_it_dtor(zend_object_iterator *iter) zval_ptr_dtor(&hooked_iter->declared_props); zval_ptr_dtor_nogc(&hooked_iter->current_key); zval_ptr_dtor(&hooked_iter->current_data); - zval_ptr_dtor(&hooked_iter->current_key); if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { zend_hash_iterator_del(hooked_iter->dynamic_prop_it); } @@ -194,78 +219,66 @@ static void zho_it_dtor(zend_object_iterator *iter) static zend_result zho_it_valid(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - if (!hooked_iter->declared_props_done) { - if (zend_hash_has_more_elements(Z_ARR(hooked_iter->declared_props)) == SUCCESS) { - return SUCCESS; - } - } - - if (zho_dynamic_it_init(hooked_iter)) { - zend_object *zobj = Z_OBJ_P(&hooked_iter->it.data); - HashPosition pos = zend_hash_iterator_pos(hooked_iter->dynamic_prop_it, zobj->properties); - return pos < zobj->properties->nNumUsed ? SUCCESS : FAILURE; - } - - return FAILURE; + zho_it_fetch_current(iter); + return Z_TYPE(hooked_iter->current_data) != IS_UNDEF ? SUCCESS : FAILURE; } static zval *zho_it_get_current_data(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + zho_it_fetch_current(iter); return &hooked_iter->current_data; } static void zho_it_get_current_key(zend_object_iterator *iter, zval *key) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + zho_it_fetch_current(iter); ZVAL_COPY(key, &hooked_iter->current_key); } static void zho_it_move_forward(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; - zend_array *properties = Z_ARR(hooked_iter->declared_props); + + zval_ptr_dtor(&hooked_iter->current_data); + ZVAL_UNDEF(&hooked_iter->current_data); + zval_ptr_dtor_nogc(&hooked_iter->current_key); + ZVAL_UNDEF(&hooked_iter->current_key); + if (!hooked_iter->declared_props_done) { + zend_array *properties = Z_ARR(hooked_iter->declared_props); zend_hash_move_forward(properties); - if (zend_hash_has_more_elements(properties) == SUCCESS) { - zho_declared_it_fetch_current(iter); - } else { + if (zend_hash_has_more_elements(properties) != SUCCESS) { hooked_iter->declared_props_done = true; - if (zho_dynamic_it_init(hooked_iter)) { - zho_dynamic_it_fetch_current(iter); - } } - } else if (zho_dynamic_it_init(hooked_iter)) { + } else if (!hooked_iter->dynamic_props_done && zho_dynamic_it_init(hooked_iter)) { zend_array *properties = Z_OBJ(iter->data)->properties; HashPosition pos = zend_hash_iterator_pos(hooked_iter->dynamic_prop_it, properties); - Bucket *bucket = properties->arData + pos; - while (true) { - pos++; - bucket++; - if (pos >= properties->nNumUsed) { - break; - } - if (Z_TYPE_INFO_P(&bucket->val) != IS_UNDEF) { - zho_dynamic_it_fetch_current(iter); - break; - } - } + pos++; EG(ht_iterators)[hooked_iter->dynamic_prop_it].pos = pos; + if (pos >= properties->nNumUsed) { + hooked_iter->dynamic_props_done = true; + } } } static void zho_it_rewind(zend_object_iterator *iter) { zend_hooked_object_iterator *hooked_iter = (zend_hooked_object_iterator*)iter; + + zval_ptr_dtor(&hooked_iter->current_data); + ZVAL_UNDEF(&hooked_iter->current_data); + zval_ptr_dtor_nogc(&hooked_iter->current_key); + ZVAL_UNDEF(&hooked_iter->current_key); + hooked_iter->declared_props_done = false; zend_array *properties = Z_ARR(hooked_iter->declared_props); zend_hash_internal_pointer_reset(properties); + hooked_iter->dynamic_props_done = false; if (hooked_iter->dynamic_prop_it != (uint32_t) -1) { EG(ht_iterators)[hooked_iter->dynamic_prop_it].pos = zho_num_backed_props(Z_OBJ(iter->data)); } - if (zho_it_valid(iter) == SUCCESS) { - zho_it_fetch_current(iter); - } } static HashTable *zho_it_get_gc(zend_object_iterator *iter, zval **table, int *n) @@ -301,6 +314,7 @@ ZEND_API zend_object_iterator *zend_hooked_object_get_iterator(zend_class_entry iterator->declared_props_done = false; zend_array *properties = zho_build_properties_ex(Z_OBJ_P(object), true, false); ZVAL_ARR(&iterator->declared_props, properties); + iterator->dynamic_props_done = false; iterator->dynamic_prop_it = (uint32_t) -1; ZVAL_UNDEF(&iterator->current_key); ZVAL_UNDEF(&iterator->current_data); diff --git a/Zend/zend_string.h b/Zend/zend_string.h index b62875a6ec1ce..ad6c5e1ee38bf 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -572,6 +572,7 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_ARGS, "args") \ _(ZEND_STR_UNKNOWN, "unknown") \ _(ZEND_STR_UNKNOWN_CAPITALIZED, "Unknown") \ + _(ZEND_STR_EXIT, "exit") \ _(ZEND_STR_EVAL, "eval") \ _(ZEND_STR_INCLUDE, "include") \ _(ZEND_STR_REQUIRE, "require") \ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index d33f8a33bcbe6..8f012868ddab4 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -556,6 +556,7 @@ typedef struct _HashTableIterator { struct _zend_object { zend_refcounted_h gc; uint32_t handle; // TODO: may be removed ??? + uint32_t extra_flags; /* OBJ_EXTRA_FLAGS() */ zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; @@ -829,6 +830,13 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define OBJ_FLAGS(obj) GC_FLAGS(obj) +/* object extra flags (zend_object.flags) */ + +#define IS_OBJ_LAZY_UNINITIALIZED (1U<<31) /* Virtual proxy or uninitialized Ghost */ +#define IS_OBJ_LAZY_PROXY (1U<<30) /* Virtual proxy (may be initialized) */ + +#define OBJ_EXTRA_FLAGS(obj) ((obj)->extra_flags) + /* Fast class cache */ #define ZSTR_HAS_CE_CACHE(s) (GC_FLAGS(s) & IS_STR_CLASS_NAME_MAP_PTR) #define ZSTR_GET_CE_CACHE(s) ZSTR_GET_CE_CACHE_EX(s, 1) @@ -1556,6 +1564,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { * macros for this purpose, so this workaround is easier to remove in the future. */ #define IS_PROP_UNINIT (1<<0) #define IS_PROP_REINITABLE (1<<1) /* It has impact only on readonly properties */ +#define IS_PROP_LAZY (1<<2) #define Z_PROP_FLAG_P(z) Z_EXTRA_P(z) #define ZVAL_COPY_VALUE_PROP(z, v) \ do { *(z) = *(v); } while (0) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 916f71412cdf7..366e13ce9b6ba 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -230,22 +230,20 @@ CWD_API void virtual_cwd_shutdown(void) /* {{{ */ } /* }}} */ -CWD_API int virtual_cwd_activate(void) /* {{{ */ +CWD_API void virtual_cwd_activate(void) /* {{{ */ { if (CWDG(cwd).cwd == NULL) { CWD_STATE_COPY(&CWDG(cwd), &main_cwd_state); } - return 0; } /* }}} */ -CWD_API int virtual_cwd_deactivate(void) /* {{{ */ +CWD_API void virtual_cwd_deactivate(void) /* {{{ */ { if (CWDG(cwd).cwd != NULL) { CWD_STATE_FREE(&CWDG(cwd)); CWDG(cwd).cwd = NULL; } - return 0; } /* }}} */ diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index 1ccdf79b7870c..0fc2799118692 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -168,8 +168,8 @@ typedef int (*verify_path_func)(const cwd_state *); CWD_API void virtual_cwd_startup(void); CWD_API void virtual_cwd_shutdown(void); -CWD_API int virtual_cwd_activate(void); -CWD_API int virtual_cwd_deactivate(void); +CWD_API void virtual_cwd_activate(void); +CWD_API void virtual_cwd_deactivate(void); CWD_API char *virtual_getcwd_ex(size_t *length); CWD_API char *virtual_getcwd(char *buf, size_t size); CWD_API zend_result virtual_chdir(const char *path); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c99cc9c1a2f65..b46952a81718b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2481,6 +2481,16 @@ ZEND_VM_C_LABEL(fast_assign_obj): } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + ZEND_VM_C_GOTO(free_and_exit_assign_obj); + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -2519,7 +2529,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -6429,9 +6439,7 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -7610,38 +7618,6 @@ ZEND_VM_C_LABEL(array_key_exists_array): ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ -ZEND_VM_COLD_HANDLER(79, ZEND_EXIT, ANY, ANY) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (OP1_TYPE != IS_UNUSED) { - zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_zval(ptr, 0); - } - } while (0); - FREE_OP1(); - } - - if (!EG(exception)) { - zend_throw_unwind_exit(); - } - HANDLE_EXCEPTION(); -} - ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 75499f028e2cd..6738674667e74 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3013,37 +3013,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (opline->op1_type != IS_UNUSED) { - zval *ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_zval(ptr, 0); - } - } while (0); - FREE_OP(opline->op1_type, opline->op1.var); - } - - if (!EG(exception)) { - zend_throw_unwind_exit(); - } - HANDLE_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -5203,9 +5172,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -7930,7 +7897,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10307,7 +10273,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12788,7 +12753,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -16950,7 +16914,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -18417,7 +18380,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -19824,7 +19786,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -20082,9 +20043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -22735,9 +22694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -24018,6 +23975,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24056,7 +24023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24162,6 +24129,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24200,7 +24177,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24306,6 +24283,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24344,7 +24331,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -24450,6 +24437,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -24488,7 +24485,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -26980,6 +26977,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27018,7 +27025,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27124,6 +27131,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27162,7 +27179,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27268,6 +27285,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27306,7 +27333,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -27412,6 +27439,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -27450,7 +27487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31304,6 +31341,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31342,7 +31389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31448,6 +31495,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31486,7 +31543,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31592,6 +31649,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31630,7 +31697,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -31736,6 +31803,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -31774,7 +31851,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34022,6 +34099,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34060,7 +34147,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34166,6 +34253,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34204,7 +34301,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34310,6 +34407,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34348,7 +34455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -34454,6 +34561,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -34492,7 +34609,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36161,6 +36278,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36199,7 +36326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36305,6 +36432,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36343,7 +36480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36449,6 +36586,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36487,7 +36634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -36593,6 +36740,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -36631,7 +36788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -38778,6 +38935,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -38816,7 +38983,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -38922,6 +39089,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -38960,7 +39137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39066,6 +39243,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -39104,7 +39291,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39210,6 +39397,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -39248,7 +39445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -40780,9 +40977,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO } else { ZVAL_EMPTY_ARRAY(result); } - } else if (Z_OBJ_P(expr)->properties == NULL - && Z_OBJ_HT_P(expr)->get_properties_for == NULL - && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + } else if (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE(expr)) { /* Optimized version without rebuilding properties HashTable */ ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { @@ -43134,6 +43329,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43172,7 +43377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43278,6 +43483,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43316,7 +43531,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43422,6 +43637,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43460,7 +43685,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -43566,6 +43791,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -43604,7 +43839,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -45235,7 +45470,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -47058,6 +47292,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47096,7 +47340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47202,6 +47446,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47240,7 +47494,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47346,6 +47600,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47384,7 +47648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -47490,6 +47754,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -47528,7 +47802,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -48963,7 +49237,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -52529,6 +52802,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52567,7 +52850,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52673,6 +52956,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52711,7 +53004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52817,6 +53110,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52855,7 +53158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -52961,6 +53264,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { @@ -52999,7 +53312,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ Z_TRY_ADDREF_P(value); } } - zend_hash_add_new(zend_std_get_properties_ex(zobj), name, value); + zend_hash_add_new(zobj->properties, name, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -54527,7 +54840,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -56322,7 +56634,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FE_RESET_R_SPEC_CV_LABEL, (void*)&&ZEND_FE_FETCH_R_SPEC_VAR_LABEL, - (void*)&&ZEND_EXIT_SPEC_LABEL, (void*)&&ZEND_FETCH_R_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, @@ -58572,11 +58883,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) HYBRID_BREAK(); - HYBRID_CASE(ZEND_EXIT_SPEC): - VM_TRACE(ZEND_EXIT_SPEC) - ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_EXIT_SPEC) - HYBRID_BREAK(); HYBRID_CASE(ZEND_BEGIN_SILENCE_SPEC): VM_TRACE(ZEND_BEGIN_SILENCE_SPEC) ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -65515,7 +65821,6 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_FE_RESET_R_SPEC_CV_HANDLER, ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_EXIT_SPEC_HANDLER, ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, @@ -67460,7 +67765,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3487, + 3486, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -67494,100 +67799,101 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 1590, - 1591 | SPEC_RULE_OP1, - 1596 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1621 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1646 | SPEC_RULE_OP1, - 1651 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1676 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1701 | SPEC_RULE_OP1, - 1706 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1731 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1756 | SPEC_RULE_OP1, - 1761 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1786 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1811 | SPEC_RULE_OP1, - 1816 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1841 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1866 | SPEC_RULE_OP1, - 1871 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1896 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1921 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1946, - 1947 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 3486, + 1590 | SPEC_RULE_OP1, + 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1645 | SPEC_RULE_OP1, + 1650 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1675 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1700 | SPEC_RULE_OP1, + 1705 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1730 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1755 | SPEC_RULE_OP1, + 1760 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1785 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1810 | SPEC_RULE_OP1, + 1815 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1840 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1865 | SPEC_RULE_OP1, + 1870 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1895 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1920 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1945, + 1946 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1956, 1957, 1958, 1959, 1960, - 1961, - 1962 | SPEC_RULE_OP2, - 1967, - 1968 | SPEC_RULE_OP1, - 1973 | SPEC_RULE_OP2, - 1978 | SPEC_RULE_OP1, - 1983 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1993 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2018 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2043 | SPEC_RULE_OP1, - 2048 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2073 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 2123 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2148 | SPEC_RULE_OP2, - 2153, - 2154 | SPEC_RULE_OP1, - 2159 | SPEC_RULE_OP1, - 2164, - 2165 | SPEC_RULE_OP1, - 2170 | SPEC_RULE_OP1, - 2175 | SPEC_RULE_OP1, + 1961 | SPEC_RULE_OP2, + 1966, + 1967 | SPEC_RULE_OP1, + 1972 | SPEC_RULE_OP2, + 1977 | SPEC_RULE_OP1, + 1982 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1992 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2017 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2042 | SPEC_RULE_OP1, + 2047 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 2122 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2147 | SPEC_RULE_OP2, + 2152, + 2153 | SPEC_RULE_OP1, + 2158 | SPEC_RULE_OP1, + 2163, + 2164 | SPEC_RULE_OP1, + 2169 | SPEC_RULE_OP1, + 2174 | SPEC_RULE_OP1, + 2179, 2180, - 2181, - 2182 | SPEC_RULE_OP2, - 2187 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2191 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2195 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2249 | SPEC_RULE_OP1, - 2254, - 2255 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2280, - 2281 | SPEC_RULE_OP1, + 2181 | SPEC_RULE_OP2, + 2186 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2190 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2248 | SPEC_RULE_OP1, + 2253, + 2254 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2279, + 2280 | SPEC_RULE_OP1, + 2285, 2286, 2287, 2288, 2289, 2290, 2291, - 2292, - 2293 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2292 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2317, 2318, 2319, - 2320, - 2321 | SPEC_RULE_OP1, - 2326, - 2327 | SPEC_RULE_ISSET, - 2329 | SPEC_RULE_OP2, - 2334, - 2335 | SPEC_RULE_OP1, - 2340 | SPEC_RULE_OBSERVER, - 2342, - 2343 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2368 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2320 | SPEC_RULE_OP1, + 2325, + 2326 | SPEC_RULE_ISSET, + 2328 | SPEC_RULE_OP2, + 2333, + 2334 | SPEC_RULE_OP1, + 2339 | SPEC_RULE_OBSERVER, + 2341, + 2342 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2367 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2377, 2378, 2379, 2380, - 2381, - 2382 | SPEC_RULE_OP1, + 2381 | SPEC_RULE_OP1, + 2386, 2387, - 2388, - 2389 | SPEC_RULE_OP1, - 2394 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2419, - 2420 | SPEC_RULE_OP1, + 2388 | SPEC_RULE_OP1, + 2393 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2418, + 2419 | SPEC_RULE_OP1, + 2424, 2425, 2426, 2427, @@ -67595,82 +67901,81 @@ void zend_vm_init(void) 2429, 2430, 2431, - 2432, - 2433 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2432 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2457, 2458, 2459, - 2460, - 2461 | SPEC_RULE_OP2, - 2466, - 2467 | SPEC_RULE_OP1, - 2472 | SPEC_RULE_OP1, - 2477 | SPEC_RULE_OP1, - 2482 | SPEC_RULE_OP1, - 2487 | SPEC_RULE_OP1, - 2492, - 2493 | SPEC_RULE_OP1, - 2498 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2523 | SPEC_RULE_OP1, - 2528 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2553 | SPEC_RULE_OP1, - 2558 | SPEC_RULE_OP1, + 2460 | SPEC_RULE_OP2, + 2465, + 2466 | SPEC_RULE_OP1, + 2471 | SPEC_RULE_OP1, + 2476 | SPEC_RULE_OP1, + 2481 | SPEC_RULE_OP1, + 2486 | SPEC_RULE_OP1, + 2491, + 2492 | SPEC_RULE_OP1, + 2497 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2522 | SPEC_RULE_OP1, + 2527 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2552 | SPEC_RULE_OP1, + 2557 | SPEC_RULE_OP1, + 2562, 2563, 2564, 2565, 2566, - 2567, - 2568 | SPEC_RULE_OBSERVER, - 2570 | SPEC_RULE_OBSERVER, - 2572 | SPEC_RULE_OBSERVER, - 2574 | SPEC_RULE_OBSERVER, + 2567 | SPEC_RULE_OBSERVER, + 2569 | SPEC_RULE_OBSERVER, + 2571 | SPEC_RULE_OBSERVER, + 2573 | SPEC_RULE_OBSERVER, + 2575, 2576, - 2577, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -67843,7 +68148,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2586 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2585 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67851,7 +68156,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2611 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2610 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67859,7 +68164,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2636 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2635 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -67870,17 +68175,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2661 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2660 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2686 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2685 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2711 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2710 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -67891,17 +68196,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2736 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2735 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2761 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2760 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2786 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2785 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -67912,14 +68217,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3111 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3110 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -67930,14 +68235,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3116 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -67948,12 +68253,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -67964,12 +68269,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -67977,12 +68282,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3121 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3120 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3196 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3195 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -67990,79 +68295,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3271 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3270 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3346 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3345 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3433 | SPEC_RULE_OP1; + spec = 3432 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3438 | SPEC_RULE_OP1; + spec = 3437 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3443 | SPEC_RULE_OP1; + spec = 3442 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3421 | SPEC_RULE_RETVAL; + spec = 3420 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3423 | SPEC_RULE_RETVAL; + spec = 3422 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3425 | SPEC_RULE_RETVAL; + spec = 3424 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3427 | SPEC_RULE_RETVAL; + spec = 3426 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3429; + spec = 3428; } else if (op1_info == MAY_BE_LONG) { - spec = 3430; + spec = 3429; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3431; + spec = 3430; } else if (op1_info == MAY_BE_LONG) { - spec = 3432; + spec = 3431; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2585; + spec = 2584; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2578; + spec = 2577; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2579; + spec = 2578; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3483; + spec = 3482; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3478 | SPEC_RULE_OP1; + spec = 3477 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3485 | SPEC_RULE_RETVAL; + spec = 3484 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -68070,22 +68375,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3448 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3447 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3484; + spec = 3483; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3473 | SPEC_RULE_OP1; + spec = 3472 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2580 | SPEC_RULE_OP1; + spec = 2579 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 99abc0ffb12de..7f3a3cb5de260 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -751,1124 +751,1123 @@ _(1586, ZEND_FE_RESET_R_SPEC_VAR) \ _(1588, ZEND_FE_RESET_R_SPEC_CV) \ _(1589, ZEND_FE_FETCH_R_SPEC_VAR) \ - _(1590, ZEND_EXIT_SPEC) \ - _(1591, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ + _(1590, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ + _(1591, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ _(1592, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1593, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1595, ZEND_FETCH_R_SPEC_CV_UNUSED) \ - _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ + _(1594, ZEND_FETCH_R_SPEC_CV_UNUSED) \ + _(1595, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ + _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ _(1597, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1598, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1600, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ - _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1599, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ + _(1600, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1602, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1603, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1604, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ + _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1608, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1610, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1616, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(1609, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ + _(1615, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ _(1617, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1618, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1620, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ - _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ + _(1619, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ + _(1620, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ + _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ _(1622, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1623, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1625, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ - _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1624, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ + _(1625, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1627, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1628, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1629, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ + _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1632, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1633, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1635, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(1634, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ + _(1635, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ _(1637, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1638, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1640, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ - _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ + _(1639, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ + _(1640, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ + _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ _(1642, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1643, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1645, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ - _(1646, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ + _(1644, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ + _(1645, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ + _(1646, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ _(1647, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1648, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1650, ZEND_FETCH_W_SPEC_CV_UNUSED) \ - _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ + _(1649, ZEND_FETCH_W_SPEC_CV_UNUSED) \ + _(1660, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ + _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ _(1662, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ - _(1665, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ - _(1671, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ + _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ + _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ + _(1670, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ + _(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ _(1672, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1673, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1674, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ - _(1675, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ - _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ + _(1673, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ + _(1674, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ + _(1685, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ + _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ _(1687, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1688, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1690, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ - _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ + _(1689, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ + _(1690, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ + _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ _(1692, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1693, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1695, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ - _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ + _(1694, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ + _(1695, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ + _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ _(1697, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1698, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1700, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ - _(1701, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ + _(1699, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ + _(1700, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ + _(1701, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ _(1702, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1703, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1705, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ - _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ + _(1704, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ + _(1715, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ + _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ _(1717, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ - _(1720, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ - _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ + _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ + _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ + _(1725, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ + _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ _(1727, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ - _(1730, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ - _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ + _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ + _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ + _(1740, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ + _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ _(1742, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1743, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1745, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ - _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ + _(1744, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ + _(1745, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ + _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ _(1747, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1748, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1750, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ - _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ + _(1749, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ + _(1750, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ + _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ _(1752, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1753, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1755, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ - _(1756, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ + _(1754, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ + _(1755, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ + _(1756, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ _(1757, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1758, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1760, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ - _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ + _(1759, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ + _(1760, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ + _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ _(1762, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1763, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1765, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ - _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1764, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ + _(1765, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1767, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1768, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1769, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ + _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1773, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1775, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(1774, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ + _(1780, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ _(1782, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1783, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1785, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ - _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ + _(1784, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ + _(1785, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ + _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ _(1787, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1788, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1790, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ - _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1789, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ + _(1790, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1792, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1793, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1794, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ + _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1797, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1798, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1800, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(1799, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ + _(1800, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ _(1802, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1803, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1805, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ - _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ + _(1804, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ + _(1805, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ + _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ _(1807, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1808, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1810, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ - _(1811, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1809, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ + _(1810, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ _(1812, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1813, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1815, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ + _(1814, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1815, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ + _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ _(1817, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ - _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ + _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ + _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ + _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ - _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ - _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ + _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ + _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ + _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ + _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(1830, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ - _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ + _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ + _(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ + _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ _(1837, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1840, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ - _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ + _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ + _(1840, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ + _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ _(1842, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1843, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ - _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ + _(1844, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ + _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ + _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1848, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ - _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ + _(1849, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ + _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ + _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1853, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ - _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1854, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ + _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1858, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ - _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ + _(1859, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ + _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ + _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1863, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1865, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ - _(1866, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ + _(1864, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ + _(1865, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ + _(1866, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ _(1867, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1868, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1870, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ - _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ + _(1869, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ + _(1880, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ + _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ _(1882, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1883, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1885, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ - _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ + _(1884, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ + _(1890, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ + _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ _(1892, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1893, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1895, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ - _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ + _(1894, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ + _(1905, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ + _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ _(1907, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1908, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ - _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ + _(1909, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ + _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ + _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1913, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ - _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ + _(1914, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ + _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ + _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1918, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1920, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ - _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ + _(1919, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ + _(1920, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ + _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ _(1922, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1923, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1925, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ - _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1924, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ + _(1925, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1927, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1928, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1929, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1933, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1935, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1934, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1942, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1943, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1945, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1946, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ + _(1944, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1945, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ + _(1946, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ _(1947, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1948, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ - _(1954, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ - _(1957, ZEND_EXT_STMT_SPEC) \ - _(1958, ZEND_EXT_FCALL_BEGIN_SPEC) \ - _(1959, ZEND_EXT_FCALL_END_SPEC) \ - _(1960, ZEND_EXT_NOP_SPEC) \ - _(1961, ZEND_TICKS_SPEC) \ - _(1962, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ - _(1965, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ - _(1967, ZEND_CATCH_SPEC_CONST) \ - _(1968, ZEND_THROW_SPEC_CONST) \ + _(1952, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ + _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ + _(1956, ZEND_EXT_STMT_SPEC) \ + _(1957, ZEND_EXT_FCALL_BEGIN_SPEC) \ + _(1958, ZEND_EXT_FCALL_END_SPEC) \ + _(1959, ZEND_EXT_NOP_SPEC) \ + _(1960, ZEND_TICKS_SPEC) \ + _(1961, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ + _(1964, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ + _(1966, ZEND_CATCH_SPEC_CONST) \ + _(1967, ZEND_THROW_SPEC_CONST) \ + _(1968, ZEND_THROW_SPEC_TMPVAR) \ _(1969, ZEND_THROW_SPEC_TMPVAR) \ - _(1970, ZEND_THROW_SPEC_TMPVAR) \ - _(1972, ZEND_THROW_SPEC_CV) \ - _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(1971, ZEND_THROW_SPEC_CV) \ + _(1972, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ _(1974, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ - _(1977, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ - _(1978, ZEND_CLONE_SPEC_CONST) \ + _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ + _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ + _(1977, ZEND_CLONE_SPEC_CONST) \ + _(1978, ZEND_CLONE_SPEC_TMPVAR) \ _(1979, ZEND_CLONE_SPEC_TMPVAR) \ - _(1980, ZEND_CLONE_SPEC_TMPVAR) \ - _(1981, ZEND_CLONE_SPEC_UNUSED) \ - _(1982, ZEND_CLONE_SPEC_CV) \ - _(1983, ZEND_RETURN_BY_REF_SPEC_CONST) \ - _(1984, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1985, ZEND_RETURN_BY_REF_SPEC_TMP) \ - _(1986, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1987, ZEND_RETURN_BY_REF_SPEC_VAR) \ - _(1988, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1991, ZEND_RETURN_BY_REF_SPEC_CV) \ - _(1992, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ + _(1980, ZEND_CLONE_SPEC_UNUSED) \ + _(1981, ZEND_CLONE_SPEC_CV) \ + _(1982, ZEND_RETURN_BY_REF_SPEC_CONST) \ + _(1983, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1984, ZEND_RETURN_BY_REF_SPEC_TMP) \ + _(1985, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1986, ZEND_RETURN_BY_REF_SPEC_VAR) \ + _(1987, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1990, ZEND_RETURN_BY_REF_SPEC_CV) \ + _(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1992, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ + _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ _(1994, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(1995, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(1997, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ - _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(1996, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ + _(1997, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(1999, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2000, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(2001, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ + _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(2004, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2005, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2007, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2006, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ + _(2007, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ _(2009, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2010, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2012, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ + _(2011, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2012, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ + _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ _(2014, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2015, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2017, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ - _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ + _(2016, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ + _(2017, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ + _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ _(2019, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ - _(2022, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ - _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ + _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ + _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ + _(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ + _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ _(2029, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ - _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ - _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ + _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ + _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ - _(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ + _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ + _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2042, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ + _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ _(2044, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2045, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2047, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ - _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ + _(2046, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ + _(2047, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ + _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ _(2049, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2050, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ - _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2051, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ + _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ + _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2059, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2060, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2062, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(2061, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ + _(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ _(2069, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2070, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2072, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ + _(2071, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ + _(2072, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ _(2073, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2074, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ - _(2080, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ + _(2078, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ + _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ + _(2082, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ _(2083, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2084, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ - _(2090, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ - _(2133, ZEND_SEND_VAR_SPEC_VAR_CONST) \ - _(2136, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ - _(2143, ZEND_SEND_VAR_SPEC_CV_CONST) \ - _(2146, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ - _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ + _(2088, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ + _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ + _(2132, ZEND_SEND_VAR_SPEC_VAR_CONST) \ + _(2135, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ + _(2142, ZEND_SEND_VAR_SPEC_CV_CONST) \ + _(2145, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ + _(2147, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ + _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ _(2149, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2150, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2152, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ - _(2153, ZEND_SEND_ARRAY_SPEC) \ - _(2154, ZEND_SEND_USER_SPEC_CONST) \ - _(2155, ZEND_SEND_USER_SPEC_TMP) \ - _(2156, ZEND_SEND_USER_SPEC_VAR) \ - _(2158, ZEND_SEND_USER_SPEC_CV) \ - _(2159, ZEND_STRLEN_SPEC_CONST) \ + _(2151, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ + _(2152, ZEND_SEND_ARRAY_SPEC) \ + _(2153, ZEND_SEND_USER_SPEC_CONST) \ + _(2154, ZEND_SEND_USER_SPEC_TMP) \ + _(2155, ZEND_SEND_USER_SPEC_VAR) \ + _(2157, ZEND_SEND_USER_SPEC_CV) \ + _(2158, ZEND_STRLEN_SPEC_CONST) \ + _(2159, ZEND_STRLEN_SPEC_TMPVAR) \ _(2160, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2161, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2163, ZEND_STRLEN_SPEC_CV) \ - _(2164, ZEND_DEFINED_SPEC_CONST) \ - _(2165, ZEND_TYPE_CHECK_SPEC_CONST) \ + _(2162, ZEND_STRLEN_SPEC_CV) \ + _(2163, ZEND_DEFINED_SPEC_CONST) \ + _(2164, ZEND_TYPE_CHECK_SPEC_CONST) \ + _(2165, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ _(2166, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2167, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2169, ZEND_TYPE_CHECK_SPEC_CV) \ - _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ - _(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ - _(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ - _(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ - _(2174, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ - _(2175, ZEND_FE_RESET_RW_SPEC_CONST) \ - _(2176, ZEND_FE_RESET_RW_SPEC_TMP) \ - _(2177, ZEND_FE_RESET_RW_SPEC_VAR) \ - _(2179, ZEND_FE_RESET_RW_SPEC_CV) \ - _(2180, ZEND_FE_FETCH_RW_SPEC_VAR) \ - _(2181, ZEND_FE_FREE_SPEC_TMPVAR) \ - _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ + _(2168, ZEND_TYPE_CHECK_SPEC_CV) \ + _(2169, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ + _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ + _(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ + _(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ + _(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ + _(2174, ZEND_FE_RESET_RW_SPEC_CONST) \ + _(2175, ZEND_FE_RESET_RW_SPEC_TMP) \ + _(2176, ZEND_FE_RESET_RW_SPEC_VAR) \ + _(2178, ZEND_FE_RESET_RW_SPEC_CV) \ + _(2179, ZEND_FE_FETCH_RW_SPEC_VAR) \ + _(2180, ZEND_FE_FREE_SPEC_TMPVAR) \ + _(2181, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ + _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ _(2183, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2184, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2186, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ - _(2187, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ - _(2188, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ + _(2185, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ + _(2186, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ + _(2187, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ + _(2188, ZEND_DO_ICALL_SPEC_OBSERVER) \ _(2189, ZEND_DO_ICALL_SPEC_OBSERVER) \ - _(2190, ZEND_DO_ICALL_SPEC_OBSERVER) \ - _(2191, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ - _(2192, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2190, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ + _(2191, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2192, ZEND_DO_UCALL_SPEC_OBSERVER) \ _(2193, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2194, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ - _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2194, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ + _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ _(2197, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2198, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ _(2210, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2211, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2213, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ - _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ + _(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ _(2215, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2216, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2218, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ - _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ + _(2218, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ _(2220, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2221, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2223, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ - _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ + _(2233, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ _(2235, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2236, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2238, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ - _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ + _(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ _(2240, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2241, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2243, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ - _(2244, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ + _(2243, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ _(2245, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2246, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2248, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ - _(2249, ZEND_ECHO_SPEC_CONST) \ + _(2247, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ + _(2248, ZEND_ECHO_SPEC_CONST) \ + _(2249, ZEND_ECHO_SPEC_TMPVAR) \ _(2250, ZEND_ECHO_SPEC_TMPVAR) \ - _(2251, ZEND_ECHO_SPEC_TMPVAR) \ - _(2253, ZEND_ECHO_SPEC_CV) \ - _(2260, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2263, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2265, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2268, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2275, ZEND_INSTANCEOF_SPEC_CV_CONST) \ - _(2277, ZEND_INSTANCEOF_SPEC_CV_VAR) \ - _(2278, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ - _(2280, ZEND_GENERATOR_CREATE_SPEC) \ - _(2283, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ - _(2285, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ - _(2286, ZEND_DECLARE_FUNCTION_SPEC) \ - _(2287, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ - _(2288, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ - _(2289, ZEND_DECLARE_CLASS_SPEC_CONST) \ - _(2290, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ - _(2291, ZEND_DECLARE_ANON_CLASS_SPEC) \ - _(2292, ZEND_ADD_ARRAY_UNPACK_SPEC) \ - _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2252, ZEND_ECHO_SPEC_CV) \ + _(2259, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ + _(2264, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ + _(2274, ZEND_INSTANCEOF_SPEC_CV_CONST) \ + _(2276, ZEND_INSTANCEOF_SPEC_CV_VAR) \ + _(2277, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ + _(2279, ZEND_GENERATOR_CREATE_SPEC) \ + _(2282, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ + _(2284, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ + _(2285, ZEND_DECLARE_FUNCTION_SPEC) \ + _(2286, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ + _(2287, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ + _(2288, ZEND_DECLARE_CLASS_SPEC_CONST) \ + _(2289, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ + _(2290, ZEND_DECLARE_ANON_CLASS_SPEC) \ + _(2291, ZEND_ADD_ARRAY_UNPACK_SPEC) \ + _(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ _(2294, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2295, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ - _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2299, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ + _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2304, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2305, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ + _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ _(2309, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ - _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ + _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ _(2314, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2317, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ - _(2318, ZEND_HANDLE_EXCEPTION_SPEC) \ - _(2319, ZEND_USER_OPCODE_SPEC) \ - _(2320, ZEND_ASSERT_CHECK_SPEC) \ - _(2321, ZEND_JMP_SET_SPEC_CONST) \ - _(2322, ZEND_JMP_SET_SPEC_TMP) \ - _(2323, ZEND_JMP_SET_SPEC_VAR) \ - _(2325, ZEND_JMP_SET_SPEC_CV) \ - _(2326, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ - _(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ - _(2328, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ - _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ + _(2317, ZEND_HANDLE_EXCEPTION_SPEC) \ + _(2318, ZEND_USER_OPCODE_SPEC) \ + _(2319, ZEND_ASSERT_CHECK_SPEC) \ + _(2320, ZEND_JMP_SET_SPEC_CONST) \ + _(2321, ZEND_JMP_SET_SPEC_TMP) \ + _(2322, ZEND_JMP_SET_SPEC_VAR) \ + _(2324, ZEND_JMP_SET_SPEC_CV) \ + _(2325, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ + _(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ + _(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ + _(2328, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ _(2330, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2331, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2333, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ - _(2334, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ + _(2333, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ _(2336, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2337, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2338, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ - _(2339, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ - _(2340, ZEND_CALL_TRAMPOLINE_SPEC) \ - _(2341, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ - _(2342, ZEND_DISCARD_EXCEPTION_SPEC) \ - _(2343, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2337, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ + _(2338, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ + _(2339, ZEND_CALL_TRAMPOLINE_SPEC) \ + _(2340, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ + _(2341, ZEND_DISCARD_EXCEPTION_SPEC) \ + _(2342, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \ _(2344, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2345, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2346, ZEND_YIELD_SPEC_CONST_UNUSED) \ - _(2347, ZEND_YIELD_SPEC_CONST_CV) \ - _(2348, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2345, ZEND_YIELD_SPEC_CONST_UNUSED) \ + _(2346, ZEND_YIELD_SPEC_CONST_CV) \ + _(2347, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \ _(2349, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2350, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2351, ZEND_YIELD_SPEC_TMP_UNUSED) \ - _(2352, ZEND_YIELD_SPEC_TMP_CV) \ - _(2353, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2350, ZEND_YIELD_SPEC_TMP_UNUSED) \ + _(2351, ZEND_YIELD_SPEC_TMP_CV) \ + _(2352, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \ _(2354, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2355, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2356, ZEND_YIELD_SPEC_VAR_UNUSED) \ - _(2357, ZEND_YIELD_SPEC_VAR_CV) \ - _(2358, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2355, ZEND_YIELD_SPEC_VAR_UNUSED) \ + _(2356, ZEND_YIELD_SPEC_VAR_CV) \ + _(2357, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ _(2359, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2360, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2361, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ - _(2362, ZEND_YIELD_SPEC_UNUSED_CV) \ - _(2363, ZEND_YIELD_SPEC_CV_CONST) \ + _(2360, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ + _(2361, ZEND_YIELD_SPEC_UNUSED_CV) \ + _(2362, ZEND_YIELD_SPEC_CV_CONST) \ + _(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \ _(2364, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2365, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2366, ZEND_YIELD_SPEC_CV_UNUSED) \ - _(2367, ZEND_YIELD_SPEC_CV_CV) \ - _(2368, ZEND_GENERATOR_RETURN_SPEC_CONST) \ - _(2369, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2370, ZEND_GENERATOR_RETURN_SPEC_TMP) \ - _(2371, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2372, ZEND_GENERATOR_RETURN_SPEC_VAR) \ - _(2373, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2376, ZEND_GENERATOR_RETURN_SPEC_CV) \ - _(2377, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2378, ZEND_FAST_CALL_SPEC) \ - _(2379, ZEND_FAST_RET_SPEC) \ - _(2380, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ - _(2381, ZEND_SEND_UNPACK_SPEC) \ - _(2382, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2365, ZEND_YIELD_SPEC_CV_UNUSED) \ + _(2366, ZEND_YIELD_SPEC_CV_CV) \ + _(2367, ZEND_GENERATOR_RETURN_SPEC_CONST) \ + _(2368, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2369, ZEND_GENERATOR_RETURN_SPEC_TMP) \ + _(2370, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2371, ZEND_GENERATOR_RETURN_SPEC_VAR) \ + _(2372, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2375, ZEND_GENERATOR_RETURN_SPEC_CV) \ + _(2376, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2377, ZEND_FAST_CALL_SPEC) \ + _(2378, ZEND_FAST_RET_SPEC) \ + _(2379, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ + _(2380, ZEND_SEND_UNPACK_SPEC) \ + _(2381, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \ _(2383, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2384, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2386, ZEND_YIELD_FROM_SPEC_CV) \ - _(2387, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ - _(2388, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ - _(2389, ZEND_COALESCE_SPEC_CONST) \ - _(2390, ZEND_COALESCE_SPEC_TMP) \ - _(2391, ZEND_COALESCE_SPEC_VAR) \ - _(2393, ZEND_COALESCE_SPEC_CV) \ - _(2394, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2385, ZEND_YIELD_FROM_SPEC_CV) \ + _(2386, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ + _(2387, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ + _(2388, ZEND_COALESCE_SPEC_CONST) \ + _(2389, ZEND_COALESCE_SPEC_TMP) \ + _(2390, ZEND_COALESCE_SPEC_VAR) \ + _(2392, ZEND_COALESCE_SPEC_CV) \ + _(2393, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ _(2395, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2396, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2398, ZEND_SPACESHIP_SPEC_CONST_CV) \ - _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2397, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2398, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2400, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2401, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ + _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2405, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2406, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2408, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2414, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ + _(2413, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ _(2415, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2416, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2418, ZEND_SPACESHIP_SPEC_CV_CV) \ - _(2419, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ - _(2420, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ - _(2423, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ - _(2425, ZEND_FETCH_STATIC_PROP_R_SPEC) \ - _(2426, ZEND_FETCH_STATIC_PROP_W_SPEC) \ - _(2427, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ - _(2428, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ - _(2429, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ - _(2430, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ - _(2431, ZEND_UNSET_STATIC_PROP_SPEC) \ - _(2432, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ - _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2417, ZEND_SPACESHIP_SPEC_CV_CV) \ + _(2418, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ + _(2419, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ + _(2422, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ + _(2424, ZEND_FETCH_STATIC_PROP_R_SPEC) \ + _(2425, ZEND_FETCH_STATIC_PROP_W_SPEC) \ + _(2426, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ + _(2427, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ + _(2428, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ + _(2429, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ + _(2430, ZEND_UNSET_STATIC_PROP_SPEC) \ + _(2431, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ + _(2432, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ _(2434, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2435, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2437, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ - _(2443, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \ + _(2442, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2443, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ _(2444, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2445, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ - _(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2446, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \ + _(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ _(2449, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2450, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2452, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ - _(2458, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ - _(2459, ZEND_BIND_STATIC_SPEC_CV) \ - _(2460, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ - _(2461, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ - _(2464, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(2466, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ - _(2467, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2451, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \ + _(2457, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ + _(2458, ZEND_BIND_STATIC_SPEC_CV) \ + _(2459, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ + _(2460, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ + _(2463, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(2465, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ + _(2466, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2467, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ _(2468, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2469, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2471, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2472, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2470, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2471, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2472, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ _(2473, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2474, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2476, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2477, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ - _(2478, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ - _(2479, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ - _(2481, ZEND_IN_ARRAY_SPEC_CV_CONST) \ - _(2482, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2475, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2476, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ + _(2477, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ + _(2478, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ + _(2480, ZEND_IN_ARRAY_SPEC_CV_CONST) \ + _(2481, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2482, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ _(2483, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2484, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2486, ZEND_COUNT_SPEC_CV_UNUSED) \ - _(2487, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2485, ZEND_COUNT_SPEC_CV_UNUSED) \ + _(2486, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2487, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ _(2488, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2489, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2490, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ - _(2491, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ - _(2492, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ - _(2493, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ - _(2494, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ - _(2495, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ - _(2497, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ - _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2489, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ + _(2490, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ + _(2491, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ + _(2492, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ + _(2493, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ + _(2494, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ + _(2496, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ + _(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ _(2499, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2500, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ - _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2504, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2505, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ + _(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2509, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2510, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2512, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2511, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ + _(2517, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ _(2519, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2520, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2522, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ - _(2523, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2521, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ + _(2522, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2523, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ _(2524, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2525, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2527, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2533, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ - _(2534, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ - _(2535, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ - _(2537, ZEND_CASE_STRICT_SPEC_TMP_CV) \ - _(2538, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ - _(2539, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ - _(2540, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ - _(2542, ZEND_CASE_STRICT_SPEC_VAR_CV) \ - _(2553, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2526, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2532, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ + _(2533, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ + _(2534, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ + _(2536, ZEND_CASE_STRICT_SPEC_TMP_CV) \ + _(2537, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ + _(2538, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ + _(2539, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ + _(2541, ZEND_CASE_STRICT_SPEC_VAR_CV) \ + _(2552, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2553, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ _(2554, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2555, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2557, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2558, ZEND_JMP_NULL_SPEC_CONST) \ - _(2559, ZEND_JMP_NULL_SPEC_TMP) \ - _(2560, ZEND_JMP_NULL_SPEC_VAR) \ - _(2562, ZEND_JMP_NULL_SPEC_CV) \ - _(2563, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ - _(2564, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ - _(2565, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ - _(2566, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2567, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ - _(2568, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ - _(2569, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ - _(2570, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ - _(2571, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ - _(2572, ZEND_FRAMELESS_ICALL_2_SPEC) \ - _(2573, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ - _(2574, ZEND_FRAMELESS_ICALL_3_SPEC) \ - _(2575, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ - _(2576, ZEND_JMP_FRAMELESS_SPEC_CONST) \ - _(2577, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ - _(2578, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2579, ZEND_RECV_NOTYPE_SPEC) \ + _(2556, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2557, ZEND_JMP_NULL_SPEC_CONST) \ + _(2558, ZEND_JMP_NULL_SPEC_TMP) \ + _(2559, ZEND_JMP_NULL_SPEC_VAR) \ + _(2561, ZEND_JMP_NULL_SPEC_CV) \ + _(2562, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ + _(2563, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ + _(2564, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ + _(2565, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ + _(2566, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ + _(2567, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ + _(2568, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ + _(2569, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ + _(2570, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ + _(2571, ZEND_FRAMELESS_ICALL_2_SPEC) \ + _(2572, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ + _(2573, ZEND_FRAMELESS_ICALL_3_SPEC) \ + _(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ + _(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \ + _(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ + _(2577, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2578, ZEND_RECV_NOTYPE_SPEC) \ + _(2580, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ _(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2582, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2584, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2585, ZEND_JMP_FORWARD_SPEC) \ - _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2583, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2584, ZEND_JMP_FORWARD_SPEC) \ + _(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2593, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2594, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2598, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2599, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2605, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2608, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2609, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2618, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2619, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2623, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2624, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2630, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2633, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2634, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2643, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2644, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2648, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2649, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2655, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2658, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2659, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2668, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2673, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2674, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2680, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2683, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2684, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2686, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ _(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2688, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2690, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2689, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2693, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2694, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2698, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2699, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2705, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2708, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2709, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2711, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ _(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2713, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2715, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2714, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2718, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2719, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2723, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2724, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2730, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2733, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2734, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2743, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2744, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2748, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2749, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2755, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2758, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2759, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2768, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2769, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2773, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2774, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2780, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2783, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2784, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2793, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2794, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2798, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2799, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2805, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2808, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2885, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2960, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3035, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3111, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3115, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3116, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3120, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3135, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3165, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3195, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3240, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3270, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3390, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3420, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3422, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3424, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3426, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3428, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3429, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3430, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3431, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3432, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3433, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(2809, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3110, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3114, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3115, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3119, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3123, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3420, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3422, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3424, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3426, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3428, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3429, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3430, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3431, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3432, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3433, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ _(3434, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3435, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3437, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3436, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3437, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ _(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3440, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3442, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3441, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3442, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3445, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3447, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3446, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3448, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3450, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3460, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3462, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ _(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3470, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3472, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3475, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3477, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3480, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3482, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3483, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3484, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3486, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3486+1, ZEND_NULL) + _(3471, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3474, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3476, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3479, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3481, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3482, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3483, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3484, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3485+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index d29fc069255db..202dfd3f734f3 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -102,7 +102,7 @@ static const char *zend_vm_opcodes_names[210] = { "ZEND_UNSET_OBJ", "ZEND_FE_RESET_R", "ZEND_FE_FETCH_R", - "ZEND_EXIT", + NULL, "ZEND_FETCH_R", "ZEND_FETCH_DIM_R", "ZEND_FETCH_OBJ_R", diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 2f59a5c874462..d472b5b9660f5 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -161,7 +161,6 @@ END_EXTERN_C() #define ZEND_UNSET_OBJ 76 #define ZEND_FE_RESET_R 77 #define ZEND_FE_FETCH_R 78 -#define ZEND_EXIT 79 #define ZEND_FETCH_R 80 #define ZEND_FETCH_DIM_R 81 #define ZEND_FETCH_OBJ_R 82 diff --git a/Zend/zend_weakrefs_arginfo.h b/Zend/zend_weakrefs_arginfo.h index 25c137c9d76b6..eba02f03fb13c 100644 --- a/Zend/zend_weakrefs_arginfo.h +++ b/Zend/zend_weakrefs_arginfo.h @@ -66,8 +66,7 @@ static zend_class_entry *register_class_WeakReference(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "WeakReference", class_WeakReference_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -77,8 +76,7 @@ static zend_class_entry *register_class_WeakMap(zend_class_entry *class_entry_Ar zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "WeakMap", class_WeakMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 3, class_entry_ArrayAccess, class_entry_Countable, class_entry_IteratorAggregate); return class_entry; diff --git a/build/gen_stub.php b/build/gen_stub.php index 2898002094040..27e52cec55188 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -83,9 +83,15 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = } } + /* Because exit() and die() are proper token/keywords we need to hack-around */ + $hasSpecialExitAsFunctionHandling = str_ends_with($stubFile, 'zend_builtin_functions.stub.php'); if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) { initPhpParser(); - $fileInfo = parseStubFile($stubCode ?? file_get_contents($stubFile)); + $stubContent = $stubCode ?? file_get_contents($stubFile); + if ($hasSpecialExitAsFunctionHandling) { + $stubContent = str_replace(['exit', 'die'], ['exit_dummy', 'die_dummy'], $stubContent); + } + $fileInfo = parseStubFile($stubContent); $context->parsedFiles[$stubFile] = $fileInfo; foreach ($fileInfo->dependencies as $dependency) { @@ -118,6 +124,9 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly = $context->allConstInfos, $stubHash ); + if ($hasSpecialExitAsFunctionHandling) { + $arginfoCode = str_replace(['exit_dummy', 'die_dummy'], ['exit', 'die'], $arginfoCode); + } if (($context->forceRegeneration || $stubHash !== $oldStubHash) && file_put_contents($arginfoFile, $arginfoCode)) { echo "Saved $arginfoFile\n"; } @@ -2907,6 +2916,7 @@ class PropertyInfo extends VariableLike public ?Expr $defaultValue; public ?string $defaultValueString; public bool $isDocReadonly; + public bool $isVirtual; /** * @var AttributeInfo[] $attributes @@ -2920,6 +2930,7 @@ public function __construct( ?Expr $defaultValue, ?string $defaultValueString, bool $isDocReadonly, + bool $isVirtual, ?string $link, ?int $phpVersionIdMinimumCompatibility, array $attributes, @@ -2930,6 +2941,7 @@ public function __construct( $this->defaultValue = $defaultValue; $this->defaultValueString = $defaultValueString; $this->isDocReadonly = $isDocReadonly; + $this->isVirtual = $isVirtual; parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment); } @@ -3045,6 +3057,10 @@ protected function getFlagsByPhpVersion(): array $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_82_VERSION_ID); } + if ($this->isVirtual) { + $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID); + } + return $flags; } @@ -3265,11 +3281,18 @@ public function getRegistration(array $allConstInfos): string $code .= "static zend_class_entry *register_class_$escapedName(" . (empty($params) ? "void" : implode(", ", $params)) . ")\n"; $code .= "{\n"; + + $flagCodes = generateVersionDependentFlagCode("%s", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); + $flags = implode("", $flagCodes); + if ($this->type === "enum") { $name = addslashes((string) $this->name); $backingType = $this->enumBackingType ? $this->enumBackingType->toTypeCode() : "IS_UNDEF"; $code .= "\tzend_class_entry *class_entry = zend_register_internal_enum(\"$name\", $backingType, class_{$escapedName}_methods);\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags\n"; + } } else { $code .= "\tzend_class_entry ce, *class_entry;\n\n"; if (count($this->name->getParts()) > 1) { @@ -3282,15 +3305,29 @@ public function getRegistration(array $allConstInfos): string } if ($this->type === "class" || $this->type === "trait") { - $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; + if (!$php84MinimumCompatibility) { + $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; + } + + $code .= "\tclass_entry = zend_register_internal_class_with_flags(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ", " . ($flags ?: 0) . ");\n"; + + if (!$php84MinimumCompatibility) { + $code .= "#else\n"; + + $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags;\n"; + } + $code .= "#endif\n"; + } } else { $code .= "\tclass_entry = zend_register_internal_interface(&ce);\n"; + if ($flags !== "") { + $code .= "\tclass_entry->ce_flags |= $flags\n"; + } } } - $flagCodes = generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); - $code .= implode("", $flagCodes); - if ($this->exposedDocComment) { if (!$php84MinimumCompatibility) { $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n"; @@ -4424,6 +4461,7 @@ function parseProperty( ): PropertyInfo { $phpDocType = null; $isDocReadonly = false; + $isVirtual = false; $link = null; if ($comments) { @@ -4435,6 +4473,8 @@ function parseProperty( $isDocReadonly = true; } elseif ($tag->name === 'link') { $link = $tag->value; + } elseif ($tag->name === 'virtual') { + $isVirtual = true; } } } @@ -4463,6 +4503,7 @@ function parseProperty( $property->default, $property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null, $isDocReadonly, + $isVirtual, $link, $phpVersionIdMinimumCompatibility, $attributes, diff --git a/build/ltmain.sh b/build/ltmain.sh index ff1685c8a89f9..3c00e79157079 100755 --- a/build/ltmain.sh +++ b/build/ltmain.sh @@ -3467,7 +3467,7 @@ EOF tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in - *.$objext) + *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then diff --git a/build/php.m4 b/build/php.m4 index dc92e56f2140b..442779ba734b4 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -128,8 +128,23 @@ AC_DEFUN([PHP_INIT_BUILD_SYSTEM], php_shtool=$srcdir/build/shtool T_MD=$($php_shtool echo -n -e %B) T_ME=$($php_shtool echo -n -e %b) + +dnl Create empty Makefile placeholders. > Makefile.objects > Makefile.fragments + +dnl Mark whether the CFLAGS are set to automatic default value by Autoconf, or +dnl they are manually modified by the environment variable from outside. E.g. +dnl './configure CFLAGS=...'. Set this before the AC_PROG_CC, where Autoconf +dnl adjusts the CFLAGS variable, so the checks can modify CFLAGS. +AS_VAR_IF([CFLAGS],, [auto_cflags=1]) + +dnl Required programs. +PHP_PROG_AWK + +abs_srcdir=$(cd $srcdir && pwd) +abs_builddir=$(pwd) + dnl Run at the end of the configuration, before creating the config.status. AC_CONFIG_COMMANDS_PRE( [dnl Directory for storing shared objects of extensions. @@ -986,7 +1001,10 @@ dnl $1 = name of extension, $2 = extension upon which it depends dnl $3 = optional: if true, it's ok for $2 to have not been configured default dnl is false and should halt the build. To be effective, this macro must be dnl invoked *after* PHP_NEW_EXTENSION. The extension on which it depends must -dnl also have been configured. See ADD_EXTENSION_DEP in win32 build. +dnl also have been configured. Due to the limited genif.sh parsing and regex +dnl matching implementation, this macro must be called on its own line, and its +dnl arguments must be passed unquoted (without Autoconf '[' and ']' characters. +dnl For Windows, see 'ADD_EXTENSION_DEP' in the win32 build. dnl AC_DEFUN([PHP_ADD_EXTENSION_DEP], [ am_i_shared=$[PHP_]translit($1,a-z_-,A-Z__)[_SHARED] @@ -1721,82 +1739,57 @@ dnl AC_DEFUN([PHP_PROG_RE2C],[ AC_CHECK_PROG([RE2C], [re2c], [re2c]) - ifelse($1,,php_re2c_required_version='',php_re2c_required_version="$1") - - if test -n "$RE2C"; then + php_re2c_check= + AS_VAR_IF([RE2C],,, [ AC_MSG_CHECKING([for re2c version]) php_re2c_version=$($RE2C --version | cut -d ' ' -f 2 2>/dev/null) - if test -z "$php_re2c_version"; then - php_re2c_version=0.0.0 - fi - ac_IFS=$IFS; IFS="." - set $php_re2c_version - IFS=$ac_IFS - php_re2c_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - php_re2c_check=ok - if test -z "$php_re2c_required_version" && test -z "$php_re2c_num"; then - php_re2c_check=invalid - elif test -n "$php_re2c_required_version"; then - ac_IFS=$IFS; IFS="." - set $php_re2c_required_version - IFS=$ac_IFS - php_re2c_required_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - php_re2c_required_version="$php_re2c_required_version or later" - - if test -z "$php_re2c_num" || test "$php_re2c_num" -lt "$php_re2c_required_num"; then - php_re2c_check=invalid - fi - fi + php_re2c_check=ok + AS_VERSION_COMPARE([$php_re2c_version], [$1], + [php_re2c_check=invalid]) - if test "$php_re2c_check" != "invalid"; then - AC_MSG_RESULT([$php_re2c_version (ok)]) - else - AC_MSG_RESULT([$php_re2c_version (too old)]) - fi - fi + AS_VAR_IF([php_re2c_check], [invalid], + [AC_MSG_RESULT([$php_re2c_version (too old)])], + [AC_MSG_RESULT([$php_re2c_version (ok)])]) + ]) - case $php_re2c_check in - ""|invalid[)] - if test ! -f "$abs_srcdir/Zend/zend_language_scanner.c"; then + AS_CASE([$php_re2c_check], + [""|invalid], [ + AS_IF([test ! -f "$abs_srcdir/Zend/zend_language_scanner.c"], [ AC_MSG_ERROR(m4_text_wrap([ - re2c $php_re2c_required_version or newer is required to generate PHP - lexers. + re2c $1 or newer is required to generate PHP lexers. ])) - fi + ]) RE2C="exit 0;" - ;; - esac + ]) PHP_SUBST([RE2C]) AS_VAR_SET([RE2C_FLAGS], m4_normalize(["$2"])) PHP_SUBST([RE2C_FLAGS]) ]) -AC_DEFUN([PHP_PROG_PHP],[ - AC_CHECK_PROG([PHP], [php], [php]) - - if test -n "$PHP"; then - AC_MSG_CHECKING([for php version]) - php_version=$($PHP -v | head -n1 | cut -d ' ' -f 2 | cut -d '-' -f 1) - if test -z "$php_version"; then - php_version=0.0.0 - fi - ac_IFS=$IFS; IFS="." - set $php_version - IFS=$ac_IFS - php_version_num=`expr [$]{1:-0} \* 10000 + [$]{2:-0} \* 100 + [$]{3:-0}` - dnl Minimum supported version for gen_stub.php is PHP 7.4. - if test "$php_version_num" -lt 70400; then - AC_MSG_RESULT([$php_version (too old)]) - unset PHP - else - AC_MSG_RESULT([$php_version (ok)]) - fi - fi - PHP_SUBST([PHP]) +dnl +dnl PHP_PROG_PHP([min-version]) +dnl +dnl Find PHP command-line interface SAPI on the system and check if version is +dnl greater or equal to "min-version". If suitable version is found, the PHP +dnl variable is set and substituted to a Makefile variable. Used for generating +dnl files and running PHP utilities during the build. +dnl +AC_DEFUN([PHP_PROG_PHP], +[m4_if([$1],, [php_required_version=7.4], [php_required_version=$1]) +AC_CHECK_PROG([PHP], [php], [php]) +AS_VAR_IF([PHP],,, [ +AC_MSG_CHECKING([for php version]) +php_version=$($PHP -v | head -n1 | cut -d ' ' -f 2) +AS_VERSION_COMPARE([$php_version], [$php_required_version], [unset PHP]) +AS_VAR_IF([PHP],, + [AC_MSG_RESULT([$php_version (too old, install $php_required_version or later)])], + [AC_MSG_RESULT([$php_version (ok)])]) +]) +PHP_SUBST([PHP]) ]) dnl ---------------------------------------------------------------------------- @@ -1919,7 +1912,7 @@ dnl dnl Common setup macro for libxml. dnl AC_DEFUN([PHP_SETUP_LIBXML], [ - PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.9.0]) + PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.9.4]) PHP_EVAL_INCLINE([$LIBXML_CFLAGS]) PHP_EVAL_LIBLINE([$LIBXML_LIBS], [$1]) $2 diff --git a/configure.ac b/configure.ac index 0abaf4a4f185b..6a30788a2afce 100644 --- a/configure.ac +++ b/configure.ac @@ -100,12 +100,6 @@ dnl ---------------------------------------------------------------------------- PHP_INIT_BUILD_SYSTEM -dnl We want this one before the checks, so the checks can modify CFLAGS. -AS_VAR_IF([CFLAGS],, [auto_cflags=1]) - -abs_srcdir=`(cd $srcdir; pwd)` -abs_builddir=`pwd` - dnl Because `make install` is often performed by the superuser, we create the dnl libs subdirectory as the user who configures PHP. Otherwise, the current dnl user will not be able to delete libs or the contents of libs. @@ -152,10 +146,10 @@ dnl Check for -R, etc. switch. PHP_RUNPATH_SWITCH dnl Checks for some support/generator progs. -PHP_PROG_AWK PHP_PROG_BISON([3.0.0]) PHP_PROG_RE2C([1.0.3], [--no-generation-date]) -PHP_PROG_PHP() +dnl Find installed PHP. Minimum supported version for gen_stub.php is PHP 7.4. +PHP_PROG_PHP([7.4]) PHP_ARG_ENABLE([re2c-cgoto], [whether to enable computed goto extension with re2c], @@ -241,7 +235,7 @@ esac dnl Detect musl libc AC_MSG_CHECKING([whether we are using musl libc]) -if command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl +if command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1 then AC_MSG_RESULT([yes]) AC_DEFINE([__MUSL__], [1], [Define to 1 when using musl libc.]) @@ -702,7 +696,19 @@ AC_FUNC_ALLOCA PHP_TIME_R_TYPE AC_CACHE_CHECK([for aarch64 CRC32 API], [php_cv_func___crc32d], -[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [__crc32d(0, 0);])], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([ +#include +# if defined(__GNUC__) +# if!defined(__clang__) +# pragma GCC push_options +# pragma GCC target ("+nothing+crc") +# elif defined(__APPLE__) +# pragma clang attribute push(__attribute__((target("crc"))), apply_to=function) +# else +# pragma clang attribute push(__attribute__((target("+nothing+crc"))), apply_to=function) +# endif +# endif +], [__crc32d(0, 0);])], [php_cv_func___crc32d=yes], [php_cv_func___crc32d=no])]) AS_VAR_IF([php_cv_func___crc32d], [yes], @@ -1470,8 +1476,6 @@ PHP_SUBST([PHP_FRAMEWORKS]) PHP_SUBST([PHP_FRAMEWORKPATH]) PHP_SUBST([INSTALL_HEADERS]) -old_CC=$CC - if test "$PHP_THREAD_SAFETY" = "yes" && test -n "$ac_cv_pthreads_cflags"; then CXXFLAGS="$CXXFLAGS $ac_cv_pthreads_cflags" CPPFLAGS="$CPPFLAGS $ac_cv_pthreads_cflags" @@ -1578,8 +1582,6 @@ PHP_SET_LIBTOOL_VARIABLE([--silent]) dnl libtool 1.4.3 needs this. PHP_SET_LIBTOOL_VARIABLE([--preserve-dup-deps]) -CC=$old_CC - PHP_CONFIGURE_PART([Generating files]) CXXFLAGS_CLEAN=$CXXFLAGS @@ -1741,6 +1743,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ zend_iterators.c zend_language_parser.c zend_language_scanner.c + zend_lazy_objects.c zend_list.c zend_llist.c zend_max_execution_timer.c @@ -1800,7 +1803,25 @@ AC_CONFIG_FILES([ AC_CONFIG_COMMANDS_PRE([PHP_PATCH_CONFIG_HEADERS([main/php_config.h.in])]) -AC_CONFIG_COMMANDS([default],[ +AC_CONFIG_COMMANDS([Zend/zend_config.h], [ +cat >Zend/zend_config.h < +FEO +]) + +AC_CONFIG_COMMANDS([main/internal_functions.c], [], [ + AWK="$AWK" $SHELL $srcdir/build/genif.sh \ + $srcdir/main/internal_functions.c.in \ + "$EXT_STATIC" > main/internal_functions.c +]) + +AC_CONFIG_COMMANDS([main/internal_functions_cli.c], [], [ + AWK="$AWK" $SHELL $srcdir/build/genif.sh \ + $srcdir/main/internal_functions.c.in \ + "$EXT_CLI_STATIC" > main/internal_functions_cli.c +]) + +AC_CONFIG_COMMANDS([default], [ cat <Zend/zend_config.h < -FEO - -echo "creating main/internal_functions.c" -AWK="$AWK" sh $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_STATIC" > main/internal_functions.c - -echo "creating main/internal_functions_cli.c" -AWK="$AWK" sh $srcdir/build/genif.sh $srcdir/main/internal_functions.c.in "$EXT_CLI_STATIC" > main/internal_functions_cli.c ]) AC_OUTPUT diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 3ca5db6d408b1..75a17604f379f 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -146,7 +146,7 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale); *(result) = mul_ex; \ } while (0) -bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale); +bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, size_t scale); bool bc_modulo(bc_num num1, bc_num num2, bc_num *resul, size_t scale); diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 5d3f0439cc0b7..809d887f68b9d 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -31,219 +31,459 @@ #include "bcmath.h" #include "private.h" +#include "convert.h" #include #include #include #include "zend_alloc.h" +static const BC_VECTOR POW_10_LUT[9] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 +}; -/* Some utility routines for the divide: First a one digit multiply. - NUM (with SIZE digits) is multiplied by DIGIT and the result is - placed into RESULT. It is written so that NUM and RESULT can be - the same pointers. */ - -static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char *result) +/* + * This function should be used when the divisor is not split into multiple chunks, i.e. when the size of the array is one. + * This is because the algorithm can be simplified. + * This function is therefore an optimized version of bc_standard_div(). + */ +static inline void bc_fast_div( + BC_VECTOR *numerator_vectors, size_t numerator_arr_size, BC_VECTOR divisor_vector, BC_VECTOR *quot_vectors, size_t quot_arr_size) { - size_t carry, value; - unsigned char *nptr, *rptr; + size_t numerator_top_index = numerator_arr_size - 1; + size_t quot_top_index = quot_arr_size - 1; + for (size_t i = 0; i < quot_arr_size - 1; i++) { + if (numerator_vectors[numerator_top_index - i] < divisor_vector) { + quot_vectors[quot_top_index - i] = 0; + /* numerator_vectors[numerator_top_index - i] < divisor_vector, so there will be no overflow. */ + numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM; + continue; + } + quot_vectors[quot_top_index - i] = numerator_vectors[numerator_top_index - i] / divisor_vector; + numerator_vectors[numerator_top_index - i] -= divisor_vector * quot_vectors[quot_top_index - i]; + numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM; + numerator_vectors[numerator_top_index - i] = 0; + } + /* last */ + quot_vectors[0] = numerator_vectors[0] / divisor_vector; +} - if (digit == 0) { - memset(result, 0, size); - } else { - if (digit == 1) { - memcpy(result, num, size); - } else { - /* Initialize */ - nptr = (unsigned char *) (num + size - 1); - rptr = (unsigned char *) (result + size - 1); - carry = 0; - - while (size-- > 0) { - value = *nptr-- * digit + carry; - *rptr-- = value % BASE; - carry = value / BASE; - } +/* + * Used when the divisor is split into 2 or more chunks. + * This use the restoring division algorithm. + * https://en.wikipedia.org/wiki/Division_algorithm#Restoring_division + */ +static inline void bc_standard_div( + BC_VECTOR *numerator_vectors, size_t numerator_arr_size, + BC_VECTOR *divisor_vectors, size_t divisor_arr_size, size_t divisor_len, + BC_VECTOR *quot_vectors, size_t quot_arr_size +) { + size_t numerator_top_index = numerator_arr_size - 1; + size_t divisor_top_index = divisor_arr_size - 1; + size_t quot_top_index = quot_arr_size - 1; + + BC_VECTOR div_carry = 0; + + /* + * Errors might occur between the true quotient and the temporary quotient calculated using only the high order digits. + * For example, the true quotient of 240 / 121 is 1. + * However, if it is calculated using only the high-order digits (24 / 12), we would get 2. + * We refer to this value of 2 as the temporary quotient. + * We also define E to be error between the true quotient and the temporary quotient, + * which in this case, is 1. + * + * Another example: Calculating 999_0000_0000 / 1000_9999 with base 10000. + * The true quotient is 9980, but if it is calculated using only the high-order digits (999 / 1000), we would get 0 + * If the temporary quotient is 0, we need to carry the digits to the next division, which is 999_0000 / 1000. + * The new temporary quotient we get is 9990, with error E = 10. + * + * Because we use the restoring division we need to perform E restorations, which can be significant if E is large. + * + * Therefore, for the error E to be at most 1 we adjust the number of high-order digits used to calculate the temporary quotient as follows: + * - Include BC_VECTOR_SIZE + 1 digits of the divisor used in the calculation of the temporary quotient. + The missing digits are filled in from the next array element. + * - Adjust the number of digits in the numerator similarly to what was done for the divisor. + * + * e.g. + * numerator = 123456780000 + * divisor = 123456789 + * base = 10000 + * numerator_arr = [0, 5678, 1234] + * divisor_arr = [6789, 2345, 1] + * numerator_top = 1234 + * divisor_top = 1 + * divisor_top_tmp = 12345 (+4 digits) + * numerator_top_tmp = 12345678 (+4 digits) + * tmp_quot = numerator_top_tmp / divisor_top_tmp = 1000 + * tmp_rem = -9000 + * tmp_quot is too large, so tmp_quot--, tmp_rem += divisor (restoring) + * quot = 999 + * rem = 123447789 + * + * Details: + * Suppose that when calculating the temporary quotient, only the high-order elements of the BC_VECTOR array are used. + * At this time, numerator and divisor can be considered to be decomposed as follows. (Here, B = 10^b, any b ∈ ℕ, any k ∈ ℕ) + * numerator = numerator_high * B^k + numerator_low + * divisor = divisor_high * B^k + divisor_low + * + * The error E can be expressed by the following formula. + * + * E = (numerator_high * B^k) / (divisor_high * B^k) - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low) + * <=> E = numerator_high / divisor_high - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low) + * <=> E = (numerator_high * (divisor_high * B^k + divisor_low) - (numerator_high * B^k + numerator_low) * divisor_high) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * + * Find the error MAX_E when the error E is maximum (0 <= E <= MAX_E). + * First, numerator_high, which only exists in the numerator, uses its maximum value. + * Considering carry-back, numerator_high can be expressed as follows. + * numerator_high = divisor_high * B + * Also, numerator_low is only present in the numerator, but since this is a subtraction, use the smallest possible value here, 0. + * numerator_low = 0 + * + * MAX_E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * + * divisor_low uses the maximum value. + * divisor_low = B^k - 1 + * MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low)) + * <=> MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1)) + * + * divisor_high uses the minimum value, but want to see how the number of digits affects the error, so represent + * the minimum value as: + * divisor_high = 10^x (any x ∈ ℕ) + * Since B = 10^b, the formula becomes: + * MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1)) + * <=> MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1)) + * + * Now let's make an approximation. Remove -1 from the numerator. Approximate the numerator to be + * large and the denominator to be small, such that MAX_E is less than this expression. + * Also, the denominator "(10^b)^k - 1" is never a negative value, so delete it. + * + * MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1)) + * MAX_E < (10^x * 10^b * (10^b)^k) / (10^x * 10^x * (10^b)^k) + * <=> MAX_E < 10^b / 10^x + * <=> MAX_E < 10^(b - x) + * + * Therefore, found that if the number of digits in base B and divisor_high are equal, the error will be less + * than 1 regardless of the number of digits in the value of k. + * + * Here, B is BC_VECTOR_BOUNDARY_NUM, so adjust the number of digits in high part of divisor to be BC_VECTOR_SIZE + 1. + */ + /* the number of usable digits, thus divisor_len % BC_VECTOR_SIZE == 0 implies we have BC_VECTOR_SIZE usable digits */ + size_t divisor_top_digits = divisor_len % BC_VECTOR_SIZE; + if (divisor_top_digits == 0) { + divisor_top_digits = BC_VECTOR_SIZE; + } + + size_t high_part_shift = POW_10_LUT[BC_VECTOR_SIZE - divisor_top_digits + 1]; + size_t low_part_shift = POW_10_LUT[divisor_top_digits - 1]; + BC_VECTOR divisor_high_part = divisor_vectors[divisor_top_index] * high_part_shift + divisor_vectors[divisor_top_index - 1] / low_part_shift; + for (size_t i = 0; i < quot_arr_size; i++) { + BC_VECTOR numerator_high_part = numerator_vectors[numerator_top_index - i] * high_part_shift + numerator_vectors[numerator_top_index - i - 1] / low_part_shift; + + /* + * Determine the temporary quotient. + * The maximum value of numerator_high is divisor_high * B in the previous example, so here numerator_high_part is + * divisor_high_part * BC_VECTOR_BOUNDARY_NUM. + * The number of digits in divisor_high_part is BC_VECTOR_SIZE + 1, so even if divisor_high_part is at its maximum value, + * it will never overflow here. + */ + numerator_high_part += div_carry * BC_VECTOR_BOUNDARY_NUM * high_part_shift; + + /* numerator_high_part < divisor_high_part => quotient == 0 */ + if (numerator_high_part < divisor_high_part) { + quot_vectors[quot_top_index - i] = 0; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; + continue; + } + + BC_VECTOR quot_guess = numerator_high_part / divisor_high_part; + + /* For sub, add the remainder to the high-order digit */ + numerator_vectors[numerator_top_index - i] += div_carry * BC_VECTOR_BOUNDARY_NUM; + + /* + * It is impossible for the temporary quotient to underestimate the true quotient. + * Therefore a temporary quotient of 0 implies the true quotient is also 0. + */ + if (quot_guess == 0) { + quot_vectors[quot_top_index - i] = 0; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; + continue; + } - if (carry != 0) { - *rptr = carry; + /* sub */ + BC_VECTOR sub; + BC_VECTOR borrow = 0; + BC_VECTOR *numerator_calc_bottom = numerator_vectors + numerator_arr_size - divisor_arr_size - i; + size_t j; + for (j = 0; j < divisor_arr_size - 1; j++) { + sub = divisor_vectors[j] * quot_guess + borrow; + BC_VECTOR sub_low = sub % BC_VECTOR_BOUNDARY_NUM; + borrow = sub / BC_VECTOR_BOUNDARY_NUM; + + if (numerator_calc_bottom[j] >= sub_low) { + numerator_calc_bottom[j] -= sub_low; + } else { + numerator_calc_bottom[j] += BC_VECTOR_BOUNDARY_NUM - sub_low; + borrow++; + } + } + /* last digit sub */ + sub = divisor_vectors[j] * quot_guess + borrow; + bool neg_remainder = numerator_calc_bottom[j] < sub; + numerator_calc_bottom[j] -= sub; + + /* If the temporary quotient is too large, add back divisor */ + BC_VECTOR carry = 0; + if (neg_remainder) { + quot_guess--; + for (j = 0; j < divisor_arr_size - 1; j++) { + numerator_calc_bottom[j] += divisor_vectors[j] + carry; + carry = numerator_calc_bottom[j] / BC_VECTOR_BOUNDARY_NUM; + numerator_calc_bottom[j] %= BC_VECTOR_BOUNDARY_NUM; } + /* last add */ + numerator_calc_bottom[j] += divisor_vectors[j] + carry; } + + quot_vectors[quot_top_index - i] = quot_guess; + div_carry = numerator_vectors[numerator_top_index - i]; + numerator_vectors[numerator_top_index - i] = 0; } } +static void bc_do_div( + const char *numerator, size_t numerator_readable_len, size_t numerator_bottom_extension, + const char *divisor, size_t divisor_len, bc_num *quot, size_t quot_len +) { + size_t divisor_arr_size = (divisor_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE; + size_t numerator_arr_size = (numerator_readable_len + numerator_bottom_extension + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE; + size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1; + size_t quot_real_arr_size = MIN(quot_arr_size, (quot_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE); + + BC_VECTOR *numerator_vectors = safe_emalloc(numerator_arr_size + divisor_arr_size + quot_arr_size, sizeof(BC_VECTOR), 0); + BC_VECTOR *divisor_vectors = numerator_vectors + numerator_arr_size; + BC_VECTOR *quot_vectors = divisor_vectors + divisor_arr_size; + + /* Fill with zeros and convert as many vector elements as needed */ + size_t numerator_vector_count = 0; + while (numerator_bottom_extension >= BC_VECTOR_SIZE) { + numerator_vectors[numerator_vector_count] = 0; + numerator_bottom_extension -= BC_VECTOR_SIZE; + numerator_vector_count++; + } -/* The full division routine. This computes N1 / N2. It returns - true if the division is ok and the result is in QUOT. The number of - digits after the decimal point is SCALE. It returns false if division - by zero is tried. The algorithm is found in Knuth Vol 2. p237. */ -bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale) -{ - bc_num qval; - unsigned char *num1, *num2; - unsigned char *ptr1, *ptr2, *n2ptr, *qptr; - int scale1, val; - unsigned int len1, len2, scale2, qdigits, extra, count; - unsigned int qdig, qguess, borrow, carry; - unsigned char *mval; - unsigned int norm; - bool zero; - - /* Test for divide by zero. */ - if (bc_is_zero(n2)) { - return false; + size_t numerator_bottom_read_len = BC_VECTOR_SIZE - numerator_bottom_extension; + + size_t base; + size_t numerator_read = 0; + if (numerator_bottom_read_len < BC_VECTOR_SIZE) { + numerator_read = MIN(numerator_bottom_read_len, numerator_readable_len); + base = POW_10_LUT[numerator_bottom_extension]; + numerator_vectors[numerator_vector_count] = 0; + for (size_t i = 0; i < numerator_read; i++) { + numerator_vectors[numerator_vector_count] += *numerator * base; + base *= BASE; + numerator--; + } + numerator_vector_count++; } - /* Test for divide by 1. If it is we must truncate. */ - if (n2->n_scale == 0 && n2->n_len == 1 && *n2->n_value == 1) { - qval = bc_new_num (n1->n_len, scale); - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - memcpy(qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale, scale)); - bc_free_num (quot); - *quot = qval; + /* Bulk convert numerator and divisor to vectors */ + if (numerator_readable_len > numerator_read) { + bc_convert_to_vector(numerator_vectors + numerator_vector_count, numerator, numerator_readable_len - numerator_read); } + bc_convert_to_vector(divisor_vectors, divisor, divisor_len); - /* Set up the divide. Move the decimal point on n1 by n2's scale. - Remember, zeros on the end of num2 are wasted effort for dividing. */ - scale2 = n2->n_scale; - n2ptr = (unsigned char *) n2->n_value + n2->n_len + scale2 - 1; - while ((scale2 > 0) && (*n2ptr == 0)) { - scale2--; - n2ptr--; + /* Do the division */ + if (divisor_arr_size == 1) { + bc_fast_div(numerator_vectors, numerator_arr_size, divisor_vectors[0], quot_vectors, quot_arr_size); + } else { + bc_standard_div(numerator_vectors, numerator_arr_size, divisor_vectors, divisor_arr_size, divisor_len, quot_vectors, quot_arr_size); + } + + /* Convert to bc_num */ + char *qptr = (*quot)->n_value; + char *qend = qptr + quot_len - 1; + + size_t i; + for (i = 0; i < quot_real_arr_size - 1; i++) { +#if BC_VECTOR_SIZE == 4 + bc_write_bcd_representation(quot_vectors[i], qend - 3); + qend -= 4; +#else + bc_write_bcd_representation(quot_vectors[i] / 10000, qend - 7); + bc_write_bcd_representation(quot_vectors[i] % 10000, qend - 3); + qend -= 8; +#endif } - len1 = n1->n_len + scale2; - scale1 = n1->n_scale - scale2; - extra = MAX(scale - scale1, 0); + while (qend >= qptr) { + *qend-- = quot_vectors[i] % BASE; + quot_vectors[i] /= BASE; + } - num1 = (unsigned char *) safe_emalloc(1, n1->n_len + n1->n_scale, extra + 2); - memset(num1, 0, n1->n_len + n1->n_scale + extra + 2); - memcpy(num1 + 1, n1->n_value, n1->n_len + n1->n_scale); + efree(numerator_vectors); +} - len2 = n2->n_len + scale2; - num2 = (unsigned char *) safe_emalloc(1, len2, 1); - memcpy(num2, n2->n_value, len2); - *(num2 + len2) = 0; - n2ptr = num2; - while (*n2ptr == 0) { - n2ptr++; - len2--; +bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) +{ + /* divide by zero */ + if (bc_is_zero(divisor)) { + return false; } - /* Calculate the number of quotient digits. */ - if (len2 > len1 + scale) { - qdigits = scale + 1; - zero = true; - } else { - zero = false; - if (len2 > len1) { - /* One for the zero integer part. */ - qdigits = scale + 1; - } else { - qdigits = len1 - len2 + scale + 1; - } + bc_free_num(quot); + + /* If numerator is zero, the quotient is always zero. */ + if (bc_is_zero(numerator)) { + *quot = bc_copy_num(BCG(_zero_)); + return true; } - /* Allocate and zero the storage for the quotient. */ - qval = bc_new_num (qdigits - scale, scale); + /* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */ + if (_bc_do_compare(divisor, BCG(_one_), scale, false) == BCMATH_EQUAL) { + size_t quot_scale = MIN(numerator->n_scale, scale); + *quot = bc_new_num_nonzeroed(numerator->n_len, quot_scale); + char *qptr = (*quot)->n_value; + memcpy(qptr, numerator->n_value, numerator->n_len + quot_scale); + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + _bc_rm_leading_zeros(*quot); + return true; + } - /* Allocate storage for the temporary storage mval. */ - mval = (unsigned char *) safe_emalloc(1, len2, 1); + char *numeratorptr = numerator->n_value; + char *numeratorend = numeratorptr + numerator->n_len + numerator->n_scale - 1; + size_t numerator_len = numerator->n_len; + size_t numerator_scale = numerator->n_scale; + + char *divisorptr = divisor->n_value; + char *divisorend = divisorptr + divisor->n_len + divisor->n_scale - 1; + size_t divisor_len = divisor->n_len; + size_t divisor_scale = divisor->n_scale; + size_t divisor_int_right_zeros = 0; + + /* remove divisor trailing zeros */ + while (*divisorend == 0 && divisor_scale > 0) { + divisorend--; + divisor_scale--; + } + while (*divisorend == 0) { + divisorend--; + divisor_int_right_zeros++; + } - /* Now for the full divide algorithm. */ - if (!zero) { - /* Normalize */ - norm = 10 / ((int) *n2ptr + 1); - if (norm != 1) { - _one_mult(num1, len1 + scale1 + extra + 1, norm, num1); - _one_mult(n2ptr, len2, norm, n2ptr); - } + if (*numeratorptr == 0 && numerator_len == 1) { + numeratorptr++; + numerator_len = 0; + } - /* Initialize divide loop. */ - qdig = 0; - if (len2 > len1) { - qptr = (unsigned char *) qval->n_value + len2 - len1; - } else { - qptr = (unsigned char *) qval->n_value; - } + size_t numerator_top_extension = 0; + size_t numerator_bottom_extension = 0; + if (divisor_scale > 0) { + /* + * e.g. divisor_scale = 4 + * divisor = .0002, to be 2 or divisor = 200.001, to be 200001 + * numerator = .03, to be 300 or numerator = .000003, to be .03 + * numerator may become longer than the original data length due to the addition of + * trailing zeros in the integer part. + */ + numerator_len += divisor_scale; + numerator_bottom_extension = numerator_scale < divisor_scale ? divisor_scale - numerator_scale : 0; + numerator_scale = numerator_scale > divisor_scale ? numerator_scale - divisor_scale : 0; + divisor_len += divisor_scale; + divisor_scale = 0; + } else if (divisor_int_right_zeros > 0) { + /* + * e.g. divisor_int_right_zeros = 4 + * divisor = 2000, to be 2 + * numerator = 30, to be .03 or numerator = 30000, to be 30 + * Also, numerator may become longer than the original data length due to the addition of + * leading zeros in the fractional part. + */ + numerator_top_extension = numerator_len < divisor_int_right_zeros ? divisor_int_right_zeros - numerator_len : 0; + numerator_len = numerator_len > divisor_int_right_zeros ? numerator_len - divisor_int_right_zeros : 0; + numerator_scale += divisor_int_right_zeros; + divisor_len -= divisor_int_right_zeros; + divisor_scale = 0; + } - /* Loop */ - while (qdig <= len1 + scale - len2) { - /* Calculate the quotient digit guess. */ - if (*n2ptr == num1[qdig]) { - qguess = 9; - } else { - qguess = (num1[qdig] * 10 + num1[qdig + 1]) / *n2ptr; - } + /* remove numerator leading zeros */ + while (*numeratorptr == 0 && numerator_len > 0) { + numeratorptr++; + numerator_len--; + } + /* remove divisor leading zeros */ + while (*divisorptr == 0) { + divisorptr++; + divisor_len--; + } - /* Test qguess. */ - if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) { - qguess--; - /* And again. */ - if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) { - qguess--; - } - } + /* Considering the scale specification, the quotient is always 0 if this condition is met */ + if (divisor_len > numerator_len + scale) { + *quot = bc_copy_num(BCG(_zero_)); + return true; + } - /* Multiply and subtract. */ - borrow = 0; - if (qguess != 0) { - *mval = 0; - _one_mult(n2ptr, len2, qguess, mval + 1); - ptr1 = (unsigned char *) num1 + qdig + len2; - ptr2 = (unsigned char *) mval + len2; - for (count = 0; count < len2 + 1; count++) { - val = (int) *ptr1 - (int) *ptr2-- - borrow; - if (val < 0) { - val += 10; - borrow = 1; - } else { - borrow = 0; - } - *ptr1-- = val; - } - } + /* set scale to numerator */ + if (numerator_scale > scale) { + size_t scale_diff = numerator_scale - scale; + if (numerator_bottom_extension > scale_diff) { + numerator_bottom_extension -= scale_diff; + } else { + numerator_bottom_extension = 0; + numeratorend -= scale_diff - numerator_bottom_extension; + } + } else { + numerator_bottom_extension += scale - numerator_scale; + } + numerator_scale = scale; - /* Test for negative result. */ - if (borrow == 1) { - qguess--; - ptr1 = (unsigned char *) num1 + qdig + len2; - ptr2 = (unsigned char *) n2ptr + len2 - 1; - carry = 0; - for (count = 0; count < len2; count++) { - val = (int) *ptr1 + (int) *ptr2-- + carry; - if (val > 9) { - val -= 10; - carry = 1; - } else { - carry = 0; - } - *ptr1-- = val; - } - if (carry == 1) { - *ptr1 = (*ptr1 + 1) % 10; - } - } + /* Length of numerator data that can be read */ + size_t numerator_readable_len = numeratorend - numeratorptr + 1; - /* We now know the quotient digit. */ - *qptr++ = qguess; - qdig++; + /* If divisor is 1 here, return the result of adjusting the decimal point position of numerator. */ + if (divisor_len == 1 && *divisorptr == 1) { + if (numerator_len == 0) { + numerator_len = 1; + numerator_top_extension++; } + size_t quot_scale = numerator_scale > numerator_bottom_extension ? numerator_scale - numerator_bottom_extension : 0; + numerator_bottom_extension = numerator_scale < numerator_bottom_extension ? numerator_bottom_extension - numerator_scale : 0; + + *quot = bc_new_num_nonzeroed(numerator_len, quot_scale); + char *qptr = (*quot)->n_value; + for (size_t i = 0; i < numerator_top_extension; i++) { + *qptr++ = 0; + } + memcpy(qptr, numeratorptr, numerator_readable_len); + qptr += numerator_readable_len; + for (size_t i = 0; i < numerator_bottom_extension; i++) { + *qptr++ = 0; + } + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + return true; } - /* Clean up and return the number. */ - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - if (bc_is_zero(qval)) { - qval->n_sign = PLUS; + size_t quot_full_len; + if (divisor_len > numerator_len) { + *quot = bc_new_num_nonzeroed(1, scale); + quot_full_len = 1 + scale; + } else { + *quot = bc_new_num_nonzeroed(numerator_len - divisor_len + 1, scale); + quot_full_len = numerator_len - divisor_len + 1 + scale; } - _bc_rm_leading_zeros(qval); - bc_free_num(quot); - *quot = qval; - /* Clean up temporary storage. */ - efree(mval); - efree(num1); - efree(num2); + /* do divide */ + bc_do_div(numeratorend, numerator_readable_len, numerator_bottom_extension, divisorend, divisor_len, quot, quot_full_len); + _bc_rm_leading_zeros(*quot); + if (bc_is_zero(*quot)) { + (*quot)->n_sign = PLUS; + } else { + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + } - /* Everything is OK. */ return true; } diff --git a/ext/bcmath/libbcmath/src/floor_or_ceil.c b/ext/bcmath/libbcmath/src/floor_or_ceil.c index b0ff811f0a223..98dc94601ac75 100644 --- a/ext/bcmath/libbcmath/src/floor_or_ceil.c +++ b/ext/bcmath/libbcmath/src/floor_or_ceil.c @@ -30,7 +30,7 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If the number is positive and we are flooring, then nothing else needs to be done. * Similarly, if the number is negative and we are ceiling, then nothing else needs to be done. */ if (num->n_scale == 0 || result->n_sign == (is_floor ? PLUS : MINUS)) { - return result; + goto check_zero; } /* check fractional part. */ @@ -43,12 +43,19 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If all digits past the decimal point are 0 */ if (count == 0) { - return result; + goto check_zero; } /* Increment the absolute value of the result by 1 and add sign information */ bc_num tmp = _bc_do_add(result, BCG(_one_)); tmp->n_sign = result->n_sign; bc_free_num(&result); - return tmp; + result = tmp; + +check_zero: + if (bc_is_zero(result)) { + result->n_sign = PLUS; + } + + return result; } diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c index 7ece5ef6b85c4..3a4892cc7079e 100644 --- a/ext/bcmath/libbcmath/src/round.c +++ b/ext/bcmath/libbcmath/src/round.c @@ -76,7 +76,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr >= 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } break; @@ -86,14 +86,14 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr > 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } /* if *nptr == 5, we need to look-up further digits before making a decision. */ break; case PHP_ROUND_CEILING: if (num->n_sign != PLUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -102,7 +102,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_FLOOR: if (num->n_sign != MINUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -110,7 +110,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) break; case PHP_ROUND_TOWARD_ZERO: - return; + goto check_zero; case PHP_ROUND_AWAY_FROM_ZERO: if (*nptr > 0) { @@ -139,17 +139,17 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_CEILING: case PHP_ROUND_FLOOR: case PHP_ROUND_AWAY_FROM_ZERO: - return; + goto check_zero; case PHP_ROUND_HALF_EVEN: if (rounded_len == 0 || num->n_value[rounded_len - 1] % 2 == 0) { - return; + goto check_zero; } break; case PHP_ROUND_HALF_ODD: if (rounded_len != 0 && num->n_value[rounded_len - 1] % 2 == 1) { - return; + goto check_zero; } break; @@ -176,4 +176,9 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) bc_free_num(result); *result = tmp; } + +check_zero: + if (bc_is_zero(*result)) { + (*result)->n_sign = PLUS; + } } diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index 0e777851a5f74..86de6a5ca5f2d 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -349,7 +349,7 @@ PHP_FUNCTION(bzopen) /* If it's not a resource its a string containing the filename to open */ if (Z_TYPE_P(file) == IS_STRING) { if (Z_STRLEN_P(file) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/bz2/tests/001.phpt b/ext/bz2/tests/001.phpt index 6b86bd6b0b6db..767a50a27d8bf 100644 --- a/ext/bz2/tests/001.phpt +++ b/ext/bz2/tests/001.phpt @@ -42,8 +42,8 @@ var_dump(bzopen($fp, "r")); ?> --EXPECTF-- -bzopen(): Argument #1 ($file) cannot be empty -bzopen(): Argument #1 ($file) cannot be empty +bzopen(): Argument #1 ($file) must not be empty +bzopen(): Argument #1 ($file) must not be empty bzopen(): Argument #2 ($mode) must be either "r" or "w" bzopen(): Argument #2 ($mode) must be either "r" or "w" bzopen(): Argument #2 ($mode) must be either "r" or "w" diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index 24063c5c550b7..fd2d1ee9a4394 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -392,7 +392,7 @@ HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, default: desc = php_win32_error_to_msg(hr); - spprintf(&msg, 0, "Error [0x%08x] %s", hr, desc); + spprintf(&msg, 0, "Error [0x%08lx] %s", hr, desc); php_win32_error_msg_free(desc); break; } @@ -639,7 +639,7 @@ zend_result php_com_do_invoke(php_com_dotnet_object *obj, zend_string *name, if (FAILED(hr)) { char *winerr = php_win32_error_to_msg(hr); - spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr); + spprintf(&msg, 0, "Unable to lookup `%s': %s", ZSTR_VAL(name), winerr); php_win32_error_msg_free(winerr); php_com_throw_exception(hr, msg); efree(msg); diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index 1b479a2d34de3..3ce2daddaa7b0 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -20,7 +20,7 @@ #include "php.h" -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H # include "php_ini.h" # include "ext/standard/info.h" # include "php_com_dotnet.h" @@ -245,7 +245,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to init .Net runtime [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to init .Net runtime [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); RETURN_THROWS(); @@ -258,7 +258,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); @@ -270,7 +270,7 @@ PHP_METHOD(dotnet, __construct) if (FAILED(hr)) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); @@ -344,7 +344,7 @@ PHP_METHOD(dotnet, __construct) if (ret == FAILURE) { char buf[1024]; char *err = php_win32_error_to_msg(hr); - snprintf(buf, sizeof(buf), "Failed to instantiate .Net object [%s] [0x%08x] %s", where, hr, err); + snprintf(buf, sizeof(buf), "Failed to instantiate .Net object [%s] [0x%08lx] %s", where, hr, err); php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); RETURN_THROWS(); diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c index e6e14a45a9c75..1f18d2a8573ab 100644 --- a/ext/com_dotnet/com_extension.c +++ b/ext/com_dotnet/com_extension.c @@ -195,7 +195,7 @@ PHP_MINIT_FUNCTION(com_dotnet) tmp->create_object = php_com_object_new; tmp->get_iterator = php_com_iter_get; -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H tmp = register_class_dotnet(php_com_variant_class_entry); tmp->default_object_handlers = &php_com_object_handlers; tmp->create_object = php_com_object_new; @@ -216,7 +216,7 @@ PHP_MINIT_FUNCTION(com_dotnet) PHP_MSHUTDOWN_FUNCTION(com_dotnet) { UNREGISTER_INI_ENTRIES(); -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H if (COMG(dotnet_runtime_stuff)) { php_com_dotnet_mshutdown(); } @@ -239,7 +239,7 @@ PHP_RINIT_FUNCTION(com_dotnet) /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(com_dotnet) { -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H if (COMG(dotnet_runtime_stuff)) { php_com_dotnet_rshutdown(); } @@ -257,7 +257,7 @@ PHP_MINFO_FUNCTION(com_dotnet) php_info_print_table_row(2, "COM support", "enabled"); php_info_print_table_row(2, "DCOM support", COMG(allow_dcom) ? "enabled" : "disabled"); -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H php_info_print_table_row(2, ".Net support", "enabled"); #else php_info_print_table_row(2, ".Net support", "not present in this build"); diff --git a/ext/com_dotnet/com_extension.stub.php b/ext/com_dotnet/com_extension.stub.php index 3207871f85c7d..0bbe976279f6a 100644 --- a/ext/com_dotnet/com_extension.stub.php +++ b/ext/com_dotnet/com_extension.stub.php @@ -363,7 +363,7 @@ class com extends variant public function __construct(string $module_name, array|string|null $server_name = null, int $codepage = CP_ACP, string $typelib = "") {} } -#if HAVE_MSCOREE_H +#ifdef HAVE_MSCOREE_H class dotnet extends variant { public function __construct(string $assembly_name, string $datatype_name, int $codepage = CP_ACP) {} diff --git a/ext/com_dotnet/com_extension_arginfo.h b/ext/com_dotnet/com_extension_arginfo.h index c75fa6df9c877..c86ca50d99e84 100644 --- a/ext/com_dotnet/com_extension_arginfo.h +++ b/ext/com_dotnet/com_extension_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b91206482b5119ce6d7c899e9599acfa2e06ec2a */ + * Stub hash: 9b2eea541946c291eb002ee98997f3dcad8bdfce */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_variant_set, 0, 2, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, variant, variant, 0) @@ -123,7 +123,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_com___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, typelib, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_dotnet___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, assembly_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, datatype_name, IS_STRING, 0) @@ -165,7 +165,7 @@ ZEND_FUNCTION(com_message_pump); ZEND_FUNCTION(com_load_typelib); ZEND_METHOD(variant, __construct); ZEND_METHOD(com, __construct); -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) ZEND_METHOD(dotnet, __construct); #endif @@ -215,7 +215,7 @@ static const zend_function_entry class_com_methods[] = { ZEND_FE_END }; -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) static const zend_function_entry class_dotnet_methods[] = { ZEND_ME(dotnet, __construct, arginfo_class_dotnet___construct, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -300,8 +300,7 @@ static zend_class_entry *register_class_variant(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "variant", class_variant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -311,18 +310,18 @@ static zend_class_entry *register_class_com(zend_class_entry *class_entry_varian zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com", class_com_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_variant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_variant, 0); return class_entry; } -#if HAVE_MSCOREE_H +#if defined(HAVE_MSCOREE_H) static zend_class_entry *register_class_dotnet(zend_class_entry *class_entry_variant) { zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "dotnet", class_dotnet_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_variant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_variant, 0); return class_entry; } @@ -333,8 +332,7 @@ static zend_class_entry *register_class_com_safearray_proxy(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com_safearray_proxy", class_com_safearray_proxy_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } @@ -344,8 +342,7 @@ static zend_class_entry *register_class_com_exception(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "com_exception", class_com_exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/com_dotnet/com_persist_arginfo.h b/ext/com_dotnet/com_persist_arginfo.h index 6867cff30a41b..4449396e9ccef 100644 --- a/ext/com_dotnet/com_persist_arginfo.h +++ b/ext/com_dotnet/com_persist_arginfo.h @@ -56,8 +56,7 @@ static zend_class_entry *register_class_COMPersistHelper(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "COMPersistHelper", class_COMPersistHelper_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index f5094942914f7..4f6a3309b8cd5 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -543,7 +543,7 @@ bool php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, bool p /* first element is the function name */ SysFreeString(names[0]); - php_printf("\t/* DISPID=%d */\n", func->memid); + php_printf("\t/* DISPID=%ld */\n", func->memid); if (func->elemdescFunc.tdesc.vt != VT_VOID) { php_printf("\t/* %s [%d] */\n", diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 3b19d89cf705d..e505dc654026f 100644 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -53,7 +53,7 @@ static inline void trace(char *fmt, ...) va_list ap; char buf[4096]; - snprintf(buf, sizeof(buf), "T=%08x ", GetCurrentThreadId()); + snprintf(buf, sizeof(buf), "T=%08lx ", GetCurrentThreadId()); OutputDebugString(buf); va_start(ap, fmt); @@ -70,7 +70,7 @@ static inline void trace(char *fmt, ...) if (COMG(rshutdown_started)) { \ trace(" PHP Object:%p (name:unknown) %s\n", Z_OBJ(disp->object), methname); \ } else { \ - trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val, methname); \ + trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), ZSTR_VAL(Z_OBJCE(disp->object)->name), methname); \ } \ if (GetCurrentThreadId() != disp->engine_thread) { \ return RPC_E_WRONG_THREAD; \ @@ -109,7 +109,7 @@ static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This) FETCH_DISP("Release"); ret = InterlockedDecrement(&disp->refcount); - trace("-- refcount now %d\n", ret); + trace("-- refcount now %lu\n", ret); if (ret == 0) { /* destroy it */ disp_destructor(disp); @@ -201,7 +201,7 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( name = php_com_olestring_to_string(bstrName, COMG(code_page)); - trace("Looking for %s, namelen=%d in %p\n", ZSTR_VAL(name), ZSTR_LEN(name), disp->name_to_dispid); + trace("Looking for %s, namelen=%lu in %p\n", ZSTR_VAL(name), ZSTR_LEN(name), disp->name_to_dispid); /* Lookup the name in the hash */ if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { @@ -235,7 +235,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { /* TODO: add support for overloaded objects */ - trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); + trace("-- Invoke: %ld %20s [%lu] flags=%08x args=%u\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); /* convert args into zvals. * Args are in reverse order */ @@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( arg = &pdp->rgvarg[ pdp->cArgs - 1 - i]; - trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg)); + trace("alloc zval for arg %u VT=%08x\n", i, V_VT(arg)); php_com_wrap_variant(¶ms[i], arg, COMG(code_page)); } @@ -275,7 +275,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( VARIANT *srcvar = &obj->v; VARIANT *dstvar = &pdp->rgvarg[ pdp->cArgs - 1 - i]; if ((V_VT(dstvar) & VT_BYREF) && obj->modified ) { - trace("percolate modified value for arg %d VT=%08x\n", i, V_VT(dstvar)); + trace("percolate modified value for arg %u VT=%08x\n", i, V_VT(dstvar)); php_com_copy_variant(dstvar, srcvar); } } @@ -311,7 +311,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( } } else { - trace("InvokeEx: I don't support DISPID=%d\n", id); + trace("InvokeEx: I don't support DISPID=%ld\n", id); } return ret; @@ -508,7 +508,7 @@ static php_dispatchex *disp_constructor(zval *object) { php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex)); - trace("constructing a COM wrapper for PHP object %p (%s)\n", object, Z_OBJCE_P(object)->name); + trace("constructing a COM wrapper for PHP object %p (%s)\n", object, ZSTR_VAL(Z_OBJCE_P(object)->name)); if (disp == NULL) return NULL; diff --git a/ext/com_dotnet/tests/lookup_error.phpt b/ext/com_dotnet/tests/lookup_error.phpt new file mode 100644 index 0000000000000..beb276eb8d99b --- /dev/null +++ b/ext/com_dotnet/tests/lookup_error.phpt @@ -0,0 +1,15 @@ +--TEST-- +Property name lookup error +--EXTENSIONS-- +com_dotnet +--FILE-- +unknownProperty; +} catch (com_exception $ex) { + echo $ex->getMessage(), "\n"; +} +?> +--EXPECTF-- +Unable to lookup `unknownProperty': %s diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index 0adfb17c4d3f3..c7eba7394843c 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -407,6 +407,13 @@ * @cvalue CURLOPT_STDERR */ const CURLOPT_STDERR = UNKNOWN; +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ +/** + * @var int + * @cvalue CURLOPT_TCP_KEEPCNT + */ +const CURLOPT_TCP_KEEPCNT = UNKNOWN; +#endif /** * @var int * @cvalue CURLOPT_TELNETOPTIONS @@ -3490,6 +3497,21 @@ * @cvalue CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 */ const CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = UNKNOWN; +/** + * @var int + * @cvalue CURLOPT_PREREQFUNCTION + */ +const CURLOPT_PREREQFUNCTION = UNKNOWN; +/** + * @var int + * @cvalue CURL_PREREQFUNC_OK + */ +const CURL_PREREQFUNC_OK = UNKNOWN; +/** + * @var int + * @cvalue CURL_PREREQFUNC_ABORT + */ +const CURL_PREREQFUNC_ABORT = UNKNOWN; #endif #if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */ diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index 044763d57df0f..f3f13ae3b4ca0 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b5a3bd62bcb62b2e7e4aacfcd4621cc632be1564 */ + * Stub hash: 3a5bd4e561f08f0dbd26383132a771acc8192fff */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -307,6 +307,9 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_STDERR", CURLOPT_STDERR, CONST_PERSISTENT); +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ + REGISTER_LONG_CONSTANT("CURLOPT_TCP_KEEPCNT", CURLOPT_TCP_KEEPCNT, CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("CURLOPT_TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLOPT_TIMEOUT", CURLOPT_TIMEOUT, CONST_PERSISTENT); @@ -1058,6 +1061,15 @@ static void register_curl_symbols(int module_number) #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ REGISTER_LONG_CONSTANT("CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CONST_PERSISTENT); #endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURLOPT_PREREQFUNCTION", CURLOPT_PREREQFUNCTION, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURL_PREREQFUNC_OK", CURL_PREREQFUNC_OK, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + REGISTER_LONG_CONSTANT("CURL_PREREQFUNC_ABORT", CURL_PREREQFUNC_ABORT, CONST_PERSISTENT); +#endif #if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */ REGISTER_LONG_CONSTANT("CURLOPT_MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CONST_PERSISTENT); #endif @@ -1096,8 +1108,7 @@ static zend_class_entry *register_class_CurlHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlHandle", class_CurlHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1107,8 +1118,7 @@ static zend_class_entry *register_class_CurlMultiHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlMultiHandle", class_CurlMultiHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1118,8 +1128,7 @@ static zend_class_entry *register_class_CurlShareHandle(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CurlShareHandle", class_CurlShareHandle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/curl/curl_file_arginfo.h b/ext/curl/curl_file_arginfo.h index 3f7d20466dbc9..bbf6900546a15 100644 --- a/ext/curl/curl_file_arginfo.h +++ b/ext/curl/curl_file_arginfo.h @@ -56,8 +56,7 @@ static zend_class_entry *register_class_CURLFile(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CURLFile", class_CURLFile_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval property_name_default_value; ZVAL_EMPTY_STRING(&property_name_default_value); @@ -85,7 +84,7 @@ static zend_class_entry *register_class_CURLStringFile(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CURLStringFile", class_CURLStringFile_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); diff --git a/ext/curl/curl_private.h b/ext/curl/curl_private.h index c15396f255b17..011c4874e6140 100644 --- a/ext/curl/curl_private.h +++ b/ext/curl/curl_private.h @@ -68,6 +68,9 @@ typedef struct { zend_fcall_info_cache progress; zend_fcall_info_cache xferinfo; zend_fcall_info_cache fnmatch; +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + zend_fcall_info_cache prereq; +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ zend_fcall_info_cache sshhostkey; #endif diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 994bac82f3809..4697f468098d6 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -504,6 +504,11 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n) zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.fnmatch); } +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(curl->handlers.prereq)) { + zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(curl->handlers.sshhostkey)) { zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.sshhostkey); @@ -709,6 +714,60 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, } /* }}} */ +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ +static int curl_prereqfunction(void *clientp, char *conn_primary_ip, char *conn_local_ip, int conn_primary_port, int conn_local_port) +{ + php_curl *ch = (php_curl *)clientp; + int rval = CURL_PREREQFUNC_OK; + + // when CURLOPT_PREREQFUNCTION is set to null, curl_prereqfunction still + // gets called. Return CURL_PREREQFUNC_OK immediately in this case to avoid + // zend_call_known_fcc() with an uninitialized FCC. + if (!ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + return rval; + } + +#if PHP_CURL_DEBUG + fprintf(stderr, "curl_prereqfunction() called\n"); + fprintf(stderr, "conn_primary_ip = %s, conn_local_ip = %s, conn_primary_port = %d, conn_local_port = %d\n", conn_primary_ip, conn_local_ip, conn_primary_port, conn_local_port); +#endif + + zval args[5]; + zval retval; + + GC_ADDREF(&ch->std); + ZVAL_OBJ(&args[0], &ch->std); + ZVAL_STRING(&args[1], conn_primary_ip); + ZVAL_STRING(&args[2], conn_local_ip); + ZVAL_LONG(&args[3], conn_primary_port); + ZVAL_LONG(&args[4], conn_local_port); + + ch->in_callback = true; + zend_call_known_fcc(&ch->handlers.prereq, &retval, /* param_count */ 5, args, /* named_params */ NULL); + ch->in_callback = false; + + if (!Z_ISUNDEF(retval)) { + _php_curl_verify_handlers(ch, /* reporterror */ true); + if (Z_TYPE(retval) == IS_LONG) { + zend_long retval_long = Z_LVAL(retval); + if (retval_long == CURL_PREREQFUNC_OK || retval_long == CURL_PREREQFUNC_ABORT) { + rval = retval_long; + } else { + zend_value_error("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT"); + } + } else { + zend_type_error("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT"); + } + } + + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[2]); + + return rval; +} +#endif + #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key, size_t keylen) { @@ -1037,6 +1096,9 @@ void init_curl_handle(php_curl *ch) ch->handlers.progress = empty_fcall_info_cache; ch->handlers.xferinfo = empty_fcall_info_cache; ch->handlers.fnmatch = empty_fcall_info_cache; +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + ch->handlers.prereq = empty_fcall_info_cache; +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ ch->handlers.sshhostkey = empty_fcall_info_cache; #endif @@ -1210,6 +1272,9 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress); php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo); php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch); +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + php_curl_copy_fcc_with_option(ch, CURLOPT_PREREQDATA, &ch->handlers.prereq, &source->handlers.prereq); +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ php_curl_copy_fcc_with_option(ch, CURLOPT_SSH_HOSTKEYDATA, &ch->handlers.sshhostkey, &source->handlers.sshhostkey); #endif @@ -1570,6 +1635,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PROGRESS, handlers.progress, curl_progress); HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_XFERINFO, handlers.xferinfo, curl_xferinfo); HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_FNMATCH_, handlers.fnmatch, curl_fnmatch); +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_PREREQ, handlers.prereq, curl_prereqfunction); +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ HANDLE_CURL_OPTION_CALLABLE(ch, CURLOPT_SSH_HOSTKEY, handlers.sshhostkey, curl_ssh_hostkeyfunction); #endif @@ -1728,6 +1796,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue #if LIBCURL_VERSION_NUM >= 0x075700 /* Available since 7.87.0 */ case CURLOPT_CA_CACHE_TIMEOUT: case CURLOPT_QUICK_EXIT: +#endif +#if LIBCURL_VERSION_NUM >= 0x080900 /* Available since 8.9.0 */ + case CURLOPT_TCP_KEEPCNT: #endif lval = zval_get_long(zvalue); if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) && @@ -2733,6 +2804,11 @@ static void curl_free_obj(zend_object *object) if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) { zend_fcc_dtor(&ch->handlers.fnmatch); } +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + zend_fcc_dtor(&ch->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) { zend_fcc_dtor(&ch->handlers.sshhostkey); @@ -2811,7 +2887,11 @@ static void _php_curl_reset_handlers(php_curl *ch) if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) { zend_fcc_dtor(&ch->handlers.fnmatch); } - +#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */ + if (ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { + zend_fcc_dtor(&ch->handlers.prereq); + } +#endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) { zend_fcc_dtor(&ch->handlers.sshhostkey); diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 3c453edd4500c..275de581ae106 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -187,7 +187,12 @@ PHP_FUNCTION(curl_multi_select) mh = Z_CURL_MULTI_P(z_mh); - error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds); + if (!(timeout >= 0.0 && timeout <= ((double)INT_MAX / 1000.0))) { + zend_argument_value_error(2, "must be between 0 and %d", (int)ceilf((double)INT_MAX / 1000)); + RETURN_THROWS(); + } + + error = curl_multi_wait(mh->multi, NULL, 0, (int) (timeout * 1000.0), &numfds); if (CURLM_OK != error) { SAVE_CURLM_ERROR(mh, error); RETURN_LONG(-1); diff --git a/ext/curl/sync-constants.php b/ext/curl/sync-constants.php index d827de5fc97e3..8f35f7b05fa38 100755 --- a/ext/curl/sync-constants.php +++ b/ext/curl/sync-constants.php @@ -17,6 +17,7 @@ const IGNORED_CURL_CONSTANTS = [ 'CURLOPT_PROGRESSDATA', 'CURLOPT_XFERINFODATA', + 'CURLOPT_PREREQDATA', ]; const IGNORED_PHP_CONSTANTS = [ diff --git a/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt new file mode 100644 index 0000000000000..d11e29f078c09 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_PREREQFUNCTION.phpt @@ -0,0 +1,182 @@ +--TEST-- +Curl option CURLOPT_PREREQFUNCTION +--EXTENSIONS-- +curl +filter +--SKIPIF-- += 7.80.0"); +?> +--FILE-- +getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid type\n"; +curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) { + return 'this should be an integer'; +}); +try { + curl_exec($ch); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid value\n"; +curl_setopt($ch, CURLOPT_PREREQFUNCTION, function() use ($port) { + return 42; +}); +try { + curl_exec($ch); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid option value\n"; +try { + curl_setopt($ch, CURLOPT_PREREQFUNCTION, 42); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with invalid option callback\n"; +try { + curl_setopt($ch, CURLOPT_PREREQFUNCTION, 'function_does_not_exist'); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "\nTesting with null as the callback\n"; +var_dump(curl_setopt($ch, CURLOPT_PREREQFUNCTION, null)); +var_dump(curl_exec($ch)); +var_dump(curl_error($ch)); +var_dump(curl_errno($ch)); + +echo "\nDone"; +?> +--EXPECT-- +int(20312) +int(0) +int(1) + +Testing with CURL_PREREQFUNC_ABORT +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +string(41) "operation aborted by pre-request callback" +int(42) + +Testing with CURL_PREREQFUNC_OK +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +int(0) + +Testing with curl_copy_handle +string(8) "callback" +int(5) +string(10) "CurlHandle" +bool(true) +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +int(0) + +Testing with no return type +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid type +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid value +The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT + +Testing with invalid option value +curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, no array or string given + +Testing with invalid option callback +curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PREREQFUNCTION, function "function_does_not_exist" not found or invalid function name + +Testing with null as the callback +bool(true) +string(0) "" +string(0) "" +int(0) + +Done diff --git a/ext/curl/tests/gh15547.phpt b/ext/curl/tests/gh15547.phpt new file mode 100644 index 0000000000000..cee3f00cdb9f8 --- /dev/null +++ b/ext/curl/tests/gh15547.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-15547 - curl_multi_select overflow on timeout argument +--EXTENSIONS-- +curl +--FILE-- +getMessage() . PHP_EOL; +} +curl_multi_close($mh); +$mh = curl_multi_init(); +try { + curl_multi_select($mh, 2500000); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +curl_multi_close($mh); +$mh = curl_multi_init(); +var_dump(curl_multi_select($mh, 1000000)); +?> +--EXPECTF-- +curl_multi_select(): Argument #2 ($timeout) must be between %d and %d +curl_multi_select(): Argument #2 ($timeout) must be between %d and %d +int(0) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index bfff54c2b6d23..1609b7c510ff2 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1578,11 +1578,15 @@ static zend_result date_period_it_has_more(zend_object_iterator *iter) php_period_obj *object = Z_PHPPERIOD_P(&iterator->intern.data); if (object->end) { - if (object->include_end_date) { - return object->current->sse <= object->end->sse ? SUCCESS : FAILURE; - } else { - return object->current->sse < object->end->sse ? SUCCESS : FAILURE; + if (object->current->sse == object->end->sse) { + if (object->include_end_date) { + return object->current->us <= object->end->us ? SUCCESS : FAILURE; + } else { + return object->current->us < object->end->us ? SUCCESS : FAILURE; + } } + + return object->current->sse < object->end->sse ? SUCCESS : FAILURE; } else { return (iterator->current_index < object->recurrences) ? SUCCESS : FAILURE; } diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 9f7fd234dc647..8f92080015f9e 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1011,7 +1011,7 @@ static zend_class_entry *register_class_DateTime(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTime", class_DateTime_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_DateTimeInterface); return class_entry; @@ -1022,7 +1022,7 @@ static zend_class_entry *register_class_DateTimeImmutable(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTimeImmutable", class_DateTimeImmutable_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_DateTimeInterface); return class_entry; @@ -1033,7 +1033,7 @@ static zend_class_entry *register_class_DateTimeZone(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateTimeZone", class_DateTimeZone_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_AFRICA_value; ZVAL_LONG(&const_AFRICA_value, PHP_DATE_TIMEZONE_GROUP_AFRICA); @@ -1127,7 +1127,7 @@ static zend_class_entry *register_class_DateInterval(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInterval", class_DateInterval_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -1137,7 +1137,7 @@ static zend_class_entry *register_class_DatePeriod(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DatePeriod", class_DatePeriod_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval const_EXCLUDE_START_DATE_value; @@ -1206,8 +1206,7 @@ static zend_class_entry *register_class_DateError(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateError", class_DateError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1217,8 +1216,7 @@ static zend_class_entry *register_class_DateObjectError(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateObjectError", class_DateObjectError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1228,8 +1226,7 @@ static zend_class_entry *register_class_DateRangeError(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateRangeError", class_DateRangeError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1239,8 +1236,7 @@ static zend_class_entry *register_class_DateException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateException", class_DateException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1250,8 +1246,7 @@ static zend_class_entry *register_class_DateInvalidTimeZoneException(zend_class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInvalidTimeZoneException", class_DateInvalidTimeZoneException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1261,8 +1256,7 @@ static zend_class_entry *register_class_DateInvalidOperationException(zend_class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateInvalidOperationException", class_DateInvalidOperationException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1272,8 +1266,7 @@ static zend_class_entry *register_class_DateMalformedStringException(zend_class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedStringException", class_DateMalformedStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1283,8 +1276,7 @@ static zend_class_entry *register_class_DateMalformedIntervalStringException(zen zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedIntervalStringException", class_DateMalformedIntervalStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -1294,8 +1286,7 @@ static zend_class_entry *register_class_DateMalformedPeriodStringException(zend_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DateMalformedPeriodStringException", class_DateMalformedPeriodStringException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DateException); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DateException, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } diff --git a/ext/date/tests/date_period_include_end.phpt b/ext/date/tests/date_period_include_end.phpt index c96e279465367..17a059e9dceb9 100644 --- a/ext/date/tests/date_period_include_end.phpt +++ b/ext/date/tests/date_period_include_end.phpt @@ -16,4 +16,3 @@ foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) a 2010-06-08 2010-06-09 2010-06-10 - diff --git a/ext/date/tests/date_period_microseconds.phpt b/ext/date/tests/date_period_microseconds.phpt new file mode 100644 index 0000000000000..e2329acc94ae5 --- /dev/null +++ b/ext/date/tests/date_period_microseconds.phpt @@ -0,0 +1,51 @@ +--TEST-- +DatePeriod: take microseconds into account +--FILE-- +format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (exclusive)\n"; +foreach (new DatePeriod($start, $interval, $end) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (inclusive)\n"; +foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +$end = new DateTime('2010-06-10T01:02:03.456790'); +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (exclusive)\n"; +foreach (new DatePeriod($start, $interval, $end) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +$end = new DateTime('2010-06-10T01:02:03.456788'); +echo "from " . $start->format('Y-m-d H:i:s.u') . " to " . $end->format('Y-m-d H:i:s.u') . " (inclusive)\n"; +foreach (new DatePeriod($start, $interval, $end, DatePeriod::INCLUDE_END_DATE) as $day) { + echo $day->format('Y-m-d H:i:s.u') . "\n"; +} + +?> +--EXPECT-- +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456789 (exclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456789 (inclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +2010-06-10 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456790 (exclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 +2010-06-10 01:02:03.456789 +from 2010-06-07 01:02:03.456789 to 2010-06-10 01:02:03.456788 (inclusive) +2010-06-07 01:02:03.456789 +2010-06-08 01:02:03.456789 +2010-06-09 01:02:03.456789 diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 index 040b826fa0478..1a977152bd02a 100644 --- a/ext/dba/config.m4 +++ b/ext/dba/config.m4 @@ -1,8 +1,16 @@ +dnl +dnl PHP_DBA_STD_BEGIN +dnl dnl Suppose we need FlatFile if no support or only CDB is used. -AC_DEFUN([PHP_DBA_STD_BEGIN],[ - unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT -]) +dnl +AC_DEFUN([PHP_DBA_STD_BEGIN], + [unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT]) +dnl +dnl PHP_TEMP_LDFLAGS(ldflags, libs) +dnl +dnl Save and restore linker flags. +dnl AC_DEFUN([PHP_TEMP_LDFLAGS],[ old_LDFLAGS=$LDFLAGS LDFLAGS="$1 $LDFLAGS" @@ -13,32 +21,45 @@ AC_DEFUN([PHP_TEMP_LDFLAGS],[ LIBS=$old_LIBS ]) -dnl Assign INCLUDE/LFLAGS from PREFIX +dnl +dnl PHP_DBA_STD_ASSIGN +dnl +dnl Assign INCLUDE/LFLAGS from PREFIX. +dnl AC_DEFUN([PHP_DBA_STD_ASSIGN],[ if test -n "$THIS_PREFIX" && test "$THIS_PREFIX" != "/usr"; then THIS_LFLAGS=$THIS_PREFIX/$PHP_LIBDIR fi ]) -dnl Standard check +dnl +dnl PHP_DBA_STD_CHECK +dnl +dnl Check if includes and libraries are set. +dnl AC_DEFUN([PHP_DBA_STD_CHECK],[ THIS_RESULT=yes - if test -z "$THIS_INCLUDE"; then - AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) - fi - if test -z "$THIS_LIBS"; then - AC_MSG_ERROR([DBA: Could not find necessary library.]) - fi + AS_VAR_IF([THIS_INCLUDE],, + [AC_MSG_ERROR([DBA: Could not find necessary header file(s).])]) + AS_VAR_IF([THIS_LIBS],, + [AC_MSG_ERROR([DBA: Could not find necessary library.])]) ]) -dnl Attach THIS_x to DBA_x +dnl +dnl PHP_DBA_STD_ATTACH +dnl +dnl Attach THIS_x to DBA_x. +dnl AC_DEFUN([PHP_DBA_STD_ATTACH],[ PHP_ADD_LIBRARY_WITH_PATH([$THIS_LIBS], [$THIS_LFLAGS], [DBA_SHARED_LIBADD]) unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX ]) -dnl Print the result message -dnl parameters(name [, full name [, empty or error message]]) +dnl +dnl PHP_DBA_STD_RESULT(name [, full name [, empty or error message]]) +dnl +dnl Print the result message. +dnl AC_DEFUN([PHP_DBA_STD_RESULT],[ THIS_NAME=[]translit($1,a-z0-9-,A-Z0-9_) if test -n "$2"; then @@ -167,14 +188,15 @@ if test "$PHP_QDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(qdbm) +PHP_DBA_STD_RESULT([qdbm]) dnl GDBM if test "$PHP_GDBM" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_QDBM" = "1"; then - PHP_DBA_STD_RESULT(gdbm, gdbm, [You cannot combine --with-gdbm with --with-qdbm]) - fi + AS_VAR_IF([HAVE_QDBM], [1], + [PHP_DBA_STD_RESULT([gdbm], + [gdbm], + [You cannot combine --with-gdbm with --with-qdbm])]) for i in $PHP_GDBM /usr/local /usr; do if test -f "$i/include/gdbm.h"; then THIS_PREFIX=$i @@ -197,7 +219,7 @@ if test "$PHP_GDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(gdbm) +PHP_DBA_STD_RESULT([gdbm]) dnl NDBM if test "$PHP_NDBM" != "no"; then @@ -233,7 +255,7 @@ if test "$PHP_NDBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(ndbm) +PHP_DBA_STD_RESULT([ndbm]) dnl TCADB if test "$PHP_TCADB" != "no"; then @@ -266,7 +288,7 @@ if test "$PHP_TCADB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(tcadb) +PHP_DBA_STD_RESULT([tcadb]) dnl LMDB if test "$PHP_LMDB" != "no"; then @@ -299,24 +321,23 @@ if test "$PHP_LMDB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(lmdb) +PHP_DBA_STD_RESULT([lmdb]) -dnl Berkeley specific (library and version test) -dnl parameters(version, library list, function) +dnl +dnl PHP_DBA_DB_CHECK(version, library list, function) +dnl +dnl Berkeley specific (library and version test). +dnl AC_DEFUN([PHP_DBA_DB_CHECK],[ - if test -z "$THIS_INCLUDE"; then - AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) - fi + AS_VAR_IF([THIS_INCLUDE],, + [AC_MSG_ERROR([DBA: Could not find necessary header file(s).])]) for LIB in $2; do if test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.a || test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.$SHLIB_SUFFIX_NAME; then lib_found=""; - PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$LIB,[ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include "$THIS_INCLUDE" - ]],[[ - $3; - ]])],[ - AC_EGREP_CPP(yes,[ + PHP_TEMP_LDFLAGS([-L$THIS_PREFIX/$PHP_LIBDIR], [-l$LIB], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$THIS_INCLUDE"], + [$3;])], + [AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR == $1 || ($1 == 4 && DB_VERSION_MAJOR == 5) yes @@ -324,45 +345,41 @@ AC_DEFUN([PHP_DBA_DB_CHECK],[ ],[ THIS_LIBS=$LIB lib_found=1 - ]) - ],[]) - ]) + ])], + [])]) if test -n "$lib_found"; then lib_found=""; break; fi fi done - if test -z "$THIS_LIBS"; then - AC_MSG_CHECKING([for DB$1 major version]) - AC_MSG_ERROR([Header contains different version]) - fi + + AS_VAR_IF([THIS_LIBS],, [AC_MSG_FAILURE(m4_text_wrap([ + DB$1 major version check failed: header contains different version + ]))]) + if test "$1" = "4"; then AC_MSG_CHECKING([for DB4 minor version and patch level]) - AC_EGREP_CPP(yes,[ + AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR != 1) || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1 && DB_VERSION_PATCH >= 25) yes #endif - ],[ - AC_MSG_RESULT([ok]) - ],[ - AC_MSG_ERROR([Version 4.1 requires patch level 25]) - ]) + ], + [AC_MSG_RESULT([ok])], + [AC_MSG_ERROR([Version 4.1 requires patch level 25])]) fi - if test "$ext_shared" = "yes"; then + AS_VAR_IF([ext_shared], [yes], [ AC_MSG_CHECKING([if dba can be used as shared extension]) - AC_EGREP_CPP(yes,[ + AC_EGREP_CPP([yes], [ #include "$THIS_INCLUDE" #if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) yes #endif - ],[ - AC_MSG_RESULT([yes]) - ],[ - AC_MSG_ERROR([At least version 3.3 is required]) - ]) - fi + ], + [AC_MSG_RESULT([yes])], + [AC_MSG_ERROR([At least version 3.3 is required])]) + ]) if test -n "$THIS_LIBS"; then AC_DEFINE_UNQUOTED([DBA_DB$1], [1], [Define to 1 if the dba extension uses the Berkeley DB version $1 (DB$1) @@ -444,14 +461,15 @@ if test "$PHP_DB4" != "no"; then done PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db4,Berkeley DB4) +PHP_DBA_STD_RESULT([db4], [Berkeley DB4]) dnl DB3 if test "$PHP_DB3" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_DB4" = "1"; then - PHP_DBA_STD_RESULT(db3, Berkeley DB3, [You cannot combine --with-db3 with --with-db4]) - fi + AS_VAR_IF([HAVE_DB4], [1], + [PHP_DBA_STD_RESULT([db3], + [Berkeley DB3], + [You cannot combine --with-db3 with --with-db4])]) for i in $PHP_DB3 /usr/local/BerkeleyDB.3.3 /usr/local/BerkeleyDB.3.2 /usr/local/BerkeleyDB.3.1 /usr/local/BerkeleyDB.3.0 /usr/local /usr; do if test -f "$i/db3/db.h"; then THIS_PREFIX=$i @@ -477,13 +495,15 @@ if test "$PHP_DB3" != "no"; then done PHP_DBA_DB_CHECK(3, db-3.3 db-3.2 db-3.1 db-3.0 db-3 db3 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db3,Berkeley DB3) +PHP_DBA_STD_RESULT([db3], [Berkeley DB3]) dnl DB2 if test "$PHP_DB2" != "no"; then PHP_DBA_STD_BEGIN if test "$HAVE_DB3" = "1" || test "$HAVE_DB4" = "1"; then - PHP_DBA_STD_RESULT(db2, Berkeley DB2, [You cannot combine --with-db2 with --with-db3 or --with-db4]) + PHP_DBA_STD_RESULT([db2], + [Berkeley DB2], + [You cannot combine --with-db2 with --with-db3 or --with-db4]) fi for i in $PHP_DB2 $PHP_DB2/BerkeleyDB /usr/BerkeleyDB /usr/local /usr; do if test -f "$i/db2/db.h"; then @@ -510,7 +530,7 @@ if test "$PHP_DB2" != "no"; then done PHP_DBA_DB_CHECK(2, db-2 db2 db, [(void)db_appinit("", NULL, (DB_ENV*)0, 0)]) fi -PHP_DBA_STD_RESULT(db2, Berkeley DB2) +PHP_DBA_STD_RESULT([db2], [Berkeley DB2]) dnl DB1 if test "$PHP_DB1" != "no"; then @@ -562,35 +582,31 @@ if test "$PHP_DB1" != "no"; then AC_MSG_CHECKING([for DB1 in header]) AC_MSG_RESULT([$THIS_INCLUDE]) if test -n "$THIS_INCLUDE"; then - PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$THIS_LIBS,[ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include "$THIS_INCLUDE" - ]],[[ - DB * dbp = dbopen("", 0, 0, DB_HASH, 0); - ]])],[ - AC_DEFINE_UNQUOTED([DB1_INCLUDE_FILE], ["$THIS_INCLUDE"], + PHP_TEMP_LDFLAGS([-L$THIS_PREFIX/$PHP_LIBDIR], [-l$THIS_LIBS], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$THIS_INCLUDE"], + [DB * dbp = dbopen("", 0, 0, DB_HASH, 0);])], + [AC_DEFINE_UNQUOTED([DB1_INCLUDE_FILE], ["$THIS_INCLUDE"], [The DB1 handler header file.]) AC_DEFINE([DBA_DB1], [1], [Define to 1 if the dba extension uses the Berkeley DB version 1 (DB1) handler.]) THIS_RESULT=yes - ],[ - THIS_RESULT=no - ]) - ]) + ], + [THIS_RESULT=no])]) fi PHP_DBA_STD_ASSIGN PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(db1, DB1) +PHP_DBA_STD_RESULT([db1], [DB1]) dnl DBM if test "$PHP_DBM" != "no"; then PHP_DBA_STD_BEGIN - if test "$HAVE_QDBM" = "1"; then - PHP_DBA_STD_RESULT(dbm, dbm, [You cannot combine --with-dbm with --with-qdbm]) - fi + AS_VAR_IF([HAVE_QDBM], [1], + [PHP_DBA_STD_RESULT([dbm], + [dbm], + [You cannot combine --with-dbm with --with-qdbm])]) for i in $PHP_DBM /usr/local /usr; do if test -f "$i/include/dbm.h"; then THIS_PREFIX=$i @@ -632,7 +648,7 @@ if test "$PHP_DBM" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(dbm) +PHP_DBA_STD_RESULT([dbm]) dnl Bundled modules that should be enabled by default if any other option is dnl enabled @@ -697,7 +713,7 @@ elif test "$PHP_CDB" != "no"; then PHP_DBA_STD_CHECK PHP_DBA_STD_ATTACH fi -PHP_DBA_STD_RESULT(cdb) +PHP_DBA_STD_RESULT([cdb]) dnl INIFILE if test "$PHP_INIFILE" != "no"; then @@ -706,7 +722,7 @@ if test "$PHP_INIFILE" != "no"; then ini_sources="libinifile/inifile.c" THIS_RESULT="builtin" fi -PHP_DBA_STD_RESULT(inifile, [INI File]) +PHP_DBA_STD_RESULT([inifile], [INI File]) dnl FLATFILE if test "$PHP_FLATFILE" != "no"; then @@ -715,18 +731,17 @@ if test "$PHP_FLATFILE" != "no"; then flat_sources="libflatfile/flatfile.c" THIS_RESULT="builtin" fi -PHP_DBA_STD_RESULT(FlatFile, FlatFile) +PHP_DBA_STD_RESULT([FlatFile], [FlatFile]) dnl dnl Extension setup dnl AC_MSG_CHECKING([whether to enable DBA interface]) -if test "$HAVE_DBA" = "1"; then - if test "$ext_shared" = "yes"; then - AC_MSG_RESULT([yes, shared]) - else - AC_MSG_RESULT([yes]) - fi +AS_VAR_IF([HAVE_DBA], [1], [ + AS_VAR_IF([ext_shared], [yes], + [AC_MSG_RESULT([yes, shared])], + [AC_MSG_RESULT([yes])]) + AC_DEFINE([HAVE_DBA], [1], [Define to 1 if the PHP extension 'dba' is available.]) PHP_NEW_EXTENSION([dba], m4_normalize([ @@ -754,6 +769,5 @@ if test "$HAVE_DBA" = "1"; then PHP_ADD_BUILD_DIR([$ext_builddir/libflatfile]) PHP_ADD_BUILD_DIR([$ext_builddir/libinifile]) PHP_SUBST([DBA_SHARED_LIBADD]) -else - AC_MSG_RESULT([no]) -fi +], +[AC_MSG_RESULT([no])]) diff --git a/ext/dba/dba.c b/ext/dba/dba.c index b1876f75f345e..c0baf2780dcb7 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -547,15 +547,15 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) } if (ZSTR_LEN(path) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(mode) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } if (handler_str && ZSTR_LEN(handler_str) == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } // TODO Check Value for permission @@ -639,11 +639,6 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent) bool is_lock_ignored = false; // bool is_file_lock = false; - if (ZSTR_LEN(mode) == 0) { - zend_argument_value_error(2, "cannot be empty"); - efree(resource_key); - RETURN_THROWS(); - } if (ZSTR_LEN(mode) > 3) { zend_argument_value_error(2, "must be at most 3 characters"); efree(resource_key); @@ -1103,9 +1098,6 @@ PHP_FUNCTION(dba_key_split) char *key, *name; size_t key_len; - if (ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &zkey) == SUCCESS) { if (Z_TYPE_P(zkey) == IS_NULL || (Z_TYPE_P(zkey) == IS_FALSE)) { php_error_docref(NULL, E_DEPRECATED, "Passing false or null is deprecated since 8.4"); diff --git a/ext/dba/dba_arginfo.h b/ext/dba/dba_arginfo.h index 0d703289de1a8..15b30978fcbc9 100644 --- a/ext/dba/dba_arginfo.h +++ b/ext/dba/dba_arginfo.h @@ -114,8 +114,7 @@ static zend_class_entry *register_class_Dba_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dba", "Connection", class_Dba_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/dba/tests/value_errors_open.phpt b/ext/dba/tests/value_errors_open.phpt index 9bbb0b00a94d0..ee995fe5b8d66 100644 --- a/ext/dba/tests/value_errors_open.phpt +++ b/ext/dba/tests/value_errors_open.phpt @@ -121,9 +121,9 @@ object(Dba\Connection)#%d (%d) { Warning: dba_open(): Handler "bogus" is not available in %s on line %d bool(false) -dba_open(): Argument #1 ($path) cannot be empty -dba_open(): Argument #2 ($mode) cannot be empty -dba_open(): Argument #3 ($handler) cannot be empty +dba_open(): Argument #1 ($path) must not be empty +dba_open(): Argument #2 ($mode) must not be empty +dba_open(): Argument #3 ($handler) must not be empty dba_open(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n" dba_open(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t" dba_open(): Argument #2 ($mode) third character must be "t" @@ -133,9 +133,9 @@ dba_open(): Argument #5 ($map_size) must be greater than or equal to 0 Warning: dba_popen(): Handler "bogus" is not available in %s on line %d bool(false) -dba_popen(): Argument #1 ($path) cannot be empty -dba_popen(): Argument #2 ($mode) cannot be empty -dba_popen(): Argument #3 ($handler) cannot be empty +dba_popen(): Argument #1 ($path) must not be empty +dba_popen(): Argument #2 ($mode) must not be empty +dba_popen(): Argument #3 ($handler) must not be empty dba_popen(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n" dba_popen(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t" dba_popen(): Argument #2 ($mode) third character must be "t" diff --git a/ext/dom/document.c b/ext/dom/document.c index 6e64fe497b025..9650d0902909a 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -107,10 +107,7 @@ zend_result dom_document_encoding_read(dom_object *obj, zval *retval) zend_result dom_document_actual_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMDocument::$actualEncoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMDocument::$actualEncoding is deprecated"); return dom_document_encoding_read(obj, retval); } @@ -419,10 +416,7 @@ Since: DOM Level 3 */ zend_result dom_document_config_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMDocument::$config is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMDocument::$config is deprecated"); ZVAL_NULL(retval); return SUCCESS; @@ -1525,7 +1519,7 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZEND_SIZE_T_INT_OVFL(source_len)) { @@ -1579,7 +1573,7 @@ PHP_METHOD(DOMDocument, save) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1883,7 +1877,7 @@ static void dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1992,7 +1986,7 @@ static void dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2085,7 +2079,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ } if (!source_len) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2162,7 +2156,7 @@ PHP_METHOD(DOMDocument, saveHTMLFile) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index a89da6d5431c9..378e841137f3f 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -164,13 +164,15 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ xmlNodePtr curnode = NULL; php_dom_iterator *iterator = (php_dom_iterator *)iter; + if (Z_ISUNDEF(iterator->curobj)) { + return; + } + dom_object *intern = Z_DOMOBJ_P(&iterator->curobj); zval *object = &iterator->intern.data; dom_object *nnmap = Z_DOMOBJ_P(object); dom_nnodemap_object *objmap = nnmap->ptr; - dom_object *intern = Z_DOMOBJ_P(&iterator->curobj); - if (intern != NULL && intern->ptr != NULL) { if (objmap->nodetype != XML_ENTITY_NODE && objmap->nodetype != XML_NOTATION_NODE) { diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index 7997dcfed1203..0737be5fa5c9f 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -64,7 +64,7 @@ PHP_METHOD(DOMImplementation, createDocumentType) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/dom/element.c b/ext/dom/element.c index a1529a0d3bb9b..b449555983021 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -182,7 +182,7 @@ URL: https://dom.spec.whatwg.org/#dom-element-classlist */ zend_result dom_element_class_list_read(dom_object *obj, zval *retval) { - const uint32_t PROP_INDEX = 20; + const uint32_t PROP_INDEX = 0; #if ZEND_DEBUG zend_string *class_list_str = ZSTR_INIT_LITERAL("classList", false); @@ -411,7 +411,7 @@ PHP_METHOD(DOMElement, setAttribute) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -903,7 +903,7 @@ PHP_METHOD(DOMElement, getAttributeNS) static void dom_set_attribute_ns_legacy(dom_object *intern, xmlNodePtr elemp, char *uri, size_t uri_len, char *name, size_t name_len, const char *value) { if (name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); return; } diff --git a/ext/dom/entity.c b/ext/dom/entity.c index 53871cb731f28..3cfcbb5ae8084 100644 --- a/ext/dom/entity.c +++ b/ext/dom/entity.c @@ -104,10 +104,7 @@ Since: DOM Level 3 */ zend_result dom_entity_actual_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$actualEncoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$actualEncoding is deprecated"); ZVAL_NULL(retval); return SUCCESS; @@ -122,10 +119,7 @@ Since: DOM Level 3 */ zend_result dom_entity_encoding_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$encoding is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$encoding is deprecated"); ZVAL_NULL(retval); return SUCCESS; @@ -140,10 +134,7 @@ Since: DOM Level 3 */ zend_result dom_entity_version_read(dom_object *obj, zval *retval) { - zend_error(E_DEPRECATED, "Property DOMEntity::$version is deprecated"); - if (UNEXPECTED(EG(exception))) { - return FAILURE; - } + PHP_DOM_DEPRECATED_PROPERTY("Property DOMEntity::$version is deprecated"); ZVAL_NULL(retval); return SUCCESS; diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c index c87d3480a5f3c..f0048aa4aae89 100644 --- a/ext/dom/html5_serializer.c +++ b/ext/dom/html5_serializer.c @@ -42,7 +42,9 @@ static zend_result dom_html5_serialize_doctype(dom_html5_serialize_context *ctx, static zend_result dom_html5_serialize_comment(dom_html5_serialize_context *ctx, const xmlNode *node) { TRY(ctx->write_string_len(ctx->application_data, "", strlen("-->")); } @@ -131,8 +133,12 @@ static zend_result dom_html5_escape_string(dom_html5_serialize_context *ctx, con static zend_result dom_html5_serialize_text_node(dom_html5_serialize_context *ctx, const xmlNode *node) { - if (node->parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(node->parent, php_dom_ns_is_html_magic_token)) { - const xmlNode *parent = node->parent; + if (!node->content) { + return SUCCESS; + } + + const xmlNode *parent = node->parent; + if (parent != NULL && parent->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(parent, php_dom_ns_is_html_magic_token)) { size_t name_length = strlen((const char *) parent->name); /* Spec tells us to only emit noscript content as-is if scripting is enabled. * However, the user agent (PHP) does not support (JS) scripting. diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 44da720b66479..1d606e814554f 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -83,7 +83,7 @@ typedef struct dom_decoding_encoding_ctx { /* https://dom.spec.whatwg.org/#dom-document-implementation */ zend_result dom_modern_document_implementation_read(dom_object *obj, zval *retval) { - const uint32_t PROP_INDEX = 14; + const uint32_t PROP_INDEX = 0; #if ZEND_DEBUG zend_string *implementation_str = ZSTR_INIT_LITERAL("implementation", false); @@ -1283,7 +1283,7 @@ PHP_METHOD(Dom_HTMLDocument, saveHtmlFile) } if (file_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1467,7 +1467,7 @@ static zend_string *dom_get_child_text_content(const xmlNode *node) const xmlNode *text = node->children; while (text != NULL) { - if (text->type == XML_TEXT_NODE || text->type == XML_CDATA_SECTION_NODE) { + if ((text->type == XML_TEXT_NODE || text->type == XML_CDATA_SECTION_NODE) && text->content != NULL) { smart_str_appends(&content, (const char *) text->content); } text = text->next; diff --git a/ext/dom/lexbor/lexbor/css/selectors/selector.h b/ext/dom/lexbor/lexbor/css/selectors/selector.h index e87f5cd590578..52dbabc7ba5ce 100644 --- a/ext/dom/lexbor/lexbor/css/selectors/selector.h +++ b/ext/dom/lexbor/lexbor/css/selectors/selector.h @@ -110,7 +110,7 @@ typedef uint32_t lxb_css_selector_specificity_t; ((sp) & ~((((uint32_t) 1 << 9) - 1) << (n))) #define LXB_CSS_SELECTOR_SPECIFICITY_MASK \ - ((((uint32_t) 1 << 31) - 1) << (9)) + ((((uint32_t) 1 << (32 - 9)) - 1) << (9)) #define lxb_css_selector_sp_i(sp) ((sp) >> 28) diff --git a/ext/dom/lexbor/lexbor/dom/interfaces/element.c b/ext/dom/lexbor/lexbor/dom/interfaces/element.c index 6bbcf9252bbcb..157beb9cf7be6 100644 --- a/ext/dom/lexbor/lexbor/dom/interfaces/element.c +++ b/ext/dom/lexbor/lexbor/dom/interfaces/element.c @@ -651,12 +651,10 @@ lxb_dom_element_qualified_name(lxb_dom_element_t *element, size_t *len) const lxb_tag_data_t *data; if (element->qualified_name != 0) { - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->qualified_name); + data = lxb_tag_data_by_id(element->qualified_name); } else { - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->node.local_name); + data = lxb_tag_data_by_id(element->node.local_name); } if (len != NULL) { @@ -723,8 +721,7 @@ lxb_dom_element_local_name(lxb_dom_element_t *element, size_t *len) { const lxb_tag_data_t *data; - data = lxb_tag_data_by_id(element->node.owner_document->tags, - element->node.local_name); + data = lxb_tag_data_by_id(element->node.local_name); if (data == NULL) { if (len != NULL) { *len = 0; diff --git a/ext/dom/lexbor/lexbor/dom/interfaces/node.c b/ext/dom/lexbor/lexbor/dom/interfaces/node.c index 702d1a802c16d..934b350858258 100644 --- a/ext/dom/lexbor/lexbor/dom/interfaces/node.c +++ b/ext/dom/lexbor/lexbor/dom/interfaces/node.c @@ -184,7 +184,7 @@ lxb_dom_node_interface_copy(lxb_dom_node_t *dst, dst->local_name = src->local_name; } else { - tag = lxb_tag_data_by_id(from->tags, src->local_name); + tag = lxb_tag_data_by_id(src->local_name); if (tag == NULL) { return LXB_STATUS_ERROR_NOT_EXISTS; } diff --git a/ext/dom/lexbor/lexbor/html/parser.c b/ext/dom/lexbor/lexbor/html/parser.c index 8ad05beb565de..caca15e4be26b 100644 --- a/ext/dom/lexbor/lexbor/html/parser.c +++ b/ext/dom/lexbor/lexbor/html/parser.c @@ -202,7 +202,7 @@ lxb_html_parse_fragment_chunk_begin(lxb_html_parser_t *parser, } lxb_html_tokenizer_set_state_by_tag(parser->tkz, doc->scripting, tag_id, ns); - lxb_html_tokenizer_tmp_tag_id_set(parser->tkz, LXB_TAG__UNDEF); + lxb_html_tokenizer_tmp_tag_id_set(parser->tkz, LXB_TAG__UNDEF); parser->root = lxb_html_interface_create(new_doc, LXB_TAG_HTML, LXB_NS_HTML); if (parser->root == NULL) { diff --git a/ext/dom/lexbor/lexbor/tag/tag.c b/ext/dom/lexbor/lexbor/tag/tag.c index 05719570126d4..be5bb30dbb09e 100644 --- a/ext/dom/lexbor/lexbor/tag/tag.c +++ b/ext/dom/lexbor/lexbor/tag/tag.c @@ -60,7 +60,7 @@ lxb_tag_append_lower(lexbor_hash_t *hash, const lxb_char_t *name, size_t length) } const lxb_tag_data_t * -lxb_tag_data_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id) +lxb_tag_data_by_id(lxb_tag_id_t tag_id) { if (tag_id >= LXB_TAG__LAST_ENTRY) { if (tag_id == LXB_TAG__LAST_ENTRY) { @@ -121,16 +121,15 @@ lxb_tag_data_by_name_upper(lexbor_hash_t *hash, * No inline functions for ABI. */ const lxb_char_t * -lxb_tag_name_by_id_noi(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_by_id_noi(lxb_tag_id_t tag_id, size_t *len) { - return lxb_tag_name_by_id(hash, tag_id, len); + return lxb_tag_name_by_id(tag_id, len); } const lxb_char_t * -lxb_tag_name_upper_by_id_noi(lexbor_hash_t *hash, - lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_upper_by_id_noi(lxb_tag_id_t tag_id, size_t *len) { - return lxb_tag_name_upper_by_id(hash, tag_id, len); + return lxb_tag_name_upper_by_id(tag_id, len); } lxb_tag_id_t diff --git a/ext/dom/lexbor/lexbor/tag/tag.h b/ext/dom/lexbor/lexbor/tag/tag.h index 9e64a2fd242d9..33a515d20364d 100644 --- a/ext/dom/lexbor/lexbor/tag/tag.h +++ b/ext/dom/lexbor/lexbor/tag/tag.h @@ -29,7 +29,7 @@ lxb_tag_data_t; LXB_API const lxb_tag_data_t * -lxb_tag_data_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id); +lxb_tag_data_by_id(lxb_tag_id_t tag_id); LXB_API const lxb_tag_data_t * lxb_tag_data_by_name(lexbor_hash_t *hash, const lxb_char_t *name, size_t len); @@ -42,9 +42,9 @@ lxb_tag_data_by_name_upper(lexbor_hash_t *hash, * Inline functions */ lxb_inline const lxb_char_t * -lxb_tag_name_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_by_id(lxb_tag_id_t tag_id, size_t *len) { - const lxb_tag_data_t *data = lxb_tag_data_by_id(hash, tag_id); + const lxb_tag_data_t *data = lxb_tag_data_by_id(tag_id); if (data == NULL) { if (len != NULL) { *len = 0; @@ -61,9 +61,9 @@ lxb_tag_name_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) } lxb_inline const lxb_char_t * -lxb_tag_name_upper_by_id(lexbor_hash_t *hash, lxb_tag_id_t tag_id, size_t *len) +lxb_tag_name_upper_by_id(lxb_tag_id_t tag_id, size_t *len) { - const lxb_tag_data_t *data = lxb_tag_data_by_id(hash, tag_id); + const lxb_tag_data_t *data = lxb_tag_data_by_id(tag_id); if (data == NULL) { if (len != NULL) { *len = 0; @@ -101,12 +101,10 @@ lxb_tag_mraw(lexbor_hash_t *hash) * No inline functions for ABI. */ LXB_API const lxb_char_t * -lxb_tag_name_by_id_noi(lexbor_hash_t *hash, lxb_tag_id_t tag_id, - size_t *len); +lxb_tag_name_by_id_noi(lxb_tag_id_t tag_id, size_t *len); LXB_API const lxb_char_t * -lxb_tag_name_upper_by_id_noi(lexbor_hash_t *hash, - lxb_tag_id_t tag_id, size_t *len); +lxb_tag_name_upper_by_id_noi(lxb_tag_id_t tag_id, size_t *len); LXB_API lxb_tag_id_t lxb_tag_id_by_name_noi(lexbor_hash_t *hash, diff --git a/ext/dom/node.c b/ext/dom/node.c index 97c77b7665e88..57009a539a1cd 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -133,7 +133,6 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval) /* }}} */ /* {{{ nodeValue string -readonly=no URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080 Modern spec URL: https://dom.spec.whatwg.org/#dom-node-nodevalue Since: @@ -671,7 +670,6 @@ zend_result dom_node_base_uri_read(dom_object *obj, zval *retval) /* }}} */ /* {{{ textContent string -readonly=no URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent Modern spec URL: https://dom.spec.whatwg.org/#dom-node-textcontent Since: DOM Level 3 diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 81fd0a601f31c..e69a2cd20564e 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -203,6 +203,16 @@ static const libxml_doc_props default_doc_props = { .classmap = NULL, }; +ZEND_DECLARE_MODULE_GLOBALS(dom) + +static PHP_GINIT_FUNCTION(dom) +{ +#if defined(COMPILE_DL_DOM) && defined(ZTS) + ZEND_TSRMLS_CACHE_UPDATE(); +#endif + dom_globals->suppress_warnings = false; +} + /* {{{ dom_get_doc_props() */ dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document) { @@ -464,6 +474,8 @@ static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) / return debug_info; } + DOM_G(suppress_warnings) = true; + object_str = ZSTR_INIT_LITERAL("(object value omitted)", false); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(prop_handlers, string_key, entry) { @@ -486,6 +498,8 @@ static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) / zend_string_release_ex(object_str, false); + DOM_G(suppress_warnings) = false; + return debug_info; } /* }}} */ @@ -668,7 +682,11 @@ zend_module_entry dom_module_entry = { /* {{{ */ NULL, PHP_MINFO(dom), DOM_API_VERSION, /* Extension versionnumber */ - STANDARD_MODULE_PROPERTIES + PHP_MODULE_GLOBALS(dom), + PHP_GINIT(dom), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index c86fd2892e385..07137320baf01 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -300,6 +300,23 @@ static zend_always_inline const xmlChar *php_dom_get_content_or_empty(const xmlN return node->content ? node->content : BAD_CAST ""; } +#define PHP_DOM_DEPRECATED_PROPERTY(message) do { \ + if (EXPECTED(!DOM_G(suppress_warnings))) {\ + zend_error(E_DEPRECATED, message); \ + if (UNEXPECTED(EG(exception))) { \ + return FAILURE; \ + } \ + } \ +} while (0) + +ZEND_BEGIN_MODULE_GLOBALS(dom) + bool suppress_warnings; +ZEND_END_MODULE_GLOBALS(dom) + +ZEND_EXTERN_MODULE_GLOBALS(dom) + +#define DOM_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(dom, v) + PHP_MINIT_FUNCTION(dom); PHP_MSHUTDOWN_FUNCTION(dom); PHP_MINFO_FUNCTION(dom); diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index 48d28a3269618..0f7f748410420 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -234,22 +234,40 @@ class DOMDocumentType extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNamedNodeMap $entities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNamedNodeMap $notations; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $internalSubset; } @@ -298,55 +316,103 @@ class DOMNode public const int DOCUMENT_POSITION_CONTAINED_BY = 0x10; public const int DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; + /** @virtual */ public ?string $nodeValue; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $parentElement; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMNodeList $childNodes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $firstChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $lastChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $previousSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $nextSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNamedNodeMap $attributes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocument $ownerDocument; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; + /** @virtual */ public string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $baseURI; + /** @virtual */ public string $textContent; /** @return DOMNode|false */ @@ -415,34 +481,64 @@ public function __wakeup(): void {} class DOMNameSpaceNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $nodeValue; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocument $ownerDocument; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMNode $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $parentElement; /** @implementation-alias DOMNode::__sleep */ @@ -466,13 +562,22 @@ public function createDocument(?string $namespace = null, string $qualifiedName class DOMDocumentFragment extends DOMNode implements DOMParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; public function __construct() {} @@ -501,7 +606,10 @@ public function replaceChildren(...$nodes): void {} class DOMNodeList implements IteratorAggregate, Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @tentative-return-type */ @@ -515,15 +623,25 @@ public function item(int $index) {} class DOMCharacterData extends DOMNode implements DOMChildNode { + /** @virtual */ public string $data; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $nextElementSibling; /** @tentative-return-type */ @@ -565,19 +683,32 @@ public function after(...$nodes): void {} class DOMAttr extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ - public bool $specified = true; + /** + * @readonly + * @virtual + */ + public bool $specified; + /** @virtual */ public string $value; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $ownerElement; - /** @readonly */ - public mixed $schemaTypeInfo = null; + /** + * @readonly + * @virtual + */ + public mixed $schemaTypeInfo; public function __construct(string $name, string $value = "") {} @@ -587,29 +718,52 @@ public function isId(): bool {} class DOMElement extends DOMNode implements \DOMParentNode, \DOMChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $tagName; + /** @virtual */ public string $className; + /** @virtual */ public string $id; - /** @readonly */ - public mixed $schemaTypeInfo = null; + /** + * @readonly + * @virtual + */ + public mixed $schemaTypeInfo; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $nextElementSibling; public function __construct(string $qualifiedName, ?string $value = null, string $namespace = "") {} @@ -699,63 +853,99 @@ public function insertAdjacentText(string $where, string $data): void {} class DOMDocument extends DOMNode implements DOMParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMDocumentType $doctype; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMImplementation $implementation; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $documentElement; /** * @readonly * @deprecated + * @virtual */ public ?string $actualEncoding; + /** @virtual */ public ?string $encoding; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $xmlEncoding; + /** @virtual */ public bool $standalone; + /** @virtual */ public bool $xmlStandalone; + /** @virtual */ public ?string $version; + /** @virtual */ public ?string $xmlVersion; + /** @virtual */ public bool $strictErrorChecking; + /** @virtual */ public ?string $documentURI; /** * @readonly * @deprecated + * @virtual */ public mixed $config; + /** @virtual */ public bool $formatOutput; + /** @virtual */ public bool $validateOnParse; + /** @virtual */ public bool $resolveExternals; + /** @virtual */ public bool $preserveWhiteSpace; + /** @virtual */ public bool $recover; + /** @virtual */ public bool $substituteEntities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DOMElement $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; public function __construct(string $version = "1.0", string $encoding = "") {} @@ -891,7 +1081,10 @@ final class DOMException extends Exception class DOMText extends DOMCharacterData { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $wholeText; public function __construct(string $data = "") {} @@ -911,7 +1104,10 @@ public function splitText(int $offset) {} class DOMNamedNodeMap implements IteratorAggregate, Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @tentative-return-type */ @@ -931,32 +1127,44 @@ public function getIterator(): Iterator {} class DOMEntity extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $notationName; /** * @readonly * @deprecated + * @virtual */ - public ?string $actualEncoding = null; + public ?string $actualEncoding; /** * @readonly * @deprecated + * @virtual */ - public ?string $encoding = null; + public ?string $encoding; /** * @readonly * @deprecated + * @virtual */ - public ?string $version = null; + public ?string $version; } class DOMEntityReference extends DOMNode @@ -966,18 +1174,28 @@ public function __construct(string $name) {} class DOMNotation extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; } class DOMProcessingInstruction extends DOMNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $target; + /** @virtual */ public string $data; public function __construct(string $name, string $value = "") {} @@ -987,9 +1205,13 @@ public function __construct(string $name, string $value = "") {} /** @not-serializable */ class DOMXPath { - /** @readonly */ + /** + * @readonly + * @virtual + */ public DOMDocument $document; + /** @virtual */ public bool $registerNodeNamespaces; public function __construct(DOMDocument $document, bool $registerNodeNS = true) {} @@ -1135,39 +1357,77 @@ class Node { private final function __construct() {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $nodeType; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $nodeName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $baseURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public bool $isConnected; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Document $ownerDocument; /** @implementation-alias DOMNode::getRootNode */ public function getRootNode(array $options = []): Node {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $parentNode; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $parentElement; /** @implementation-alias DOMNode::hasChildNodes */ public function hasChildNodes(): bool {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public NodeList $childNodes; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $firstChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $lastChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $previousSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Node $nextSibling; + /** @virtual */ public ?string $nodeValue; + /** @virtual */ public ?string $textContent; /** @implementation-alias DOMNode::normalize */ public function normalize(): void {} @@ -1213,7 +1473,10 @@ public function __wakeup(): void {} class NodeList implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNodeList::count */ @@ -1228,7 +1491,10 @@ public function item(int $index): ?Node {} class NamedNodeMap implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNamedNodeMap::item */ @@ -1247,7 +1513,10 @@ public function getIterator(): \Iterator {} class DtdNamedNodeMap implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNamedNodeMap::item */ @@ -1266,7 +1535,10 @@ public function getIterator(): \Iterator {} class HTMLCollection implements \IteratorAggregate, \Countable { - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMNodeList::item */ @@ -1291,23 +1563,40 @@ enum AdjacentPosition : string class Element extends Node implements ParentNode, ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $tagName; + /** @virtual */ public string $id; + /** @virtual */ public string $className; /** @readonly */ public TokenList $classList; /** @implementation-alias DOMNode::hasAttributes */ public function hasAttributes(): bool {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public NamedNodeMap $attributes; /** @implementation-alias DOMElement::getAttributeNames */ public function getAttributeNames(): array {} @@ -1344,15 +1633,30 @@ public function getElementsByTagNameNS(?string $namespace, string $localName): H public function insertAdjacentElement(AdjacentPosition $where, Element $element): ?Element {} public function insertAdjacentText(AdjacentPosition $where, string $data): void {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $nextElementSibling; /** @implementation-alias DOMElement::setIdAttribute */ @@ -1381,8 +1685,10 @@ public function querySelectorAll(string $selectors): NodeList {} public function closest(string $selectors): ?Element {} public function matches(string $selectors): bool {} + /** @virtual */ public string $innerHTML; + /** @virtual */ public string $substitutedNodeValue; /** @return list */ @@ -1400,21 +1706,40 @@ class HTMLElement extends Element class Attr extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $namespaceURI; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $prefix; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $localName; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; + /** @virtual */ public string $value; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $ownerElement; - /** @readonly */ - public bool $specified = true; + /** + * @readonly + * @virtual + */ + public bool $specified; /** @implementation-alias DOMAttr::isId */ public function isId(): bool {} @@ -1425,13 +1750,23 @@ public function rename(?string $namespaceURI, string $qualifiedName): void {} class CharacterData extends Node implements ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $previousElementSibling; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $nextElementSibling; + /** @virtual */ public string $data; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; /** @implementation-alias DOMCharacterData::substringData */ public function substringData(int $offset, int $count): string {} @@ -1456,7 +1791,10 @@ class Text extends CharacterData /** @implementation-alias DOMText::splitText */ public function splitText(int $offset): Text {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $wholeText; } @@ -1464,7 +1802,10 @@ class CDATASection extends Text {} class ProcessingInstruction extends CharacterData { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $target; } @@ -1475,17 +1816,35 @@ class Comment extends CharacterData class DocumentType extends Node implements ChildNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $name; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DtdNamedNodeMap $entities; - /** @readonly */ + /** + * @readonly + * @virtual + */ public DtdNamedNodeMap $notations; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $internalSubset; /** @implementation-alias DOMElement::remove */ @@ -1500,11 +1859,20 @@ public function replaceWith(Node|string ...$nodes): void {} class DocumentFragment extends Node implements ParentNode { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; /** @implementation-alias DOMDocumentFragment::appendXML */ @@ -1524,11 +1892,20 @@ public function querySelectorAll(string $selectors): NodeList {} class Entity extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $systemId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?string $notationName; } @@ -1536,9 +1913,15 @@ class EntityReference extends Node {} class Notation extends Node { - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $publicId; - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $systemId; } @@ -1546,15 +1929,26 @@ abstract class Document extends Node implements ParentNode { /** @readonly */ public Implementation $implementation; + /** @virtual */ public string $URL; + /** @virtual */ public string $documentURI; + /** @virtual */ public string $characterSet; + /** @virtual */ public string $charset; + /** @virtual */ public string $inputEncoding; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?DocumentType $doctype; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $documentElement; /** @implementation-alias Dom\Element::getElementsByTagName */ public function getElementsByTagName(string $qualifiedName): HTMLCollection {} @@ -1581,11 +1975,20 @@ public function createAttribute(string $localName): Attr {} /** @implementation-alias DOMDocument::createAttributeNS */ public function createAttributeNS(?string $namespace, string $qualifiedName): Attr {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $firstElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?Element $lastElementChild; - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $childElementCount; /** @implementation-alias DOMDocument::getElementById */ @@ -1618,9 +2021,14 @@ public function querySelector(string $selectors): ?Element {} /** @implementation-alias Dom\Element::querySelectorAll */ public function querySelectorAll(string $selectors): NodeList {} + /** @virtual */ public ?HTMLElement $body; - /** @readonly */ + /** + * @readonly + * @virtual + */ public ?HTMLElement $head; + /** @virtual */ public string $title; } @@ -1655,13 +2063,19 @@ public static function createFromFile(string $path, int $options = 0, ?string $o public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): XMLDocument {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public string $xmlEncoding; + /** @virtual */ public bool $xmlStandalone; + /** @virtual */ public string $xmlVersion; + /** @virtual */ public bool $formatOutput; /** @implementation-alias DOMDocument::createEntityReference */ @@ -1687,7 +2101,10 @@ final class TokenList implements IteratorAggregate, Countable /** @implementation-alias Dom\Node::__construct */ private function __construct() {} - /** @readonly */ + /** + * @readonly + * @virtual + */ public int $length; public function item(int $index): ?string {} public function contains(string $token): bool {} @@ -1696,6 +2113,7 @@ public function remove(string ...$tokens): void {} public function toggle(string $token, ?bool $force = null): bool {} public function replace(string $token, string $newToken): bool {} public function supports(string $token): bool {} + /** @virtual */ public string $value; public function count(): int {} @@ -1721,9 +2139,13 @@ private function __construct() {} /** @not-serializable */ final class XPath { - /** @readonly */ + /** + * @readonly + * @virtual + */ public Document $document; + /** @virtual */ public bool $registerNodeNamespaces; public function __construct(Document $document, bool $registerNodeNS = true) {} diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index 08bc3ad1f645c..7839671b14b23 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 085c060d5a6f3d0c3db1cdbe5c5a3ec4ca261d5c */ + * Stub hash: b79ad2b70757f7d65a6b4fd907222a4955264bf6 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 0) ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0) @@ -2006,44 +2006,44 @@ static zend_class_entry *register_class_DOMDocumentType(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocumentType", class_DOMDocumentType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_entities_default_value; ZVAL_UNDEF(&property_entities_default_value); zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, 1); zend_string *property_entities_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_DOMNamedNodeMap, 0, 0)); zend_string_release(property_entities_name); zval property_notations_default_value; ZVAL_UNDEF(&property_notations_default_value); zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, 1); zend_string *property_notations_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_DOMNamedNodeMap, 0, 0)); zend_string_release(property_notations_name); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); zval property_internalSubset_default_value; ZVAL_UNDEF(&property_internalSubset_default_value); zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, 1); - zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_internalSubset_name); return class_entry; @@ -2054,7 +2054,7 @@ static zend_class_entry *register_class_DOMCdataSection(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMCdataSection", class_DOMCdataSection_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMText); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMText, 0); return class_entry; } @@ -2064,7 +2064,7 @@ static zend_class_entry *register_class_DOMComment(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMComment", class_DOMComment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMCharacterData, 0); return class_entry; } @@ -2094,7 +2094,7 @@ static zend_class_entry *register_class_DOMNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNode", class_DOMNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_DOCUMENT_POSITION_DISCONNECTED_value; ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1); @@ -2135,118 +2135,118 @@ static zend_class_entry *register_class_DOMNode(void) zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); zval property_childNodes_default_value; ZVAL_UNDEF(&property_childNodes_default_value); zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, 1); zend_string *property_childNodes_class_DOMNodeList = zend_string_init("DOMNodeList", sizeof("DOMNodeList")-1, 1); - zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0)); + zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_DOMNodeList, 0, 0)); zend_string_release(property_childNodes_name); zval property_firstChild_default_value; ZVAL_UNDEF(&property_firstChild_default_value); zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, 1); zend_string *property_firstChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_firstChild_name); zval property_lastChild_default_value; ZVAL_UNDEF(&property_lastChild_default_value); zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, 1); zend_string *property_lastChild_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_lastChild_name); zval property_previousSibling_default_value; ZVAL_UNDEF(&property_previousSibling_default_value); zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, 1); zend_string *property_previousSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_previousSibling_name); zval property_nextSibling_default_value; ZVAL_UNDEF(&property_nextSibling_default_value); zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, 1); zend_string *property_nextSibling_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_nextSibling_name); zval property_attributes_default_value; ZVAL_UNDEF(&property_attributes_default_value); zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_string *property_attributes_class_DOMNamedNodeMap = zend_string_init("DOMNamedNodeMap", sizeof("DOMNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_DOMNamedNodeMap, 0, MAY_BE_NULL)); zend_string_release(property_attributes_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_localName_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_baseURI_name); zval property_textContent_default_value; ZVAL_UNDEF(&property_textContent_default_value); zend_string *property_textContent_name = zend_string_init("textContent", sizeof("textContent") - 1, 1); - zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_textContent_name); return class_entry; @@ -2257,69 +2257,69 @@ static zend_class_entry *register_class_DOMNameSpaceNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNameSpaceNode", class_DOMNameSpaceNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_localName_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_DOMDocument, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_DOMNode = zend_string_init("DOMNode", sizeof("DOMNode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_DOMNode, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); return class_entry; @@ -2330,7 +2330,7 @@ static zend_class_entry *register_class_DOMImplementation(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMImplementation", class_DOMImplementation_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -2340,27 +2340,27 @@ static zend_class_entry *register_class_DOMDocumentFragment(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocumentFragment", class_DOMDocumentFragment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMParentNode); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -2371,13 +2371,13 @@ static zend_class_entry *register_class_DOMNodeList(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNodeList", class_DOMNodeList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -2388,33 +2388,33 @@ static zend_class_entry *register_class_DOMCharacterData(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMCharacterData", class_DOMCharacterData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMChildNode); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); return class_entry; @@ -2425,37 +2425,37 @@ static zend_class_entry *register_class_DOMAttr(zend_class_entry *class_entry_DO zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMAttr", class_DOMAttr_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_specified_default_value; - ZVAL_TRUE(&property_specified_default_value); + ZVAL_UNDEF(&property_specified_default_value); zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, 1); - zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_specified_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_ownerElement_default_value; ZVAL_UNDEF(&property_ownerElement_default_value); zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, 1); zend_string *property_ownerElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_ownerElement_name); zval property_schemaTypeInfo_default_value; - ZVAL_NULL(&property_schemaTypeInfo_default_value); + ZVAL_UNDEF(&property_schemaTypeInfo_default_value); zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, 1); - zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_schemaTypeInfo_name); return class_entry; @@ -2466,65 +2466,65 @@ static zend_class_entry *register_class_DOMElement(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMElement", class_DOMElement_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 2, class_entry_DOMParentNode, class_entry_DOMChildNode); zval property_tagName_default_value; ZVAL_UNDEF(&property_tagName_default_value); zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, 1); - zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_tagName_name); zval property_className_default_value; ZVAL_UNDEF(&property_className_default_value); zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); - zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_className_name); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); - zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_id_name); zval property_schemaTypeInfo_default_value; - ZVAL_NULL(&property_schemaTypeInfo_default_value); + ZVAL_UNDEF(&property_schemaTypeInfo_default_value); zend_string *property_schemaTypeInfo_name = zend_string_init("schemaTypeInfo", sizeof("schemaTypeInfo") - 1, 1); - zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_schemaTypeInfo_name, &property_schemaTypeInfo_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_schemaTypeInfo_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); return class_entry; @@ -2535,144 +2535,144 @@ static zend_class_entry *register_class_DOMDocument(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMDocument", class_DOMDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zend_class_implements(class_entry, 1, class_entry_DOMParentNode); zval property_doctype_default_value; ZVAL_UNDEF(&property_doctype_default_value); zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1); zend_string *property_doctype_class_DOMDocumentType = zend_string_init("DOMDocumentType", sizeof("DOMDocumentType")-1, 1); - zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_DOMDocumentType, 0, MAY_BE_NULL)); zend_string_release(property_doctype_name); zval property_implementation_default_value; ZVAL_UNDEF(&property_implementation_default_value); zend_string *property_implementation_name = zend_string_init("implementation", sizeof("implementation") - 1, 1); zend_string *property_implementation_class_DOMImplementation = zend_string_init("DOMImplementation", sizeof("DOMImplementation")-1, 1); - zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0)); + zend_declare_typed_property(class_entry, property_implementation_name, &property_implementation_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_implementation_class_DOMImplementation, 0, 0)); zend_string_release(property_implementation_name); zval property_documentElement_default_value; ZVAL_UNDEF(&property_documentElement_default_value); zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1); zend_string *property_documentElement_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_documentElement_name); zval property_actualEncoding_default_value; ZVAL_UNDEF(&property_actualEncoding_default_value); zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_actualEncoding_name); zval property_encoding_default_value; ZVAL_UNDEF(&property_encoding_default_value); zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1); - zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_encoding_name); zval property_xmlEncoding_default_value; ZVAL_UNDEF(&property_xmlEncoding_default_value); zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_xmlEncoding_name); zval property_standalone_default_value; ZVAL_UNDEF(&property_standalone_default_value); zend_string *property_standalone_name = zend_string_init("standalone", sizeof("standalone") - 1, 1); - zend_declare_typed_property(class_entry, property_standalone_name, &property_standalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_standalone_name, &property_standalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_standalone_name); zval property_xmlStandalone_default_value; ZVAL_UNDEF(&property_xmlStandalone_default_value); zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_xmlStandalone_name); zval property_version_default_value; ZVAL_UNDEF(&property_version_default_value); zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_version_name); zval property_xmlVersion_default_value; ZVAL_UNDEF(&property_xmlVersion_default_value); zend_string *property_xmlVersion_name = zend_string_init("xmlVersion", sizeof("xmlVersion") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_xmlVersion_name); zval property_strictErrorChecking_default_value; ZVAL_UNDEF(&property_strictErrorChecking_default_value); zend_string *property_strictErrorChecking_name = zend_string_init("strictErrorChecking", sizeof("strictErrorChecking") - 1, 1); - zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_strictErrorChecking_name, &property_strictErrorChecking_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_strictErrorChecking_name); zval property_documentURI_default_value; ZVAL_UNDEF(&property_documentURI_default_value); zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1); - zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_documentURI_name); zval property_config_default_value; ZVAL_UNDEF(&property_config_default_value); zend_string *property_config_name = zend_string_init("config", sizeof("config") - 1, 1); - zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); + zend_declare_typed_property(class_entry, property_config_name, &property_config_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); zend_string_release(property_config_name); zval property_formatOutput_default_value; ZVAL_UNDEF(&property_formatOutput_default_value); zend_string *property_formatOutput_name = zend_string_init("formatOutput", sizeof("formatOutput") - 1, 1); - zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_formatOutput_name); zval property_validateOnParse_default_value; ZVAL_UNDEF(&property_validateOnParse_default_value); zend_string *property_validateOnParse_name = zend_string_init("validateOnParse", sizeof("validateOnParse") - 1, 1); - zend_declare_typed_property(class_entry, property_validateOnParse_name, &property_validateOnParse_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_validateOnParse_name, &property_validateOnParse_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_validateOnParse_name); zval property_resolveExternals_default_value; ZVAL_UNDEF(&property_resolveExternals_default_value); zend_string *property_resolveExternals_name = zend_string_init("resolveExternals", sizeof("resolveExternals") - 1, 1); - zend_declare_typed_property(class_entry, property_resolveExternals_name, &property_resolveExternals_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_resolveExternals_name, &property_resolveExternals_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_resolveExternals_name); zval property_preserveWhiteSpace_default_value; ZVAL_UNDEF(&property_preserveWhiteSpace_default_value); zend_string *property_preserveWhiteSpace_name = zend_string_init("preserveWhiteSpace", sizeof("preserveWhiteSpace") - 1, 1); - zend_declare_typed_property(class_entry, property_preserveWhiteSpace_name, &property_preserveWhiteSpace_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_preserveWhiteSpace_name, &property_preserveWhiteSpace_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_preserveWhiteSpace_name); zval property_recover_default_value; ZVAL_UNDEF(&property_recover_default_value); zend_string *property_recover_name = zend_string_init("recover", sizeof("recover") - 1, 1); - zend_declare_typed_property(class_entry, property_recover_name, &property_recover_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_recover_name, &property_recover_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_recover_name); zval property_substituteEntities_default_value; ZVAL_UNDEF(&property_substituteEntities_default_value); zend_string *property_substituteEntities_name = zend_string_init("substituteEntities", sizeof("substituteEntities") - 1, 1); - zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_substituteEntities_name, &property_substituteEntities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_substituteEntities_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_DOMElement = zend_string_init("DOMElement", sizeof("DOMElement")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_DOMElement, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -2683,8 +2683,7 @@ static zend_class_entry *register_class_DOMException(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMException", class_DOMException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_FINAL); zend_register_class_alias("Dom\\DOMException", class_entry); zval property_code_default_value; @@ -2701,12 +2700,12 @@ static zend_class_entry *register_class_DOMText(zend_class_entry *class_entry_DO zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMText", class_DOMText_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMCharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMCharacterData, 0); zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, 1); - zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_wholeText_name); return class_entry; @@ -2717,13 +2716,13 @@ static zend_class_entry *register_class_DOMNamedNodeMap(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", class_DOMNamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -2734,42 +2733,42 @@ static zend_class_entry *register_class_DOMEntity(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMEntity", class_DOMEntity_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_systemId_name); zval property_notationName_default_value; ZVAL_UNDEF(&property_notationName_default_value); zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, 1); - zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_notationName_name); zval property_actualEncoding_default_value; - ZVAL_NULL(&property_actualEncoding_default_value); + ZVAL_UNDEF(&property_actualEncoding_default_value); zend_string *property_actualEncoding_name = zend_string_init("actualEncoding", sizeof("actualEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_actualEncoding_name, &property_actualEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_actualEncoding_name); zval property_encoding_default_value; - ZVAL_NULL(&property_encoding_default_value); + ZVAL_UNDEF(&property_encoding_default_value); zend_string *property_encoding_name = zend_string_init("encoding", sizeof("encoding") - 1, 1); - zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_encoding_name, &property_encoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_encoding_name); zval property_version_default_value; - ZVAL_NULL(&property_version_default_value); + ZVAL_UNDEF(&property_version_default_value); zend_string *property_version_name = zend_string_init("version", sizeof("version") - 1, 1); - zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_version_name, &property_version_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_version_name); return class_entry; @@ -2780,7 +2779,7 @@ static zend_class_entry *register_class_DOMEntityReference(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMEntityReference", class_DOMEntityReference_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); return class_entry; } @@ -2790,18 +2789,18 @@ static zend_class_entry *register_class_DOMNotation(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMNotation", class_DOMNotation_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); return class_entry; @@ -2812,18 +2811,18 @@ static zend_class_entry *register_class_DOMProcessingInstruction(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMProcessingInstruction", class_DOMProcessingInstruction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DOMNode); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DOMNode, 0); zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, 1); - zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_target_name); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); return class_entry; @@ -2835,20 +2834,19 @@ static zend_class_entry *register_class_DOMXPath(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DOMXPath", class_DOMXPath_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval property_document_default_value; ZVAL_UNDEF(&property_document_default_value); zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1); zend_string *property_document_class_DOMDocument = zend_string_init("DOMDocument", sizeof("DOMDocument")-1, 1); - zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0)); + zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_DOMDocument, 0, 0)); zend_string_release(property_document_name); zval property_registerNodeNamespaces_default_value; ZVAL_UNDEF(&property_registerNodeNamespaces_default_value); zend_string *property_registerNodeNamespaces_name = zend_string_init("registerNodeNamespaces", sizeof("registerNodeNamespaces") - 1, 1); - zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_registerNodeNamespaces_name); return class_entry; @@ -2880,8 +2878,7 @@ static zend_class_entry *register_class_Dom_Implementation(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Implementation", class_Dom_Implementation_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -2891,8 +2888,7 @@ static zend_class_entry *register_class_Dom_Node(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Node", class_Dom_Node_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval const_DOCUMENT_POSITION_DISCONNECTED_value; ZVAL_LONG(&const_DOCUMENT_POSITION_DISCONNECTED_value, 0x1); @@ -2933,93 +2929,93 @@ static zend_class_entry *register_class_Dom_Node(void) zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_nodeName_default_value; ZVAL_UNDEF(&property_nodeName_default_value); zend_string *property_nodeName_name = zend_string_init("nodeName", sizeof("nodeName") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_nodeName_name, &property_nodeName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_nodeName_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_baseURI_name); zval property_isConnected_default_value; ZVAL_UNDEF(&property_isConnected_default_value); zend_string *property_isConnected_name = zend_string_init("isConnected", sizeof("isConnected") - 1, 1); - zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isConnected_name, &property_isConnected_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isConnected_name); zval property_ownerDocument_default_value; ZVAL_UNDEF(&property_ownerDocument_default_value); zend_string *property_ownerDocument_name = zend_string_init("ownerDocument", sizeof("ownerDocument") - 1, 1); zend_string *property_ownerDocument_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1); - zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerDocument_name, &property_ownerDocument_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerDocument_class_Dom_Document, 0, MAY_BE_NULL)); zend_string_release(property_ownerDocument_name); zval property_parentNode_default_value; ZVAL_UNDEF(&property_parentNode_default_value); zend_string *property_parentNode_name = zend_string_init("parentNode", sizeof("parentNode") - 1, 1); zend_string *property_parentNode_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentNode_name, &property_parentNode_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentNode_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_parentNode_name); zval property_parentElement_default_value; ZVAL_UNDEF(&property_parentElement_default_value); zend_string *property_parentElement_name = zend_string_init("parentElement", sizeof("parentElement") - 1, 1); zend_string *property_parentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_parentElement_name, &property_parentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_parentElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_parentElement_name); zval property_childNodes_default_value; ZVAL_UNDEF(&property_childNodes_default_value); zend_string *property_childNodes_name = zend_string_init("childNodes", sizeof("childNodes") - 1, 1); zend_string *property_childNodes_class_Dom_NodeList = zend_string_init("Dom\\\116odeList", sizeof("Dom\\\116odeList")-1, 1); - zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0)); + zend_declare_typed_property(class_entry, property_childNodes_name, &property_childNodes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_childNodes_class_Dom_NodeList, 0, 0)); zend_string_release(property_childNodes_name); zval property_firstChild_default_value; ZVAL_UNDEF(&property_firstChild_default_value); zend_string *property_firstChild_name = zend_string_init("firstChild", sizeof("firstChild") - 1, 1); zend_string *property_firstChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstChild_name, &property_firstChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstChild_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_firstChild_name); zval property_lastChild_default_value; ZVAL_UNDEF(&property_lastChild_default_value); zend_string *property_lastChild_name = zend_string_init("lastChild", sizeof("lastChild") - 1, 1); zend_string *property_lastChild_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastChild_name, &property_lastChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastChild_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_lastChild_name); zval property_previousSibling_default_value; ZVAL_UNDEF(&property_previousSibling_default_value); zend_string *property_previousSibling_name = zend_string_init("previousSibling", sizeof("previousSibling") - 1, 1); zend_string *property_previousSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousSibling_name, &property_previousSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousSibling_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_previousSibling_name); zval property_nextSibling_default_value; ZVAL_UNDEF(&property_nextSibling_default_value); zend_string *property_nextSibling_name = zend_string_init("nextSibling", sizeof("nextSibling") - 1, 1); zend_string *property_nextSibling_class_Dom_Node = zend_string_init("Dom\\\116ode", sizeof("Dom\\\116ode")-1, 1); - zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextSibling_name, &property_nextSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextSibling_class_Dom_Node, 0, MAY_BE_NULL)); zend_string_release(property_nextSibling_name); zval property_nodeValue_default_value; ZVAL_UNDEF(&property_nodeValue_default_value); zend_string *property_nodeValue_name = zend_string_init("nodeValue", sizeof("nodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nodeValue_name, &property_nodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_nodeValue_name); zval property_textContent_default_value; ZVAL_UNDEF(&property_textContent_default_value); zend_string *property_textContent_name = zend_string_init("textContent", sizeof("textContent") - 1, 1); - zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_textContent_name, &property_textContent_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_textContent_name); return class_entry; @@ -3030,13 +3026,13 @@ static zend_class_entry *register_class_Dom_NodeList(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NodeList", class_Dom_NodeList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3047,13 +3043,13 @@ static zend_class_entry *register_class_Dom_NamedNodeMap(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NamedNodeMap", class_Dom_NamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3064,13 +3060,13 @@ static zend_class_entry *register_class_Dom_DtdNamedNodeMap(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DtdNamedNodeMap", class_Dom_DtdNamedNodeMap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3081,13 +3077,13 @@ static zend_class_entry *register_class_Dom_HTMLCollection(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLCollection", class_Dom_HTMLCollection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3125,43 +3121,43 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Element", class_Dom_Element_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 2, class_entry_Dom_ParentNode, class_entry_Dom_ChildNode); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_tagName_default_value; ZVAL_UNDEF(&property_tagName_default_value); zend_string *property_tagName_name = zend_string_init("tagName", sizeof("tagName") - 1, 1); - zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_tagName_name, &property_tagName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_tagName_name); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); - zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_id_name); zval property_className_default_value; ZVAL_UNDEF(&property_className_default_value); zend_string *property_className_name = zend_string_init("className", sizeof("className") - 1, 1); - zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_className_name, &property_className_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_className_name); zval property_classList_default_value; @@ -3175,53 +3171,53 @@ static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entr ZVAL_UNDEF(&property_attributes_default_value); zend_string *property_attributes_name = zend_string_init("attributes", sizeof("attributes") - 1, 1); zend_string *property_attributes_class_Dom_NamedNodeMap = zend_string_init("Dom\\\116amedNodeMap", sizeof("Dom\\\116amedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_attributes_name, &property_attributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_attributes_class_Dom_NamedNodeMap, 0, 0)); zend_string_release(property_attributes_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); zval property_innerHTML_default_value; ZVAL_UNDEF(&property_innerHTML_default_value); zend_string *property_innerHTML_name = zend_string_init("innerHTML", sizeof("innerHTML") - 1, 1); - zend_declare_typed_property(class_entry, property_innerHTML_name, &property_innerHTML_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_innerHTML_name, &property_innerHTML_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_innerHTML_name); zval property_substitutedNodeValue_default_value; ZVAL_UNDEF(&property_substitutedNodeValue_default_value); zend_string *property_substitutedNodeValue_name = zend_string_init("substitutedNodeValue", sizeof("substitutedNodeValue") - 1, 1); - zend_declare_typed_property(class_entry, property_substitutedNodeValue_name, &property_substitutedNodeValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_substitutedNodeValue_name, &property_substitutedNodeValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_substitutedNodeValue_name); return class_entry; @@ -3232,7 +3228,7 @@ static zend_class_entry *register_class_Dom_HTMLElement(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLElement", class_Dom_HTMLElement_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Element); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Element, 0); return class_entry; } @@ -3242,49 +3238,49 @@ static zend_class_entry *register_class_Dom_Attr(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Attr", class_Dom_Attr_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_namespaceURI_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_prefix_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_ownerElement_default_value; ZVAL_UNDEF(&property_ownerElement_default_value); zend_string *property_ownerElement_name = zend_string_init("ownerElement", sizeof("ownerElement") - 1, 1); zend_string *property_ownerElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_ownerElement_name, &property_ownerElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_ownerElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_ownerElement_name); zval property_specified_default_value; - ZVAL_TRUE(&property_specified_default_value); + ZVAL_UNDEF(&property_specified_default_value); zend_string *property_specified_name = zend_string_init("specified", sizeof("specified") - 1, 1); - zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_specified_name, &property_specified_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_specified_name); return class_entry; @@ -3295,33 +3291,33 @@ static zend_class_entry *register_class_Dom_CharacterData(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "CharacterData", class_Dom_CharacterData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ChildNode); zval property_previousElementSibling_default_value; ZVAL_UNDEF(&property_previousElementSibling_default_value); zend_string *property_previousElementSibling_name = zend_string_init("previousElementSibling", sizeof("previousElementSibling") - 1, 1); zend_string *property_previousElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_previousElementSibling_name, &property_previousElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previousElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_previousElementSibling_name); zval property_nextElementSibling_default_value; ZVAL_UNDEF(&property_nextElementSibling_default_value); zend_string *property_nextElementSibling_name = zend_string_init("nextElementSibling", sizeof("nextElementSibling") - 1, 1); zend_string *property_nextElementSibling_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_nextElementSibling_name, &property_nextElementSibling_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_nextElementSibling_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_nextElementSibling_name); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); - zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_data_name); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); return class_entry; @@ -3332,12 +3328,12 @@ static zend_class_entry *register_class_Dom_Text(zend_class_entry *class_entry_D zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Text", class_Dom_Text_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); zval property_wholeText_default_value; ZVAL_UNDEF(&property_wholeText_default_value); zend_string *property_wholeText_name = zend_string_init("wholeText", sizeof("wholeText") - 1, 1); - zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_wholeText_name, &property_wholeText_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_wholeText_name); return class_entry; @@ -3348,7 +3344,7 @@ static zend_class_entry *register_class_Dom_CDATASection(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "CDATASection", class_Dom_CDATASection_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Text); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Text, 0); return class_entry; } @@ -3358,12 +3354,12 @@ static zend_class_entry *register_class_Dom_ProcessingInstruction(zend_class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "ProcessingInstruction", class_Dom_ProcessingInstruction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); zval property_target_default_value; ZVAL_UNDEF(&property_target_default_value); zend_string *property_target_name = zend_string_init("target", sizeof("target") - 1, 1); - zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_target_name, &property_target_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_target_name); return class_entry; @@ -3374,7 +3370,7 @@ static zend_class_entry *register_class_Dom_Comment(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Comment", class_Dom_Comment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_CharacterData); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_CharacterData, 0); return class_entry; } @@ -3384,45 +3380,45 @@ static zend_class_entry *register_class_Dom_DocumentType(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DocumentType", class_Dom_DocumentType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ChildNode); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_entities_default_value; ZVAL_UNDEF(&property_entities_default_value); zend_string *property_entities_name = zend_string_init("entities", sizeof("entities") - 1, 1); zend_string *property_entities_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_entities_name, &property_entities_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_entities_class_Dom_DtdNamedNodeMap, 0, 0)); zend_string_release(property_entities_name); zval property_notations_default_value; ZVAL_UNDEF(&property_notations_default_value); zend_string *property_notations_name = zend_string_init("notations", sizeof("notations") - 1, 1); zend_string *property_notations_class_Dom_DtdNamedNodeMap = zend_string_init("Dom\\DtdNamedNodeMap", sizeof("Dom\\DtdNamedNodeMap")-1, 1); - zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0)); + zend_declare_typed_property(class_entry, property_notations_name, &property_notations_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notations_class_Dom_DtdNamedNodeMap, 0, 0)); zend_string_release(property_notations_name); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); zval property_internalSubset_default_value; ZVAL_UNDEF(&property_internalSubset_default_value); zend_string *property_internalSubset_name = zend_string_init("internalSubset", sizeof("internalSubset") - 1, 1); - zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_internalSubset_name, &property_internalSubset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_internalSubset_name); return class_entry; @@ -3433,27 +3429,27 @@ static zend_class_entry *register_class_Dom_DocumentFragment(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "DocumentFragment", class_Dom_DocumentFragment_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); return class_entry; @@ -3464,24 +3460,24 @@ static zend_class_entry *register_class_Dom_Entity(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Entity", class_Dom_Entity_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_systemId_name); zval property_notationName_default_value; ZVAL_UNDEF(&property_notationName_default_value); zend_string *property_notationName_name = zend_string_init("notationName", sizeof("notationName") - 1, 1); - zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_notationName_name, &property_notationName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); zend_string_release(property_notationName_name); return class_entry; @@ -3492,7 +3488,7 @@ static zend_class_entry *register_class_Dom_EntityReference(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "EntityReference", class_Dom_EntityReference_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); return class_entry; } @@ -3502,18 +3498,18 @@ static zend_class_entry *register_class_Dom_Notation(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Notation", class_Dom_Notation_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, 0); zval property_publicId_default_value; ZVAL_UNDEF(&property_publicId_default_value); zend_string *property_publicId_name = zend_string_init("publicId", sizeof("publicId") - 1, 1); - zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_publicId_name, &property_publicId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_publicId_name); zval property_systemId_default_value; ZVAL_UNDEF(&property_systemId_default_value); zend_string *property_systemId_name = zend_string_init("systemId", sizeof("systemId") - 1, 1); - zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_systemId_name, &property_systemId_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_systemId_name); return class_entry; @@ -3524,8 +3520,7 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "Document", class_Dom_Document_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Node); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Node, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 1, class_entry_Dom_ParentNode); zval property_implementation_default_value; @@ -3538,85 +3533,85 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent zval property_URL_default_value; ZVAL_UNDEF(&property_URL_default_value); zend_string *property_URL_name = zend_string_init("URL", sizeof("URL") - 1, 1); - zend_declare_typed_property(class_entry, property_URL_name, &property_URL_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_URL_name, &property_URL_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_URL_name); zval property_documentURI_default_value; ZVAL_UNDEF(&property_documentURI_default_value); zend_string *property_documentURI_name = zend_string_init("documentURI", sizeof("documentURI") - 1, 1); - zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_documentURI_name, &property_documentURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_documentURI_name); zval property_characterSet_default_value; ZVAL_UNDEF(&property_characterSet_default_value); zend_string *property_characterSet_name = zend_string_init("characterSet", sizeof("characterSet") - 1, 1); - zend_declare_typed_property(class_entry, property_characterSet_name, &property_characterSet_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_characterSet_name, &property_characterSet_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_characterSet_name); zval property_charset_default_value; ZVAL_UNDEF(&property_charset_default_value); zend_string *property_charset_name = zend_string_init("charset", sizeof("charset") - 1, 1); - zend_declare_typed_property(class_entry, property_charset_name, &property_charset_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_charset_name, &property_charset_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_charset_name); zval property_inputEncoding_default_value; ZVAL_UNDEF(&property_inputEncoding_default_value); zend_string *property_inputEncoding_name = zend_string_init("inputEncoding", sizeof("inputEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_inputEncoding_name, &property_inputEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_inputEncoding_name, &property_inputEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_inputEncoding_name); zval property_doctype_default_value; ZVAL_UNDEF(&property_doctype_default_value); zend_string *property_doctype_name = zend_string_init("doctype", sizeof("doctype") - 1, 1); zend_string *property_doctype_class_Dom_DocumentType = zend_string_init("Dom\\DocumentType", sizeof("Dom\\DocumentType")-1, 1); - zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_doctype_name, &property_doctype_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_doctype_class_Dom_DocumentType, 0, MAY_BE_NULL)); zend_string_release(property_doctype_name); zval property_documentElement_default_value; ZVAL_UNDEF(&property_documentElement_default_value); zend_string *property_documentElement_name = zend_string_init("documentElement", sizeof("documentElement") - 1, 1); zend_string *property_documentElement_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_documentElement_name, &property_documentElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_documentElement_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_documentElement_name); zval property_firstElementChild_default_value; ZVAL_UNDEF(&property_firstElementChild_default_value); zend_string *property_firstElementChild_name = zend_string_init("firstElementChild", sizeof("firstElementChild") - 1, 1); zend_string *property_firstElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_firstElementChild_name, &property_firstElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_firstElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_firstElementChild_name); zval property_lastElementChild_default_value; ZVAL_UNDEF(&property_lastElementChild_default_value); zend_string *property_lastElementChild_name = zend_string_init("lastElementChild", sizeof("lastElementChild") - 1, 1); zend_string *property_lastElementChild_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1); - zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_lastElementChild_name, &property_lastElementChild_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_lastElementChild_class_Dom_Element, 0, MAY_BE_NULL)); zend_string_release(property_lastElementChild_name); zval property_childElementCount_default_value; ZVAL_UNDEF(&property_childElementCount_default_value); zend_string *property_childElementCount_name = zend_string_init("childElementCount", sizeof("childElementCount") - 1, 1); - zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_childElementCount_name); zval property_body_default_value; ZVAL_UNDEF(&property_body_default_value); zend_string *property_body_name = zend_string_init("body", sizeof("body") - 1, 1); zend_string *property_body_class_Dom_HTMLElement = zend_string_init("Dom\\HTMLElement", sizeof("Dom\\HTMLElement")-1, 1); - zend_declare_typed_property(class_entry, property_body_name, &property_body_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_body_class_Dom_HTMLElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_body_name, &property_body_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_body_class_Dom_HTMLElement, 0, MAY_BE_NULL)); zend_string_release(property_body_name); zval property_head_default_value; ZVAL_UNDEF(&property_head_default_value); zend_string *property_head_name = zend_string_init("head", sizeof("head") - 1, 1); zend_string *property_head_class_Dom_HTMLElement = zend_string_init("Dom\\HTMLElement", sizeof("Dom\\HTMLElement")-1, 1); - zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL)); + zend_declare_typed_property(class_entry, property_head_name, &property_head_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_head_class_Dom_HTMLElement, 0, MAY_BE_NULL)); zend_string_release(property_head_name); zval property_title_default_value; ZVAL_UNDEF(&property_title_default_value); zend_string *property_title_name = zend_string_init("title", sizeof("title") - 1, 1); - zend_declare_typed_property(class_entry, property_title_name, &property_title_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_title_name, &property_title_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_title_name); return class_entry; @@ -3627,8 +3622,7 @@ static zend_class_entry *register_class_Dom_HTMLDocument(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "HTMLDocument", class_Dom_HTMLDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Document); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Document, ZEND_ACC_FINAL); return class_entry; } @@ -3638,31 +3632,30 @@ static zend_class_entry *register_class_Dom_XMLDocument(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "XMLDocument", class_Dom_XMLDocument_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Dom_Document); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Dom_Document, ZEND_ACC_FINAL); zval property_xmlEncoding_default_value; ZVAL_UNDEF(&property_xmlEncoding_default_value); zend_string *property_xmlEncoding_name = zend_string_init("xmlEncoding", sizeof("xmlEncoding") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlEncoding_name, &property_xmlEncoding_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlEncoding_name); zval property_xmlStandalone_default_value; ZVAL_UNDEF(&property_xmlStandalone_default_value); zend_string *property_xmlStandalone_name = zend_string_init("xmlStandalone", sizeof("xmlStandalone") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_xmlStandalone_name, &property_xmlStandalone_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_xmlStandalone_name); zval property_xmlVersion_default_value; ZVAL_UNDEF(&property_xmlVersion_default_value); zend_string *property_xmlVersion_name = zend_string_init("xmlVersion", sizeof("xmlVersion") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlVersion_name, &property_xmlVersion_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlVersion_name); zval property_formatOutput_default_value; ZVAL_UNDEF(&property_formatOutput_default_value); zend_string *property_formatOutput_name = zend_string_init("formatOutput", sizeof("formatOutput") - 1, 1); - zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_formatOutput_name, &property_formatOutput_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_formatOutput_name); return class_entry; @@ -3673,20 +3666,19 @@ static zend_class_entry *register_class_Dom_TokenList(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "TokenList", class_Dom_TokenList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 2, class_entry_Dom_IteratorAggregate, class_entry_Dom_Countable); zval property_length_default_value; ZVAL_UNDEF(&property_length_default_value); zend_string *property_length_name = zend_string_init("length", sizeof("length") - 1, 1); - zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_length_name, &property_length_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_length_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); return class_entry; @@ -3697,8 +3689,7 @@ static zend_class_entry *register_class_Dom_NamespaceInfo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "NamespaceInfo", class_Dom_NamespaceInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE|ZEND_ACC_READONLY_CLASS; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE|ZEND_ACC_READONLY_CLASS); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); @@ -3728,20 +3719,19 @@ static zend_class_entry *register_class_Dom_XPath(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Dom", "XPath", class_Dom_XPath_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval property_document_default_value; ZVAL_UNDEF(&property_document_default_value); zend_string *property_document_name = zend_string_init("document", sizeof("document") - 1, 1); zend_string *property_document_class_Dom_Document = zend_string_init("Dom\\Document", sizeof("Dom\\Document")-1, 1); - zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0)); + zend_declare_typed_property(class_entry, property_document_name, &property_document_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_document_class_Dom_Document, 0, 0)); zend_string_release(property_document_name); zval property_registerNodeNamespaces_default_value; ZVAL_UNDEF(&property_registerNodeNamespaces_default_value); zend_string *property_registerNodeNamespaces_name = zend_string_init("registerNodeNamespaces", sizeof("registerNodeNamespaces") - 1, 1); - zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_registerNodeNamespaces_name, &property_registerNodeNamespaces_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_registerNodeNamespaces_name); return class_entry; diff --git a/ext/dom/tests/bug69846.phpt b/ext/dom/tests/bug69846.phpt index 04631444e898c..2f41433e35021 100644 --- a/ext/dom/tests/bug69846.phpt +++ b/ext/dom/tests/bug69846.phpt @@ -28,9 +28,9 @@ foreach ($dataNodes AS $node) { } ?> ---EXPECT-- +--EXPECTF-- int(3) -object(DOMText)#7 (23) { +object(DOMText)#%d (23) { ["wholeText"]=> string(3) " " @@ -82,15 +82,15 @@ object(DOMText)#7 (23) { string(3) " " } -object(DOMElement)#7 (27) { - ["schemaTypeInfo"]=> - NULL +object(DOMElement)#%d (27) { ["tagName"]=> string(5) "form1" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> @@ -146,7 +146,7 @@ object(DOMElement)#7 (27) { Value C " } -object(DOMText)#7 (23) { +object(DOMText)#%d (23) { ["wholeText"]=> string(1) " " diff --git a/ext/dom/tests/bug80602_3.phpt b/ext/dom/tests/bug80602_3.phpt index 3409533fed2d6..8f4626e433ace 100644 --- a/ext/dom/tests/bug80602_3.phpt +++ b/ext/dom/tests/bug80602_3.phpt @@ -24,14 +24,14 @@ var_dump($target); --EXPECTF-- barfoobaz object(DOMElement)#3 (27) { - ["schemaTypeInfo"]=> - NULL ["tagName"]=> string(4) "last" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> NULL ["lastElementChild"]=> @@ -81,14 +81,14 @@ object(DOMElement)#3 (27) { } barfoobaz object(DOMElement)#2 (27) { - ["schemaTypeInfo"]=> - NULL ["tagName"]=> string(4) "last" ["className"]=> string(0) "" ["id"]=> string(0) "" + ["schemaTypeInfo"]=> + NULL ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt index 542b2fc4733e1..a1cbabffbb239 100644 --- a/ext/dom/tests/domobject_debug_handler.phpt +++ b/ext/dom/tests/domobject_debug_handler.phpt @@ -16,10 +16,6 @@ var_dump($d); ?> --EXPECTF-- Deprecated: Creation of dynamic property DOMDocument::$dynamicProperty is deprecated in %s on line %d - -Deprecated: Property DOMDocument::$actualEncoding is deprecated in %s on line %d - -Deprecated: Property DOMDocument::$config is deprecated in %s on line %d object(DOMDocument)#1 (41) { ["dynamicProperty"]=> object(stdClass)#2 (0) { diff --git a/ext/dom/tests/gh15551.phpt b/ext/dom/tests/gh15551.phpt new file mode 100644 index 0000000000000..3b4b7d4e85793 --- /dev/null +++ b/ext/dom/tests/gh15551.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h) +--EXTENSIONS-- +dom +--FILE-- +childNodes; +$iter = $nodes->getIterator(); +$iter->next(); +var_dump($iter->valid()); +?> +--EXPECT-- +bool(false) diff --git a/ext/dom/tests/gh15570.phpt b/ext/dom/tests/gh15570.phpt new file mode 100644 index 0000000000000..f2337cca2259d --- /dev/null +++ b/ext/dom/tests/gh15570.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-15570 (Segmentation fault (access null pointer) in ext/dom/html5_serializer.c) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +dom +--FILE-- + + +HTML; +$dom = Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR); +$a = $dom->head->firstChild->cloneNode(false); +var_dump($dom->saveHTML($a)); +?> +--EXPECT-- +string(1) " +" diff --git a/ext/dom/tests/modern/common/Document_title_getter.phpt b/ext/dom/tests/modern/common/Document_title_getter.phpt index eb4f4b7cdb5fd..7aeb95d0efd67 100644 --- a/ext/dom/tests/modern/common/Document_title_getter.phpt +++ b/ext/dom/tests/modern/common/Document_title_getter.phpt @@ -43,6 +43,10 @@ var_dump($dom->title); $dom = Dom\XMLDocument::createFromString("title\nhere"); var_dump($dom->title); +$dom = Dom\XMLDocument::createFromString("</root>"); +$dom->getElementsByTagName('title')[0]->appendChild($dom->importLegacyNode(new DOMText)); +var_dump($dom->title); + echo "=== SVG namespaced root ===\n"; $dom = Dom\XMLDocument::createFromString("<root xmlns=\"http://www.w3.org/1999/xhtml\"><title>title"); @@ -72,6 +76,7 @@ string(0) "" string(2) "xz" string(2) "yw" string(10) "title here" +string(0) "" === SVG namespaced root === string(5) "title" string(5) "title" diff --git a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt index fda707577b5f5..124bd2e79a35a 100644 --- a/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt +++ b/ext/dom/tests/modern/html/encoding/HTMLDocument_fallback_encoding.phpt @@ -9,10 +9,6 @@ $dom = Dom\HTMLDocument::createFromFile(__DIR__ . "/fallback_encoding.html"); var_dump($dom->inputEncoding); echo $dom->saveHtml(); -?> ---CLEAN-- - --EXPECT-- string(5) "UTF-8" diff --git a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt index 96b054168a2dc..98e2bd48addf8 100644 --- a/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt +++ b/ext/dom/tests/modern/html/parser/HTMLDocument_fromFile_empty_path.phpt @@ -9,7 +9,7 @@ $dom = Dom\HTMLDocument::createFromFile(""); ?> --EXPECTF-- -Fatal error: Uncaught ValueError: Path cannot be empty in %s:%d +Fatal error: Uncaught ValueError: Path must not be empty in %s:%d Stack trace: #0 %s(%d): Dom\HTMLDocument::createFromFile('') #1 {main} diff --git a/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt b/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt new file mode 100644 index 0000000000000..eaedfbe23232c --- /dev/null +++ b/ext/dom/tests/modern/html/serializer/legacy_null_content.phpt @@ -0,0 +1,20 @@ +--TEST-- +Serialize legacy nodes with NULL content +--EXTENSIONS-- +dom +--FILE-- +appendChild($dom->createElement('html')); + +$root->appendChild($dom->importLegacyNode(new DOMText)); +$root->appendChild($dom->importLegacyNode(new DOMComment)); +$root->appendChild($dom->importLegacyNode(new DOMProcessingInstruction('target'))); +$root->appendChild($dom->importLegacyNode(new DOMCdataSection(''))); + +echo $dom->saveHTML(), "\n"; +echo $dom->documentElement->innerHTML, "\n"; +?> +--EXPECT-- + + diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 2c264a23039f8..d27db9bcd29b5 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -447,7 +447,7 @@ PHP_FUNCTION(enchant_broker_request_dict) PHP_ENCHANT_GET_BROKER; if (taglen == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/enchant/enchant_arginfo.h b/ext/enchant/enchant_arginfo.h index d1f0d56ddb025..cc722e18d0681 100644 --- a/ext/enchant/enchant_arginfo.h +++ b/ext/enchant/enchant_arginfo.h @@ -231,8 +231,7 @@ static zend_class_entry *register_class_EnchantBroker(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EnchantBroker", class_EnchantBroker_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -242,8 +241,7 @@ static zend_class_entry *register_class_EnchantDictionary(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EnchantDictionary", class_EnchantDictionary_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt b/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt index b49967cbedc3f..37f5d359481b3 100644 --- a/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt +++ b/ext/enchant/tests/broker_request_dict_error_on_empty_tag.phpt @@ -18,4 +18,4 @@ try { ?> --EXPECT-- -enchant_broker_request_dict(): Argument #2 ($tag) cannot be empty +enchant_broker_request_dict(): Argument #2 ($tag) must not be empty diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 7e9df52af5b0e..518c31526532d 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -4550,7 +4550,7 @@ PHP_FUNCTION(exif_read_data) } if (!Z_STRLEN_P(stream)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -4727,7 +4727,7 @@ PHP_FUNCTION(exif_thumbnail) } if (!Z_STRLEN_P(stream)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/exif/tests/filename_empty.phpt b/ext/exif/tests/filename_empty.phpt index a089926c3b513..8e83f6b487f85 100644 --- a/ext/exif/tests/filename_empty.phpt +++ b/ext/exif/tests/filename_empty.phpt @@ -31,7 +31,7 @@ try { ?> --EXPECT-- -exif_read_data(): Argument #1 ($file) cannot be empty -exif_thumbnail(): Argument #1 ($file) cannot be empty +exif_read_data(): Argument #1 ($file) must not be empty +exif_thumbnail(): Argument #1 ($file) must not be empty exif_read_data(): Argument #1 ($file) must not contain any null bytes exif_thumbnail(): Argument #1 ($file) must not contain any null bytes diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index d53427523f4bc..6d9216b6f7f3f 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -246,6 +246,7 @@ static zend_always_inline void zend_ffi_object_init(zend_object *object, zend_cl { GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = GC_OBJECT | (IS_OBJ_DESTRUCTOR_CALLED << GC_FLAGS_SHIFT); + object->extra_flags = 0; object->ce = ce; object->handlers = ce->default_object_handlers; object->properties = NULL; diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index aca7a8d25637c..56f1444bd7ab6 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -213,8 +213,7 @@ static zend_class_entry *register_class_FFI(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FFI", class_FFI_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval const___BIGGEST_ALIGNMENT___value; ZVAL_LONG(&const___BIGGEST_ALIGNMENT___value, __BIGGEST_ALIGNMENT__); @@ -230,8 +229,7 @@ static zend_class_entry *register_class_FFI_CData(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "CData", class_FFI_CData_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -241,8 +239,7 @@ static zend_class_entry *register_class_FFI_CType(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "CType", class_FFI_CType_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval const_TYPE_VOID_value; ZVAL_LONG(&const_TYPE_VOID_value, ZEND_FFI_TYPE_VOID); @@ -482,7 +479,7 @@ static zend_class_entry *register_class_FFI_Exception(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "Exception", class_FFI_Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } @@ -492,8 +489,7 @@ static zend_class_entry *register_class_FFI_ParserException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FFI", "ParserException", class_FFI_ParserException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FFI_Exception); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FFI_Exception, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/ffi/tests/gh14286_2.phpt b/ext/ffi/tests/gh14286_2.phpt index 683929780c053..c3fc0b242a476 100644 --- a/ext/ffi/tests/gh14286_2.phpt +++ b/ext/ffi/tests/gh14286_2.phpt @@ -4,7 +4,7 @@ GH-14286 (ffi enum type (when enum has no name) make memory leak) ffi --SKIPIF-- --INI-- ffi.enable=1 diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 8680722ae9541..eb505f0085af9 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -374,7 +374,7 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime php_stream_statbuf ssb; if (buffer == NULL || buffer_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); goto clean; } if (CHECK_NULL_PATH(buffer, buffer_len)) { diff --git a/ext/fileinfo/fileinfo_arginfo.h b/ext/fileinfo/fileinfo_arginfo.h index 2ae8a2316e57b..36b9351ea1387 100644 --- a/ext/fileinfo/fileinfo_arginfo.h +++ b/ext/fileinfo/fileinfo_arginfo.h @@ -103,8 +103,7 @@ static zend_class_entry *register_class_finfo(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "finfo", class_finfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/fileinfo/tests/finfo_file_001.phpt b/ext/fileinfo/tests/finfo_file_001.phpt index 7eb39487b7d2b..86ce797a04db4 100644 --- a/ext/fileinfo/tests/finfo_file_001.phpt +++ b/ext/fileinfo/tests/finfo_file_001.phpt @@ -22,7 +22,7 @@ var_dump(finfo_file($fp, '&')); ?> --EXPECTF-- finfo_file(): Argument #1 ($finfo) must not contain any null bytes -finfo_file(): Argument #1 ($finfo) cannot be empty +finfo_file(): Argument #1 ($finfo) must not be empty string(9) "directory" Warning: finfo_file(&): Failed to open stream: No such file or directory in %s on line %d diff --git a/ext/fileinfo/tests/mime_content_type_001.phpt b/ext/fileinfo/tests/mime_content_type_001.phpt index 38c136f3844c7..98c1325959d85 100644 --- a/ext/fileinfo/tests/mime_content_type_001.phpt +++ b/ext/fileinfo/tests/mime_content_type_001.phpt @@ -47,5 +47,5 @@ mime_content_type(): Argument #1 ($filename) must be of type resource|string, st mime_content_type(): Argument #1 ($filename) must be of type resource|string, array given Warning: mime_content_type(foo/inexistent): Failed to open stream: No such file or directory in %s on line %d -mime_content_type(): Argument #1 ($filename) cannot be empty +mime_content_type(): Argument #1 ($filename) must not be empty mime_content_type(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index ca8e65c1f75f6..b8758199279c7 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -382,7 +382,7 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if (thousand_set) { if (thousand_len < 1) { - zend_value_error("%s(): \"thousand\" option cannot be empty", get_active_function_name()); + zend_value_error("%s(): \"thousand\" option must not be empty", get_active_function_name()); RETURN_VALIDATION_FAILED } else { tsd_sep = thousand; diff --git a/ext/filter/tests/bug51368.phpt b/ext/filter/tests/bug51368.phpt index 73c743b5dee4f..78f374848b644 100644 --- a/ext/filter/tests/bug51368.phpt +++ b/ext/filter/tests/bug51368.phpt @@ -21,4 +21,4 @@ try { --EXPECT-- float(1000) float(1234.567) -filter_var(): "thousand" option cannot be empty +filter_var(): "thousand" option must not be empty diff --git a/ext/ftp/ftp_arginfo.h b/ext/ftp/ftp_arginfo.h index 9aa6fcb48b352..0187ee325c615 100644 --- a/ext/ftp/ftp_arginfo.h +++ b/ext/ftp/ftp_arginfo.h @@ -300,8 +300,7 @@ static zend_class_entry *register_class_FTP_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "FTP", "Connection", class_FTP_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 5af2d4a5152bb..899dc05b3e829 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -646,7 +646,7 @@ PHP_FUNCTION(imagesetstyle) num_styles = zend_hash_num_elements(Z_ARRVAL_P(styles)); if (num_styles == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index f68b34d5e101b..6cc6da64c9bbd 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -996,8 +996,7 @@ static zend_class_entry *register_class_GdImage(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GdImage", class_GdImage_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1007,8 +1006,7 @@ static zend_class_entry *register_class_GdFont(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GdFont", class_GdFont_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/gd/tests/bug72709.phpt b/ext/gd/tests/bug72709.phpt index 7ea80df9a78e4..b0b4aa77bdf92 100644 --- a/ext/gd/tests/bug72709.phpt +++ b/ext/gd/tests/bug72709.phpt @@ -18,5 +18,5 @@ imagedestroy($im); ?> ====DONE==== --EXPECT-- -imagesetstyle(): Argument #2 ($style) cannot be empty +imagesetstyle(): Argument #2 ($style) must not be empty ====DONE==== diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 939619bfb3bbc..ebf9bd767180a 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -55,7 +55,7 @@ ZEND_GET_MODULE(php_gettext) zend_argument_value_error(_arg_num, "is too long"); \ RETURN_THROWS(); \ } else if (domain_len == 0) { \ - zend_argument_value_error(_arg_num, "cannot be empty"); \ + zend_argument_must_not_be_empty_error(_arg_num); \ RETURN_THROWS(); \ } @@ -190,11 +190,6 @@ PHP_FUNCTION(bindtextdomain) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) - if (!ZSTR_LEN(domain)) { - zend_argument_value_error(1, "cannot be empty"); - RETURN_THROWS(); - } - if (dir == NULL) { RETURN_STRING(bindtextdomain(ZSTR_VAL(domain), NULL)); } @@ -312,11 +307,6 @@ PHP_FUNCTION(bind_textdomain_codeset) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) - if (!ZSTR_LEN(domain)) { - zend_argument_value_error(1, "cannot be empty"); - RETURN_THROWS(); - } - retval = bind_textdomain_codeset(ZSTR_VAL(domain), codeset ? ZSTR_VAL(codeset) : NULL); if (!retval) { diff --git a/ext/gettext/tests/dcngettext.phpt b/ext/gettext/tests/dcngettext.phpt index 3b8123413e252..16258d6780153 100644 --- a/ext/gettext/tests/dcngettext.phpt +++ b/ext/gettext/tests/dcngettext.phpt @@ -33,6 +33,6 @@ string(1) "1" string(4) "test" string(4) "test" string(4) "test" -dcngettext(): Argument #1 ($domain) cannot be empty -dcngettext(): Argument #1 ($domain) cannot be empty +dcngettext(): Argument #1 ($domain) must not be empty +dcngettext(): Argument #1 ($domain) must not be empty Done diff --git a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt index e6df576edf063..cd07db1a94227 100644 --- a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt +++ b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt @@ -20,8 +20,8 @@ gettext echo "Done\n"; ?> --EXPECT-- -bind_textdomain_codeset(): Argument #1 ($domain) cannot be empty -bind_textdomain_codeset(): Argument #1 ($domain) cannot be empty +bind_textdomain_codeset(): Argument #1 ($domain) must not be empty +bind_textdomain_codeset(): Argument #1 ($domain) must not be empty string(5) "UTF-8" Done --CREDITS-- diff --git a/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt b/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt index f80063bed1105..607460b3c2db0 100644 --- a/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt +++ b/ext/gettext/tests/gettext_bindtextdomain-emptydomain.phpt @@ -15,7 +15,7 @@ try { ?> --EXPECT-- -bindtextdomain(): Argument #1 ($domain) cannot be empty +bindtextdomain(): Argument #1 ($domain) must not be empty --CREDITS-- Till Klampaeckel, till@php.net PHP Testfest Berlin 2009-05-09 diff --git a/ext/gettext/tests/gettext_textdomain-retval.phpt b/ext/gettext/tests/gettext_textdomain-retval.phpt index 96b29c7bf946c..2f2f52d37743b 100644 --- a/ext/gettext/tests/gettext_textdomain-retval.phpt +++ b/ext/gettext/tests/gettext_textdomain-retval.phpt @@ -36,7 +36,7 @@ test test foo textdomain(): Argument #1 ($domain) cannot be zero -textdomain(): Argument #1 ($domain) cannot be empty +textdomain(): Argument #1 ($domain) must not be empty --CREDITS-- Christian Weiske, cweiske@php.net PHP Testfest Berlin 2009-05-09 diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h index 43d6944036888..31927d3e482bc 100644 --- a/ext/gmp/gmp_arginfo.h +++ b/ext/gmp/gmp_arginfo.h @@ -333,8 +333,7 @@ static zend_class_entry *register_class_GMP(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GMP", class_GMP_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 8a1214b3274f7..9d099c2d50b45 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -105,7 +105,7 @@ static struct mhash_bc_entry mhash_to_hash[MHASH_NUM_ALGOS] = { PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo) /* {{{ */ { zend_string *lower = zend_string_tolower(algo); - php_hash_ops *ops = zend_hash_find_ptr(&php_hash_hashtable, lower); + const php_hash_ops *ops = zend_hash_find_ptr(&php_hash_hashtable, lower); zend_string_release(lower); return ops; @@ -121,7 +121,7 @@ PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *o } /* }}} */ -PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context) /* {{{ */ +PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context) /* {{{ */ { php_hash_ops *hash_ops = (php_hash_ops *)ops; @@ -229,7 +229,7 @@ static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) { significant bits first. This allows 32-bit and 64-bit architectures to interchange serialized HashContexts. */ -PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ +PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1; unsigned char *buf = (unsigned char *) hash->context; @@ -331,7 +331,7 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z } /* }}} */ -PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ +PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ { if (hash->ops->serialize_spec) { *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; @@ -635,7 +635,7 @@ PHP_FUNCTION(hash_init) } if (!key || (ZSTR_LEN(key) == 0)) { /* Note: a zero length key is no key at all */ - zend_argument_value_error(3, "cannot be empty when HMAC is requested"); + zend_argument_value_error(3, "must not be empty when HMAC is requested"); RETURN_THROWS(); } } @@ -914,7 +914,7 @@ PHP_FUNCTION(hash_hkdf) } if (ZSTR_LEN(ikm) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/hash/hash_adler32.c b/ext/hash/hash_adler32.c index 3937853fdc317..3898ea60e8775 100644 --- a/ext/hash/hash_adler32.c +++ b/ext/hash/hash_adler32.c @@ -52,7 +52,7 @@ PHP_HASH_API void PHP_ADLER32Final(unsigned char digest[4], PHP_ADLER32_CTX *con context->state = 0; } -PHP_HASH_API int PHP_ADLER32Copy(const php_hash_ops *ops, PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context) +PHP_HASH_API zend_result PHP_ADLER32Copy(const php_hash_ops *ops, const PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context) { copy_context->state = orig_context->state; return SUCCESS; diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index e86ee61b656a2..92a3c40129554 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -282,8 +282,7 @@ static zend_class_entry *register_class_HashContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "HashContext", class_HashContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index 1c3b09c3f2b3c..a770d0b554167 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -84,7 +84,7 @@ PHP_HASH_API void PHP_CRC32BEFinal(unsigned char digest[4], PHP_CRC32_CTX *conte context->state = 0; } -PHP_HASH_API int PHP_CRC32Copy(const php_hash_ops *ops, PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context) +PHP_HASH_API zend_result PHP_CRC32Copy(const php_hash_ops *ops, const PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context) { copy_context->state = orig_context->state; return SUCCESS; diff --git a/ext/hash/hash_murmur.c b/ext/hash/hash_murmur.c index 384133b84bd41..0117b2e57d361 100644 --- a/ext/hash/hash_murmur.c +++ b/ext/hash/hash_murmur.c @@ -75,7 +75,7 @@ PHP_HASH_API void PHP_MURMUR3AFinal(unsigned char digest[4], PHP_MURMUR3A_CTX *c digest[3] = (unsigned char)(ctx->h & 0xff); } -PHP_HASH_API int PHP_MURMUR3ACopy(const php_hash_ops *ops, PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3ACopy(const php_hash_ops *ops, const PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context) { copy_context->h = orig_context->h; copy_context->carry = orig_context->carry; @@ -154,7 +154,7 @@ PHP_HASH_API void PHP_MURMUR3CFinal(unsigned char digest[16], PHP_MURMUR3C_CTX * digest[15] = (unsigned char)(h[3] & 0xff); } -PHP_HASH_API int PHP_MURMUR3CCopy(const php_hash_ops *ops, PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3CCopy(const php_hash_ops *ops, const PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context) { memcpy(©_context->h, &orig_context->h, sizeof orig_context->h); memcpy(©_context->carry, &orig_context->carry, sizeof orig_context->carry); @@ -231,7 +231,7 @@ PHP_HASH_API void PHP_MURMUR3FFinal(unsigned char digest[16], PHP_MURMUR3F_CTX * digest[15] = (unsigned char)(h[1] & 0xff); } -PHP_HASH_API int PHP_MURMUR3FCopy(const php_hash_ops *ops, PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context) +PHP_HASH_API zend_result PHP_MURMUR3FCopy(const php_hash_ops *ops, const PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context) { memcpy(©_context->h, &orig_context->h, sizeof orig_context->h); memcpy(©_context->carry, &orig_context->carry, sizeof orig_context->carry); diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 8a0fddba5b4a6..07da2cfd2d016 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -292,7 +292,7 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ #endif #define PHP_KECCAK_SPEC "b200IiIIB" -static int php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) +static zend_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) { *magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK; return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC); diff --git a/ext/hash/hash_sha_ni.c b/ext/hash/hash_sha_ni.c index 3c98786c73fd2..92a2235e28415 100644 --- a/ext/hash/hash_sha_ni.c +++ b/ext/hash/hash_sha_ni.c @@ -27,7 +27,7 @@ #include "php_hash.h" #include "php_hash_sha.h" -#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_IMMINTRIN_H) +#if defined(PHP_HASH_INTRIN_SHA_NATIVE) || defined(PHP_HASH_INTRIN_SHA_RESOLVER) # include diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 07ac801d99e95..203f3c7d2d9eb 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -69,7 +69,7 @@ PHP_HASH_API void PHP_XXH32Final(unsigned char digest[4], PHP_XXH32_CTX *ctx) XXH32_canonicalFromHash((XXH32_canonical_t*)digest, XXH32_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH32Copy(const php_hash_ops *ops, PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -134,7 +134,7 @@ PHP_HASH_API void PHP_XXH64Final(unsigned char digest[8], PHP_XXH64_CTX *ctx) XXH64_canonicalFromHash((XXH64_canonical_t*)digest, XXH64_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH64Copy(const php_hash_ops *ops, PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH64Copy(const php_hash_ops *ops, const PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -183,7 +183,7 @@ zend_always_inline static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *a return; } else if (_secret) { if (IS_STRING != Z_TYPE_P(_secret)) { - php_error_docref(NULL, E_DEPRECATED, "Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs"); + php_error_docref(NULL, E_DEPRECATED, "Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs"); } zend_string *secret_string = zval_try_get_string(_secret); if (UNEXPECTED(!secret_string)) { @@ -225,7 +225,7 @@ PHP_HASH_API void PHP_XXH3_64_Final(unsigned char digest[8], PHP_XXH3_64_CTX *ct XXH64_canonicalFromHash((XXH64_canonical_t*)digest, XXH3_64bits_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH3_64_Copy(const php_hash_ops *ops, PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; @@ -275,7 +275,7 @@ PHP_HASH_API void PHP_XXH3_128_Final(unsigned char digest[16], PHP_XXH3_128_CTX XXH128_canonicalFromHash((XXH128_canonical_t*)digest, XXH3_128bits_digest(&ctx->s)); } -PHP_HASH_API int PHP_XXH3_128_Copy(const php_hash_ops *ops, PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context) +PHP_HASH_API zend_result PHP_XXH3_128_Copy(const php_hash_ops *ops, const PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context) { copy_context->s = orig_context->s; return SUCCESS; diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 0fd2f5d41f25e..3b058ef48bdb2 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -34,8 +34,8 @@ typedef struct _php_hashcontext_object php_hashcontext_object; typedef void (*php_hash_init_func_t)(void *context, HashTable *args); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); -typedef int (*php_hash_copy_func_t)(const void *ops, void *orig_context, void *dest_context); -typedef int (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); +typedef zend_result (*php_hash_copy_func_t)(const void *ops, const void *orig_context, void *dest_context); +typedef zend_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); typedef struct _php_hash_ops { @@ -147,10 +147,10 @@ extern zend_module_entry hash_module_entry; extern PHP_HASH_API zend_class_entry *php_hashcontext_ce; PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops); -PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context); -PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); +PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context); +PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); -PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); +PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); static inline void *php_hash_alloc_context(const php_hash_ops *ops) { diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index 90953573c6908..bacb47ff1c916 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_ADLER32_H #define PHP_HASH_ADLER32_H -#include "ext/standard/basic_functions.h" - typedef struct { uint32_t state; } PHP_ADLER32_CTX; @@ -27,6 +25,6 @@ typedef struct { PHP_HASH_API void PHP_ADLER32Init(PHP_ADLER32_CTX *context, ZEND_ATTRIBUTE_UNUSED HashTable *args); PHP_HASH_API void PHP_ADLER32Update(PHP_ADLER32_CTX *context, const unsigned char *input, size_t len); PHP_HASH_API void PHP_ADLER32Final(unsigned char digest[4], PHP_ADLER32_CTX *context); -PHP_HASH_API int PHP_ADLER32Copy(const php_hash_ops *ops, PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context); +PHP_HASH_API zend_result PHP_ADLER32Copy(const php_hash_ops *ops, const PHP_ADLER32_CTX *orig_context, PHP_ADLER32_CTX *copy_context); #endif diff --git a/ext/hash/php_hash_crc32.h b/ext/hash/php_hash_crc32.h index 520829387e3b4..b6accea17bb64 100644 --- a/ext/hash/php_hash_crc32.h +++ b/ext/hash/php_hash_crc32.h @@ -30,6 +30,6 @@ PHP_HASH_API void PHP_CRC32BUpdate(PHP_CRC32_CTX *context, const unsigned char * PHP_HASH_API void PHP_CRC32CUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len); PHP_HASH_API void PHP_CRC32LEFinal(unsigned char digest[4], PHP_CRC32_CTX *context); PHP_HASH_API void PHP_CRC32BEFinal(unsigned char digest[4], PHP_CRC32_CTX *context); -PHP_HASH_API int PHP_CRC32Copy(const php_hash_ops *ops, PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context); +PHP_HASH_API zend_result PHP_CRC32Copy(const php_hash_ops *ops, const PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context); #endif diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 45110dfb7b55b..66992b09b976c 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_GOST_H #define PHP_HASH_GOST_H -#include "ext/standard/basic_functions.h" - /* GOST context */ typedef struct { uint32_t state[16]; diff --git a/ext/hash/php_hash_haval.h b/ext/hash/php_hash_haval.h index 7f1fb6bf0fa72..e3a3a31b36851 100644 --- a/ext/hash/php_hash_haval.h +++ b/ext/hash/php_hash_haval.h @@ -17,7 +17,6 @@ #ifndef PHP_HASH_HAVAL_H #define PHP_HASH_HAVAL_H -#include "ext/standard/basic_functions.h" /* HAVAL context. */ typedef struct { uint32_t state[8]; diff --git a/ext/hash/php_hash_murmur.h b/ext/hash/php_hash_murmur.h index b1c326ada225b..6180a9b8f3411 100644 --- a/ext/hash/php_hash_murmur.h +++ b/ext/hash/php_hash_murmur.h @@ -27,7 +27,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3AInit(PHP_MURMUR3A_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3AUpdate(PHP_MURMUR3A_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3AFinal(unsigned char digest[4], PHP_MURMUR3A_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3ACopy(const php_hash_ops *ops, PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3ACopy(const php_hash_ops *ops, const PHP_MURMUR3A_CTX *orig_context, PHP_MURMUR3A_CTX *copy_context); typedef struct { uint32_t h[4]; @@ -39,7 +39,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3CInit(PHP_MURMUR3C_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3CUpdate(PHP_MURMUR3C_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3CFinal(unsigned char digest[16], PHP_MURMUR3C_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3CCopy(const php_hash_ops *ops, PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3CCopy(const php_hash_ops *ops, const PHP_MURMUR3C_CTX *orig_context, PHP_MURMUR3C_CTX *copy_context); typedef struct { uint64_t h[2]; @@ -51,7 +51,7 @@ typedef struct { PHP_HASH_API void PHP_MURMUR3FInit(PHP_MURMUR3F_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_MURMUR3FUpdate(PHP_MURMUR3F_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_MURMUR3FFinal(unsigned char digest[16], PHP_MURMUR3F_CTX *ctx); -PHP_HASH_API int PHP_MURMUR3FCopy(const php_hash_ops *ops, PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context); +PHP_HASH_API zend_result PHP_MURMUR3FCopy(const php_hash_ops *ops, const PHP_MURMUR3F_CTX *orig_context, PHP_MURMUR3F_CTX *copy_context); #endif /* PHP_HASH_MURMUR_H */ diff --git a/ext/hash/php_hash_ripemd.h b/ext/hash/php_hash_ripemd.h index da5621acd7b7e..0065450d21bb2 100644 --- a/ext/hash/php_hash_ripemd.h +++ b/ext/hash/php_hash_ripemd.h @@ -16,7 +16,6 @@ #ifndef PHP_HASH_RIPEMD_H #define PHP_HASH_RIPEMD_H -#include "ext/standard/basic_functions.h" /* RIPEMD context. */ typedef struct { diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index d5282026b96a6..d5b04ddd2f479 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -19,7 +19,6 @@ #define PHP_HASH_SHA_H #include "ext/standard/sha1.h" -#include "ext/standard/basic_functions.h" /* SHA224 context. */ typedef struct { @@ -62,7 +61,9 @@ void SHA256_Transform_sse2(uint32_t state[PHP_STATIC_RESTRICT 8], const uint8_t # elif defined(HAVE_FUNC_ATTRIBUTE_TARGET) # define PHP_HASH_INTRIN_SHA_RESOLVER 1 # endif +#endif +#if defined(PHP_HASH_INTRIN_SHA_NATIVE) || defined(PHP_HASH_INTRIN_SHA_RESOLVER) void SHA256_Transform_shani(uint32_t state[PHP_STATIC_RESTRICT 8], const uint8_t block[PHP_STATIC_RESTRICT 64]); #endif diff --git a/ext/hash/php_hash_sha3.h b/ext/hash/php_hash_sha3.h index b574087f60f4f..8381a8943b4d9 100644 --- a/ext/hash/php_hash_sha3.h +++ b/ext/hash/php_hash_sha3.h @@ -17,8 +17,6 @@ #ifndef PHP_HASH_SHA3_H #define PHP_HASH_SHA3_H -#include "php.h" - typedef struct { #ifdef HAVE_SLOW_HASH3 unsigned char state[200]; // 5 * 5 * sizeof(uint64) diff --git a/ext/hash/php_hash_snefru.h b/ext/hash/php_hash_snefru.h index 217eb8727ef4a..df90e8e469686 100644 --- a/ext/hash/php_hash_snefru.h +++ b/ext/hash/php_hash_snefru.h @@ -21,8 +21,6 @@ * AKA "Xerox Secure Hash Function" */ -#include "ext/standard/basic_functions.h" - /* SNEFRU context */ typedef struct { uint32_t state[16]; diff --git a/ext/hash/php_hash_xxhash.h b/ext/hash/php_hash_xxhash.h index ace70deedb008..f099039f37114 100644 --- a/ext/hash/php_hash_xxhash.h +++ b/ext/hash/php_hash_xxhash.h @@ -28,7 +28,7 @@ typedef struct { PHP_HASH_API void PHP_XXH32Init(PHP_XXH32_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH32Update(PHP_XXH32_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH32Final(unsigned char digest[4], PHP_XXH32_CTX *ctx); -PHP_HASH_API int PHP_XXH32Copy(const php_hash_ops *ops, PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_CTX *orig_context, PHP_XXH32_CTX *copy_context); typedef struct { XXH64_state_t s; @@ -38,7 +38,7 @@ typedef struct { PHP_HASH_API void PHP_XXH64Init(PHP_XXH64_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH64Update(PHP_XXH64_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH64Final(unsigned char digest[8], PHP_XXH64_CTX *ctx); -PHP_HASH_API int PHP_XXH64Copy(const php_hash_ops *ops, PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH64Copy(const php_hash_ops *ops, const PHP_XXH64_CTX *orig_context, PHP_XXH64_CTX *copy_context); #define PHP_XXH3_SECRET_SIZE_MIN XXH3_SECRET_SIZE_MIN #define PHP_XXH3_SECRET_SIZE_MAX 256 @@ -60,14 +60,14 @@ typedef PHP_XXH3_CTX PHP_XXH3_64_CTX; PHP_HASH_API void PHP_XXH3_64_Init(PHP_XXH3_64_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH3_64_Update(PHP_XXH3_64_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH3_64_Final(unsigned char digest[8], PHP_XXH3_64_CTX *ctx); -PHP_HASH_API int PHP_XXH3_64_Copy(const php_hash_ops *ops, PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH3_64_CTX *orig_context, PHP_XXH3_64_CTX *copy_context); typedef PHP_XXH3_CTX PHP_XXH3_128_CTX; PHP_HASH_API void PHP_XXH3_128_Init(PHP_XXH3_128_CTX *ctx, HashTable *args); PHP_HASH_API void PHP_XXH3_128_Update(PHP_XXH3_128_CTX *ctx, const unsigned char *in, size_t len); PHP_HASH_API void PHP_XXH3_128_Final(unsigned char digest[16], PHP_XXH3_128_CTX *ctx); -PHP_HASH_API int PHP_XXH3_128_Copy(const php_hash_ops *ops, PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context); +PHP_HASH_API zend_result PHP_XXH3_128_Copy(const php_hash_ops *ops, const PHP_XXH3_128_CTX *orig_context, PHP_XXH3_128_CTX *copy_context); #endif /* PHP_HASH_XXHASH_H */ diff --git a/ext/hash/tests/hash_hkdf_error.phpt b/ext/hash/tests/hash_hkdf_error.phpt index 60a887d003d01..86aa10a02f351 100644 --- a/ext/hash/tests/hash_hkdf_error.phpt +++ b/ext/hash/tests/hash_hkdf_error.phpt @@ -61,6 +61,6 @@ trycatch_dump( [ValueError] hash_hkdf(): Argument #1 ($algo) must be a valid cryptographic hashing algorithm -- Testing hash_hkdf() function with invalid parameters -- -[ValueError] hash_hkdf(): Argument #2 ($key) cannot be empty +[ValueError] hash_hkdf(): Argument #2 ($key) must not be empty [ValueError] hash_hkdf(): Argument #3 ($length) must be greater than or equal to 0 [ValueError] hash_hkdf(): Argument #3 ($length) must be less than or equal to 5100 diff --git a/ext/hash/tests/hash_init_error.phpt b/ext/hash/tests/hash_init_error.phpt index 4256b570e45b6..560ad4f8e9ae3 100644 --- a/ext/hash/tests/hash_init_error.phpt +++ b/ext/hash/tests/hash_init_error.phpt @@ -47,7 +47,7 @@ hash_init(): Argument #1 ($algo) must be a valid hashing algorithm hash_init(): Argument #1 ($algo) must be a cryptographic hashing algorithm if HMAC is requested -- Testing hash_init() function with HASH_HMAC and no key -- -hash_init(): Argument #3 ($key) cannot be empty when HMAC is requested +hash_init(): Argument #3 ($key) must not be empty when HMAC is requested Deprecated: hash_init(): Passing null to parameter #3 ($key) of type string is deprecated in %s on line %d -hash_init(): Argument #3 ($key) cannot be empty when HMAC is requested +hash_init(): Argument #3 ($key) must not be empty when HMAC is requested diff --git a/ext/hash/tests/xxh3_convert_secret_to_string.phpt b/ext/hash/tests/xxh3_convert_secret_to_string.phpt index a68c4a1422336..a06555e7f73ba 100644 --- a/ext/hash/tests/xxh3_convert_secret_to_string.phpt +++ b/ext/hash/tests/xxh3_convert_secret_to_string.phpt @@ -8,7 +8,7 @@ try { var_dump($x); ?> --EXPECTF-- -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d array(1) { ["secret"]=> int(4) diff --git a/ext/hash/tests/xxhash_secret.phpt b/ext/hash/tests/xxhash_secret.phpt index d450d05786736..4cd6798ef769c 100644 --- a/ext/hash/tests/xxhash_secret.phpt +++ b/ext/hash/tests/xxhash_secret.phpt @@ -49,13 +49,13 @@ foreach (["xxh3", "xxh128"] as $a) { --EXPECTF-- string(67) "xxh3: Only one of seed or secret is to be passed for initialization" -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d string(23) "exception in __toString" string(57) "xxh3: Secret length must be >= 136 bytes, 17 bytes passed" 8028aa834c03557a == 8028aa834c03557a == true string(69) "xxh128: Only one of seed or secret is to be passed for initialization" -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d string(23) "exception in __toString" string(59) "xxh128: Secret length must be >= 136 bytes, 17 bytes passed" 54279097795e7218093a05d4d781cbb9 == 54279097795e7218093a05d4d781cbb9 == true diff --git a/ext/hash/tests/xxhash_seed_deprecation.phpt b/ext/hash/tests/xxhash_seed_deprecation.phpt index 6c9634cade249..773f20a4747bc 100644 --- a/ext/hash/tests/xxhash_seed_deprecation.phpt +++ b/ext/hash/tests/xxhash_seed_deprecation.phpt @@ -23,6 +23,6 @@ Deprecated: hash_init(): Passing a seed of a type other than int is deprecated b Deprecated: hash_init(): Passing a seed of a type other than int is deprecated because it is ignored in %s on line %d -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d -Deprecated: hash_init(): Passing a seed of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d +Deprecated: hash_init(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs in %s on line %d diff --git a/ext/iconv/tests/iconv_basic_001.phpt b/ext/iconv/tests/iconv_basic_001.phpt index 518b8a885ba73..a66d8b6d33037 100644 --- a/ext/iconv/tests/iconv_basic_001.phpt +++ b/ext/iconv/tests/iconv_basic_001.phpt @@ -21,5 +21,5 @@ $string_out = iconv($in_charset, $out_charset, $string_to_translate); var_dump($string_out); ?> ---EXPECT-- -string(15) "Zlutoucky kun\n" +--EXPECTF-- +string(1%d) "Zlutouck%Sy kun\n" diff --git a/ext/intl/breakiterator/breakiterator_arginfo.h b/ext/intl/breakiterator/breakiterator_arginfo.h index 8135a9cace64d..9475f5e987fc6 100644 --- a/ext/intl/breakiterator/breakiterator_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_arginfo.h @@ -156,8 +156,7 @@ static zend_class_entry *register_class_IntlBreakIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlBreakIterator", class_IntlBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval const_DONE_value; @@ -282,8 +281,7 @@ static zend_class_entry *register_class_IntlRuleBasedBreakIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlRuleBasedBreakIterator", class_IntlRuleBasedBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlBreakIterator, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -293,8 +291,7 @@ static zend_class_entry *register_class_IntlCodePointBreakIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlCodePointBreakIterator", class_IntlCodePointBreakIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlBreakIterator, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h index 4642e09c36624..f83c0accf6bf4 100644 --- a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h @@ -21,8 +21,7 @@ static zend_class_entry *register_class_IntlPartsIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlPartsIterator", class_IntlPartsIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlIterator); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlIterator, ZEND_ACC_NOT_SERIALIZABLE); zval const_KEY_SEQUENTIAL_value; ZVAL_LONG(&const_KEY_SEQUENTIAL_value, PARTS_ITERATOR_KEY_SEQUENTIAL); diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 44c5cc16b21c0..9e050539b2e87 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -325,8 +325,7 @@ static zend_class_entry *register_class_IntlCalendar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlCalendar", class_IntlCalendar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FIELD_ERA_value; ZVAL_LONG(&const_FIELD_ERA_value, UCAL_ERA); @@ -570,8 +569,7 @@ static zend_class_entry *register_class_IntlGregorianCalendar(zend_class_entry * zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlGregorianCalendar", class_IntlGregorianCalendar_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlCalendar); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IntlCalendar, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/collator/collator_arginfo.h b/ext/intl/collator/collator_arginfo.h index 451d23eb0a238..3f469b02facd4 100644 --- a/ext/intl/collator/collator_arginfo.h +++ b/ext/intl/collator/collator_arginfo.h @@ -99,8 +99,7 @@ static zend_class_entry *register_class_Collator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Collator", class_Collator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_DEFAULT_VALUE_value; ZVAL_LONG(&const_DEFAULT_VALUE_value, UCOL_DEFAULT); diff --git a/ext/intl/common/common_arginfo.h b/ext/intl/common/common_arginfo.h index dcdf8434b4e70..c5e023ecb8883 100644 --- a/ext/intl/common/common_arginfo.h +++ b/ext/intl/common/common_arginfo.h @@ -179,8 +179,7 @@ static zend_class_entry *register_class_IntlIterator(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlIterator", class_IntlIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 97e93d11e72cc..543108ba27eb1 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -127,4 +127,6 @@ if test "$PHP_INTL" != "no"; then $ext_builddir/transliterator $ext_builddir/uchar ])) + + PHP_ADD_EXTENSION_DEP(intl, date) fi diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index dec7180e62174..8de0e1eff0fc9 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -8,6 +8,7 @@ if (PHP_INTL != "no") { // always build as shared - zend_strtod.c/ICU type conflict EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true, "/I \"" + configure_module_dirname + "\" /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('intl', 'date'); ADD_SOURCES(configure_module_dirname + "/collator", "\ collator_attr.c \ collator_class.c \ diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index 92c00af50ba95..4e02daf9478ad 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -122,8 +122,7 @@ static zend_class_entry *register_class_UConverter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UConverter", class_UConverter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_REASON_UNASSIGNED_value; ZVAL_LONG(&const_REASON_UNASSIGNED_value, UCNV_UNASSIGNED); diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index df1de7d6895f4..b57cb79468f2b 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -145,8 +145,7 @@ static zend_class_entry *register_class_IntlDateFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlDateFormatter", class_IntlDateFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FULL_value; ZVAL_LONG(&const_FULL_value, UDAT_FULL); diff --git a/ext/intl/dateformat/datepatterngenerator_arginfo.h b/ext/intl/dateformat/datepatterngenerator_arginfo.h index fd00ab845df62..14327b0d69f88 100644 --- a/ext/intl/dateformat/datepatterngenerator_arginfo.h +++ b/ext/intl/dateformat/datepatterngenerator_arginfo.h @@ -29,8 +29,7 @@ static zend_class_entry *register_class_IntlDatePatternGenerator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlDatePatternGenerator", class_IntlDatePatternGenerator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 0f067ee73c697..9b2874da05ac6 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -123,8 +123,7 @@ static zend_class_entry *register_class_NumberFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NumberFormatter", class_NumberFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_PATTERN_DECIMAL_value; ZVAL_LONG(&const_PATTERN_DECIMAL_value, UNUM_PATTERN_DECIMAL); diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c index db8765837c193..62ee83f62f9ba 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.c @@ -125,7 +125,7 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(domain) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(domain) > INT32_MAX - 1) { diff --git a/ext/intl/locale/locale_arginfo.h b/ext/intl/locale/locale_arginfo.h index b03c552225298..7bba882d20457 100644 --- a/ext/intl/locale/locale_arginfo.h +++ b/ext/intl/locale/locale_arginfo.h @@ -108,7 +108,7 @@ static zend_class_entry *register_class_Locale(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Locale", class_Locale_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_ACTUAL_LOCALE_value; ZVAL_LONG(&const_ACTUAL_LOCALE_value, ULOC_ACTUAL_LOCALE); diff --git a/ext/intl/msgformat/msgformat_arginfo.h b/ext/intl/msgformat/msgformat_arginfo.h index bc45b5b535de5..74353fbf93ae2 100644 --- a/ext/intl/msgformat/msgformat_arginfo.h +++ b/ext/intl/msgformat/msgformat_arginfo.h @@ -78,8 +78,7 @@ static zend_class_entry *register_class_MessageFormatter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "MessageFormatter", class_MessageFormatter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/intl/normalizer/normalizer_arginfo.h b/ext/intl/normalizer/normalizer_arginfo.h index a7a870a60d55e..5b8d80e3573f8 100644 --- a/ext/intl/normalizer/normalizer_arginfo.h +++ b/ext/intl/normalizer/normalizer_arginfo.h @@ -38,7 +38,7 @@ static zend_class_entry *register_class_Normalizer(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Normalizer", class_Normalizer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_FORM_D_value; ZVAL_LONG(&const_FORM_D_value, NORMALIZER_FORM_D); diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 702412125e594..a4fa30644258c 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1250,7 +1250,7 @@ static zend_class_entry *register_class_IntlException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlException", class_IntlException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/intl/resourcebundle/resourcebundle_arginfo.h b/ext/intl/resourcebundle/resourcebundle_arginfo.h index bfbb3511e62bc..f52de6314aa5d 100644 --- a/ext/intl/resourcebundle/resourcebundle_arginfo.h +++ b/ext/intl/resourcebundle/resourcebundle_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_ResourceBundle(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ResourceBundle", class_ResourceBundle_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); return class_entry; diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index 92475b0ed08d3..c64bf1d451849 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -186,9 +186,9 @@ static zval *resource_bundle_array_fetch( if (offset_str) { if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) { if (offset_arg_num) { - zend_argument_value_error(offset_arg_num, "cannot be empty"); + zend_argument_must_not_be_empty_error(offset_arg_num); } else { - zend_value_error("Offset cannot be empty"); + zend_value_error("Offset must not be empty"); } return NULL; } diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.c b/ext/intl/resourcebundle/resourcebundle_iterator.c index 8e405f0a5868e..c79269e475070 100644 --- a/ext/intl/resourcebundle/resourcebundle_iterator.c +++ b/ext/intl/resourcebundle/resourcebundle_iterator.c @@ -42,7 +42,6 @@ static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator ) resourcebundle_extract_value( &iterator->current, rb ); } else { - // zend_throw_exception( spl_ce_OutOfRangeException, "Running past end of ResourceBundle", 0); ZVAL_UNDEF(&iterator->current); } } diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index d0ba891ea958e..cee17335dcd40 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -62,8 +62,7 @@ static zend_class_entry *register_class_Spoofchecker(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Spoofchecker", class_Spoofchecker_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_SINGLE_SCRIPT_CONFUSABLE_value; ZVAL_LONG(&const_SINGLE_SCRIPT_CONFUSABLE_value, USPOOF_SINGLE_SCRIPT_CONFUSABLE); diff --git a/ext/intl/tests/dateformat_format_variant3.phpt b/ext/intl/tests/dateformat_format_variant3.phpt index 4986c2ff37af3..86582d39229ba 100644 --- a/ext/intl/tests/dateformat_format_variant3.phpt +++ b/ext/intl/tests/dateformat_format_variant3.phpt @@ -3,7 +3,7 @@ datefmt_format_code() --EXTENSIONS-- intl --XFAIL-- -This test assumes wrong data wrt to PDT. It is also too big and needs splitting up. +This test assumes wrong data wrt PDT. It is also too big and needs splitting up. --SKIPIF-- = 52.1'); ?> --FILE-- diff --git a/ext/intl/tests/idn_uts46_errors.phpt b/ext/intl/tests/idn_uts46_errors.phpt index 435d464f7ac3c..1cbf336defa61 100644 --- a/ext/intl/tests/idn_uts46_errors.phpt +++ b/ext/intl/tests/idn_uts46_errors.phpt @@ -48,7 +48,7 @@ var_dump($foo["errors"]==IDNA_ERROR_CONTEXTJ); bad variant: ValueError: idn_to_ascii(): Argument #2 ($flags) must be INTL_IDNA_VARIANT_UTS46 empty domain: -ValueError: idn_to_ascii(): Argument #1 ($domain) cannot be empty +ValueError: idn_to_ascii(): Argument #1 ($domain) must not be empty with error, but no details arg: bool(false) with error, with details arg: diff --git a/ext/intl/tests/resourcebundle_dimension_errors.phpt b/ext/intl/tests/resourcebundle_dimension_errors.phpt index 77f30262008ad..2c2d0839e02fc 100644 --- a/ext/intl/tests/resourcebundle_dimension_errors.phpt +++ b/ext/intl/tests/resourcebundle_dimension_errors.phpt @@ -57,5 +57,5 @@ Error: Cannot use object of type ResourceBundle as array string(7) "default" TypeError: Cannot access offset of type float on ResourceBundle TypeError: Cannot access offset of type stdClass on ResourceBundle -ValueError: Offset cannot be empty +ValueError: Offset must not be empty ValueError: Index must be between -2147483648 and 2147483647 diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index 023346526a00e..b26e594cf930f 100644 --- a/ext/intl/timezone/timezone_arginfo.h +++ b/ext/intl/timezone/timezone_arginfo.h @@ -178,8 +178,7 @@ static zend_class_entry *register_class_IntlTimeZone(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlTimeZone", class_IntlTimeZone_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_DISPLAY_SHORT_value; ZVAL_LONG(&const_DISPLAY_SHORT_value, TimeZone::SHORT); diff --git a/ext/intl/transliterator/transliterator_arginfo.h b/ext/intl/transliterator/transliterator_arginfo.h index ee39917117172..0a53fe9a6b9c4 100644 --- a/ext/intl/transliterator/transliterator_arginfo.h +++ b/ext/intl/transliterator/transliterator_arginfo.h @@ -58,8 +58,7 @@ static zend_class_entry *register_class_Transliterator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Transliterator", class_Transliterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_FORWARD_value; ZVAL_LONG(&const_FORWARD_value, TRANSLITERATOR_FORWARD); diff --git a/ext/intl/uchar/uchar_arginfo.h b/ext/intl/uchar/uchar_arginfo.h index d6217c7f8f8dc..ea70f17658867 100644 --- a/ext/intl/uchar/uchar_arginfo.h +++ b/ext/intl/uchar/uchar_arginfo.h @@ -314,7 +314,7 @@ static zend_class_entry *register_class_IntlChar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IntlChar", class_IntlChar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_UNICODE_VERSION_value; zend_string *const_UNICODE_VERSION_value_str = zend_string_init(U_UNICODE_VERSION, strlen(U_UNICODE_VERSION), 1); diff --git a/ext/json/json_arginfo.h b/ext/json/json_arginfo.h index a02cfd4a78105..e81a78d2b712b 100644 --- a/ext/json/json_arginfo.h +++ b/ext/json/json_arginfo.h @@ -101,7 +101,7 @@ static zend_class_entry *register_class_JsonException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "JsonException", class_JsonException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 1e344cde436ff..de3106601b9c5 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -28,6 +28,7 @@ #include #include "zend_enum.h" #include "zend_property_hooks.h" +#include "zend_lazy_objects.h" static const char digits[] = "0123456789abcdef"; @@ -124,7 +125,8 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } else if (Z_OBJ_P(val)->properties == NULL && Z_OBJ_HT_P(val)->get_properties_for == NULL && Z_OBJ_HT_P(val)->get_properties == zend_std_get_properties - && Z_OBJ_P(val)->ce->num_hooked_props == 0) { + && Z_OBJ_P(val)->ce->num_hooked_props == 0 + && !zend_object_is_lazy(Z_OBJ_P(val))) { /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(val); zend_class_entry *ce = obj->ce; diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index e15635ffe628e..b7db6bbbcf3f0 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1501,7 +1501,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) nlinks = zend_hash_num_elements(Z_ARRVAL_P(link)); if (nlinks == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); ret = 0; goto cleanup; } @@ -2696,7 +2696,7 @@ PHP_FUNCTION(ldap_modify_batch) zend_hash_internal_pointer_reset(Z_ARRVAL_P(modinfo)); num_modvals = zend_hash_num_elements(Z_ARRVAL_P(modinfo)); if (num_modvals == 0) { - zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" cannot be empty", get_active_function_name()); + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must not be empty", get_active_function_name()); RETURN_THROWS(); } diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 369909889be90..0e5409ef53025 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -892,8 +892,7 @@ static zend_class_entry *register_class_LDAP_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "Connection", class_LDAP_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -903,8 +902,7 @@ static zend_class_entry *register_class_LDAP_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "Result", class_LDAP_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -914,8 +912,7 @@ static zend_class_entry *register_class_LDAP_ResultEntry(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "LDAP", "ResultEntry", class_LDAP_ResultEntry_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/ldap/tests/ldap_search_error.phpt b/ext/ldap/tests/ldap_search_error.phpt index 659b8a6c0664b..4e775ad13d66e 100644 --- a/ext/ldap/tests/ldap_search_error.phpt +++ b/ext/ldap/tests/ldap_search_error.phpt @@ -59,7 +59,7 @@ bool(false) Warning: ldap_search(): Array initialization wrong in %s on line %d bool(false) -ldap_search(): Argument #1 ($ldap) cannot be empty +ldap_search(): Argument #1 ($ldap) must not be empty ldap_search(): Argument #2 ($base) must have the same number of elements as the links array ldap_search(): Argument #3 ($filter) must have the same number of elements as the links array ldap_search(): Argument #2 ($base) must be of type string when argument #1 ($ldap) is an LDAP instance diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index 416ae1f136637..d836f0efcba7f 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -9,13 +9,19 @@ if (PHP_LIBXML == "yes") { CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && ADD_EXTENSION_DEP('libxml', 'iconv')) { - EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); - ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); - if (!PHP_LIBXML_SHARED) { - ADD_DEF_FILE("ext\\libxml\\php_libxml2.def"); + if (GREP_HEADER("libxml/xmlversion.h", "#define\\s+LIBXML_VERSION\\s+(\\d+)", PHP_PHP_BUILD + "\\include\\libxml2") && + +RegExp.$1 >= 20904) { + + EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); + ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); + if (!PHP_LIBXML_SHARED) { + ADD_DEF_FILE("ext\\libxml\\php_libxml2.def"); + } + PHP_INSTALL_HEADERS("ext/libxml", "php_libxml.h"); + } else { + WARNING("libxml support can't be enabled, libxml version >= 2.9.4 required"); } - PHP_INSTALL_HEADERS("ext/libxml", "php_libxml.h"); } else { WARNING("libxml support can't be enabled, iconv or libxml are missing") PHP_LIBXML = "no" diff --git a/ext/libxml/libxml_arginfo.h b/ext/libxml/libxml_arginfo.h index 90db5d10d4e06..816d780173c17 100644 --- a/ext/libxml/libxml_arginfo.h +++ b/ext/libxml/libxml_arginfo.h @@ -109,7 +109,7 @@ static zend_class_entry *register_class_LibXMLError(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LibXMLError", class_LibXMLError_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_level_default_value; ZVAL_UNDEF(&property_level_default_value); diff --git a/ext/mbstring/config.m4 b/ext/mbstring/config.m4 index 890287e3ddd78..b526db0b200c0 100644 --- a/ext/mbstring/config.m4 +++ b/ext/mbstring/config.m4 @@ -178,4 +178,5 @@ if test "$PHP_MBSTRING" != "no"; then dnl libmbfl is required PHP_MBSTRING_SETUP_LIBMBFL PHP_MBSTRING_EXTENSION + PHP_ADD_EXTENSION_DEP(mbstring, pcre) fi diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index 37c01b84fd1e2..070d3d73137ac 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -7,6 +7,7 @@ if (PHP_MBSTRING != "no") { if (CHECK_HEADER_ADD_INCLUDE("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED); + ADD_EXTENSION_DEP('mbstring', 'pcre'); STDOUT.WriteLine("Using bundled libmbfl..."); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index a9670684cbda0..1ca160d4740a6 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2238,7 +2238,7 @@ PHP_FUNCTION(mb_substr_count) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(needle) == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -2278,7 +2278,7 @@ PHP_FUNCTION(mb_substr_count) if (ZSTR_LEN(needle_u8) == 0) { zend_string_free(haystack_u8); zend_string_free(needle_u8); - zend_argument_value_error(2, "must not be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } } @@ -5673,7 +5673,7 @@ PHP_FUNCTION(mb_ord) ZEND_PARSE_PARAMETERS_END(); if (str_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -5810,7 +5810,7 @@ PHP_FUNCTION(mb_str_pad) } if (ZSTR_LEN(pad) == 0) { - zend_argument_value_error(3, "must be a non-empty string"); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index c947b5e6f049c..e1a5a10c39938 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -900,7 +900,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) } if (arg_pattern_len == 0) { - zend_argument_value_error(1, "must not be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1468,7 +1468,7 @@ PHP_FUNCTION(mb_ereg_search_init) } if (arg_pattern && arg_pattern_len == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/mbstring/tests/mb_str_pad.phpt b/ext/mbstring/tests/mb_str_pad.phpt index 24f5d45e37d06..2ea118e03fa58 100644 --- a/ext/mbstring/tests/mb_str_pad.phpt +++ b/ext/mbstring/tests/mb_str_pad.phpt @@ -9,27 +9,27 @@ echo "--- Error conditions ---\n"; try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_RIGHT)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_LEFT)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, '', STR_PAD_BOTH)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(mb_str_pad('▶▶', 6, ' ', 123456)); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { - var_dump(mb_str_pad('▶▶', 6, ' ', STR_PAD_BOTH, 'unexisting')); + var_dump(mb_str_pad('▶▶', 6, ' ', STR_PAD_BOTH, 'non-existing')); } catch (ValueError $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } echo "--- Simple ASCII strings ---\n"; @@ -87,11 +87,11 @@ foreach ($tests as $encoding => $test) { ?> --EXPECT-- --- Error conditions --- -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(66) "mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string" -string(90) "mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH" -string(82) "mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "unexisting" given" +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty +ValueError: mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH +ValueError: mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "non-existing" given --- Simple ASCII strings --- string(7) "+Hello+" string(10) "+-World+-+" diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index 631005b64c9be..9f534f29d26ad 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -13,7 +13,7 @@ AC_DEFUN([PHP_MYSQL_SOCKET_SEARCH], [ ; do if test -r $i; then MYSQL_SOCK=$i - break 2 + break fi done diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 9c2d57a8b25ab..de287b347deef 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -96,7 +96,6 @@ * @cvalue CLIENT_FOUND_ROWS */ const MYSQLI_CLIENT_FOUND_ROWS = UNKNOWN; -#ifdef CLIENT_SSL_VERIFY_SERVER_CERT /** * @var int * @cvalue CLIENT_SSL_VERIFY_SERVER_CERT @@ -107,7 +106,6 @@ * @cvalue CLIENT_SSL_DONT_VERIFY_SERVER_CERT */ const MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT = UNKNOWN; -#endif /** * @var int * @cvalue CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS @@ -181,21 +179,6 @@ * @cvalue CURSOR_TYPE_READ_ONLY */ const MYSQLI_CURSOR_TYPE_READ_ONLY = UNKNOWN; -/** - * @var int - * @cvalue CURSOR_TYPE_FOR_UPDATE - */ -const MYSQLI_CURSOR_TYPE_FOR_UPDATE = UNKNOWN; -/** - * @var int - * @cvalue CURSOR_TYPE_SCROLLABLE - */ -const MYSQLI_CURSOR_TYPE_SCROLLABLE = UNKNOWN; -/** - * @var int - * @cvalue STMT_ATTR_PREFETCH_ROWS - */ -const MYSQLI_STMT_ATTR_PREFETCH_ROWS = UNKNOWN; /* column information */ /** @@ -407,21 +390,19 @@ const MYSQLI_TYPE_CHAR = UNKNOWN; /** * @var int - * @cvalue FIELD_TYPE_INTERVAL + * @cvalue FIELD_TYPE_GEOMETRY */ -const MYSQLI_TYPE_INTERVAL = UNKNOWN; +const MYSQLI_TYPE_GEOMETRY = UNKNOWN; /** * @var int - * @cvalue FIELD_TYPE_GEOMETRY + * @cvalue FIELD_TYPE_VECTOR */ -const MYSQLI_TYPE_GEOMETRY = UNKNOWN; -#ifdef FIELD_TYPE_JSON +const MYSQLI_TYPE_VECTOR = UNKNOWN; /** * @var int * @cvalue FIELD_TYPE_JSON */ const MYSQLI_TYPE_JSON = UNKNOWN; -#endif /** * @var int * @cvalue FIELD_TYPE_NEWDECIMAL @@ -445,14 +426,12 @@ * @deprecated */ const MYSQLI_NO_DATA = UNKNOWN; -#ifdef MYSQL_DATA_TRUNCATED /** * @var int * @cvalue MYSQL_DATA_TRUNCATED * @deprecated */ const MYSQLI_DATA_TRUNCATED = UNKNOWN; -#endif /* reporting */ /** @@ -499,22 +478,18 @@ * @deprecated */ const MYSQLI_SERVER_QUERY_NO_INDEX_USED = UNKNOWN; -#ifdef SERVER_QUERY_WAS_SLOW /** * @var int * @cvalue SERVER_QUERY_WAS_SLOW * @deprecated */ const MYSQLI_SERVER_QUERY_WAS_SLOW = UNKNOWN; -#endif -#ifdef SERVER_PS_OUT_PARAMS /** * @var int * @cvalue SERVER_PS_OUT_PARAMS * @deprecated */ const MYSQLI_SERVER_PS_OUT_PARAMS = UNKNOWN; -#endif /** * @var int @@ -570,14 +545,12 @@ * @deprecated */ const MYSQLI_REFRESH_MASTER = UNKNOWN; -#ifdef REFRESH_BACKUP_LOG /** * @var int * @cvalue REFRESH_BACKUP_LOG * @deprecated */ const MYSQLI_REFRESH_BACKUP_LOG = UNKNOWN; -#endif /** * @var int diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 0a153087923e8..2bc33e4ad673c 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -72,10 +72,8 @@ PHP_FUNCTION(mysqli_autocommit) /* }}} */ /* {{{ mysqli_stmt_bind_param_do_bind */ -static -int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *args, const char * const types, unsigned int num_extra_args) +static enum_func_status mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, uint32_t num_vars, zval *args, const char * const types, unsigned int arg_num) { - unsigned int i; MYSQLND_PARAM_BIND *params; enum_func_status ret = FAIL; @@ -87,7 +85,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a if (!params) { goto end; } - for (i = 0; i < num_vars; i++) { + for (uint32_t i = 0; i < num_vars; i++) { uint8_t type; switch (types[i]) { case 'd': /* Double */ @@ -107,7 +105,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a type = MYSQL_TYPE_VAR_STRING; break; default: - zend_argument_value_error(num_extra_args, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers"); + zend_argument_value_error(arg_num, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers"); ret = FAIL; mysqlnd_stmt_free_param_bind(stmt->stmt, params); goto end; @@ -126,7 +124,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a PHP_FUNCTION(mysqli_stmt_bind_param) { zval *args; - int argc; + uint32_t argc; MY_STMT *stmt; zval *mysql_stmt; char *types; @@ -139,7 +137,7 @@ PHP_FUNCTION(mysqli_stmt_bind_param) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if (!types_len) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } @@ -154,19 +152,17 @@ PHP_FUNCTION(mysqli_stmt_bind_param) RETURN_THROWS(); } - RETVAL_BOOL(!mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, hasThis() ? 1 : 2)); + RETVAL_BOOL(mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, ERROR_ARG_POS(2)) == PASS); MYSQLI_REPORT_STMT_ERROR(stmt->stmt); } /* }}} */ /* {{{ mysqli_stmt_bind_result_do_bind */ -static int -mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc) +static enum_func_status mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, uint32_t argc) { - unsigned int i; MYSQLND_RESULT_BIND *params = mysqlnd_stmt_alloc_result_bind(stmt->stmt); if (params) { - for (i = 0; i < argc; i++) { + for (uint32_t i = 0; i < argc; i++) { ZVAL_COPY_VALUE(¶ms[i].zv, &args[i]); } return mysqlnd_stmt_bind_result(stmt->stmt, params); @@ -179,8 +175,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc) PHP_FUNCTION(mysqli_stmt_bind_result) { zval *args; - int argc; - zend_ulong rc; + uint32_t argc; MY_STMT *stmt; zval *mysql_stmt; @@ -190,13 +185,13 @@ PHP_FUNCTION(mysqli_stmt_bind_result) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); - if ((uint32_t)argc != mysql_stmt_field_count(stmt->stmt)) { + if (argc != mysql_stmt_field_count(stmt->stmt)) { zend_argument_count_error("Number of bind variables doesn't match number of fields in prepared statement"); RETURN_THROWS(); } - rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc); - RETURN_BOOL(!rc); + enum_func_status rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc); + RETURN_BOOL(rc == PASS); } /* }}} */ @@ -207,21 +202,16 @@ PHP_FUNCTION(mysqli_change_user) zval *mysql_link = NULL; char *user, *password, *dbname; size_t user_len, password_len, dbname_len; - zend_ulong rc; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osss!", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len); + enum_func_status rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len); MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - if (rc) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(rc == PASS); } /* }}} */ @@ -1170,45 +1160,20 @@ static int mysqli_options_get_option_zval_type(int option) case MYSQLND_OPT_NET_READ_BUFFER_SIZE: case MYSQLND_OPT_INT_AND_FLOAT_NATIVE: case MYSQL_OPT_CONNECT_TIMEOUT: -#ifdef MYSQL_REPORT_DATA_TRUNCATION - case MYSQL_REPORT_DATA_TRUNCATION: -#endif case MYSQL_OPT_LOCAL_INFILE: case MYSQL_OPT_NAMED_PIPE: -#ifdef MYSQL_OPT_PROTOCOL case MYSQL_OPT_PROTOCOL: -#endif /* MySQL 4.1.0 */ case MYSQL_OPT_READ_TIMEOUT: case MYSQL_OPT_WRITE_TIMEOUT: -#ifdef MYSQL_OPT_GUESS_CONNECTION /* removed in MySQL-8.0 */ - case MYSQL_OPT_GUESS_CONNECTION: - case MYSQL_OPT_USE_EMBEDDED_CONNECTION: - case MYSQL_OPT_USE_REMOTE_CONNECTION: - case MYSQL_SECURE_AUTH: -#endif -#ifdef MYSQL_OPT_RECONNECT - case MYSQL_OPT_RECONNECT: -#endif /* MySQL 5.0.13 */ -#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: -#endif /* MySQL 5.0.23 */ -#ifdef MYSQL_OPT_COMPRESS case MYSQL_OPT_COMPRESS: -#endif /* mysqlnd @ PHP 5.3.2 */ case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS: return IS_LONG; -#ifdef MYSQL_SHARED_MEMORY_BASE_NAME - case MYSQL_SHARED_MEMORY_BASE_NAME: -#endif /* MySQL 4.1.0 */ -#ifdef MYSQL_SET_CLIENT_IP - case MYSQL_SET_CLIENT_IP: -#endif /* MySQL 4.1.1 */ case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: case MYSQL_INIT_COMMAND: case MYSQL_SET_CHARSET_NAME: - case MYSQL_SET_CHARSET_DIR: case MYSQL_SERVER_PUBLIC_KEY: case MYSQL_OPT_LOAD_DATA_LOCAL_DIR: return IS_STRING; @@ -1740,8 +1705,6 @@ PHP_FUNCTION(mysqli_stmt_attr_set) switch (mode_in) { case CURSOR_TYPE_NO_CURSOR: case CURSOR_TYPE_READ_ONLY: - case CURSOR_TYPE_FOR_UPDATE: - case CURSOR_TYPE_SCROLLABLE: break; default: zend_argument_value_error(ERROR_ARG_POS(3), "must be one of the MYSQLI_CURSOR_TYPE_* constants " @@ -1751,18 +1714,9 @@ PHP_FUNCTION(mysqli_stmt_attr_set) mode = mode_in; mode_p = &mode; break; - case STMT_ATTR_PREFETCH_ROWS: - if (mode_in < 1) { - zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS"); - RETURN_THROWS(); - } - mode = mode_in; - mode_p = &mode; - break; default: - zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " - "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + zend_argument_value_error(ERROR_ARG_POS(2), "must be either " + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } @@ -1792,9 +1746,8 @@ PHP_FUNCTION(mysqli_stmt_attr_get) if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) { /* Success corresponds to 0 return value and a non-zero value * should only happen if the attr/option is unknown */ - zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " - "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " - "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + zend_argument_value_error(ERROR_ARG_POS(2), "must be either " + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE"); RETURN_THROWS(); } diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 6e347bafcc417..3613b952780cb 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c904ba3577e74cd390278004de0cf3594eb66f18 */ + * Stub hash: 32baf7b0642af68dea551687bc44ae47d708d810 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -1056,12 +1056,8 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_PERSISTENT); -#if defined(CLIENT_SSL_VERIFY_SERVER_CERT) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT", CLIENT_SSL_VERIFY_SERVER_CERT, CONST_PERSISTENT); -#endif -#if defined(CLIENT_SSL_VERIFY_SERVER_CERT) REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT", CLIENT_SSL_DONT_VERIFY_SERVER_CERT, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS", CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_PERSISTENT); @@ -1075,9 +1071,6 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_PERSISTENT); @@ -1119,18 +1112,14 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_PERSISTENT); -#if defined(FIELD_TYPE_JSON) + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VECTOR", FIELD_TYPE_VECTOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_JSON", FIELD_TYPE_JSON, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(MYSQL_DATA_TRUNCATED) REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_PERSISTENT); @@ -1139,12 +1128,8 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(SERVER_QUERY_WAS_SLOW) REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_PERSISTENT | CONST_DEPRECATED); -#endif -#if defined(SERVER_PS_OUT_PARAMS) REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_PERSISTENT | CONST_DEPRECATED); @@ -1154,9 +1139,7 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_REPLICA", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_PERSISTENT | CONST_DEPRECATED); -#if defined(REFRESH_BACKUP_LOG) REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_PERSISTENT | CONST_DEPRECATED); -#endif REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_PERSISTENT); @@ -1215,8 +1198,7 @@ static zend_class_entry *register_class_mysqli_driver(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_driver", class_mysqli_driver_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_client_info_default_value; ZVAL_UNDEF(&property_client_info_default_value); @@ -1250,7 +1232,7 @@ static zend_class_entry *register_class_mysqli(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli", class_mysqli_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); @@ -1437,7 +1419,7 @@ static zend_class_entry *register_class_mysqli_result(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_result", class_mysqli_result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval property_current_field_default_value; @@ -1478,7 +1460,7 @@ static zend_class_entry *register_class_mysqli_stmt(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_stmt", class_mysqli_stmt_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); @@ -1548,8 +1530,7 @@ static zend_class_entry *register_class_mysqli_warning(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_warning", class_mysqli_warning_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_message_default_value; ZVAL_UNDEF(&property_message_default_value); @@ -1577,8 +1558,7 @@ static zend_class_entry *register_class_mysqli_sql_exception(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "mysqli_sql_exception", class_mysqli_sql_exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, ZEND_ACC_FINAL); zval property_sqlstate_default_value; zend_string *property_sqlstate_default_value_str = zend_string_init("00000", strlen("00000"), 1); diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 425f543d630c0..365c4891a09a7 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -572,7 +572,7 @@ PHP_FUNCTION(mysqli_query) } if (!query_len) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && @@ -1013,7 +1013,7 @@ PHP_FUNCTION(mysqli_begin_transaction) RETURN_THROWS(); } if (name && !name_len) { - zend_argument_value_error(ERROR_ARG_POS(3), "cannot be empty"); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(3)); RETURN_THROWS(); } @@ -1037,7 +1037,7 @@ PHP_FUNCTION(mysqli_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } @@ -1061,7 +1061,7 @@ PHP_FUNCTION(mysqli_release_savepoint) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (name_len == 0) { - zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + zend_argument_must_not_be_empty_error(ERROR_ARG_POS(2)); RETURN_THROWS(); } if (FAIL == mysqlnd_release_savepoint(mysql->mysql, name)) { diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index ec70cb9877fbf..8284812a7991f 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -4,10 +4,8 @@ mysqli_stmt_bind_result (SHOW) mysqli --SKIPIF-- set_charset("latin1")) { /* 5C should be escaped */ diff --git a/ext/mysqli/tests/071.phpt b/ext/mysqli/tests/071.phpt index c5b569a664b0a..8fb150feca264 100644 --- a/ext/mysqli/tests/071.phpt +++ b/ext/mysqli/tests/071.phpt @@ -11,7 +11,6 @@ require_once 'skipifconnectfailure.inc'; require_once 'connect.inc'; $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - $version = $mysql->server_version; var_dump($mysql->query('DO 1')); diff --git a/ext/mysqli/tests/bug45289.phpt b/ext/mysqli/tests/bug45289.phpt index 87256659f74c2..d1591bd9b4035 100644 --- a/ext/mysqli/tests/bug45289.phpt +++ b/ext/mysqli/tests/bug45289.phpt @@ -24,7 +24,7 @@ require_once 'skipifconnectfailure.inc'; if (!$stmt->bind_param('i', $id) || !$stmt->execute()) printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); - if ($res = $link->store_result()) { + if ($link->store_result()) { printf("[004] Can store result!\n"); } else { printf("[004] [%d] %s\n", $link->errno, $link->error); diff --git a/ext/mysqli/tests/bug55283.phpt b/ext/mysqli/tests/bug55283.phpt index 4517e26cc3031..f5473c7c49599 100644 --- a/ext/mysqli/tests/bug55283.phpt +++ b/ext/mysqli/tests/bug55283.phpt @@ -43,8 +43,6 @@ $link->close(); --FILE-- getMessage() . \PHP_EOL; } -$test2 = array(); $test2 = array(); try { $test1 = mysqli_poll($test2, $test3, $tablica, 0); diff --git a/ext/mysqli/tests/bug66124.phpt b/ext/mysqli/tests/bug66124.phpt index 521c17e8fb999..d63f04e63cfd4 100644 --- a/ext/mysqli/tests/bug66124.phpt +++ b/ext/mysqli/tests/bug66124.phpt @@ -16,7 +16,6 @@ $table_create = "CREATE TABLE `test` ( $table_insert = "INSERT INTO `test` SET `id`=?"; $table_select = "SELECT * FROM `test`"; -$table_delete = "DELETE FROM `test`"; $id = '1311200011005001566'; diff --git a/ext/mysqli/tests/bug72489.phpt b/ext/mysqli/tests/bug72489.phpt index e1ed342d44407..0c10bcd19cc48 100644 --- a/ext/mysqli/tests/bug72489.phpt +++ b/ext/mysqli/tests/bug72489.phpt @@ -45,8 +45,6 @@ while ($stmt->fetch()) { echo "Finished 1\n"; -$newArray = array(); - echo "Finished 2\n"; ?> diff --git a/ext/mysqli/tests/bug76386.phpt b/ext/mysqli/tests/bug76386.phpt index 8c4a7a7710b9b..5ff4bb403100b 100644 --- a/ext/mysqli/tests/bug76386.phpt +++ b/ext/mysqli/tests/bug76386.phpt @@ -67,7 +67,7 @@ $link->query('INSERT INTO t_test VALUES ();'); $stmt = $link->prepare('SELECT * FROM t_test;'); if ($stmt) { $stmt->execute(); - $tid = $t = $t2 = $t3 = $t4 = null; + $tid = $t = $t2 = $t4 = null; $stmt->bind_result($tid, $t, $t2, $t4, $t6); while ($stmt->fetch()) { var_dump($t, $t2, $t4, $t6); diff --git a/ext/mysqli/tests/bug81335.phpt b/ext/mysqli/tests/bug81335.phpt new file mode 100644 index 0000000000000..26f6bcd7e2d14 --- /dev/null +++ b/ext/mysqli/tests/bug81335.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #81335: Packets out of order after connection timeout +--EXTENSIONS-- +mysqli +--SKIPIF-- += 8.0.24"); +} +?> +--FILE-- +query('SET WAIT_TIMEOUT=1'); +usleep(1000000 * 1.1); +try { + $mysqli->query('SELECT 1 + 1'); +} catch(mysqli_sql_exception $e) { + echo $e->getMessage(); + echo "\n"; + echo $e->getCode(); +} +?> +--EXPECTF-- +The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. +4031 diff --git a/ext/mysqli/tests/bug_mysql_49406.phpt b/ext/mysqli/tests/bug_mysql_49406.phpt index f9dd11b619bcc..09cc544a12b75 100644 --- a/ext/mysqli/tests/bug_mysql_49406.phpt +++ b/ext/mysqli/tests/bug_mysql_49406.phpt @@ -58,7 +58,6 @@ require_once 'skipifconnectfailure.inc'; MYSQLI_TYPE_STRING => "STRING", MYSQLI_TYPE_NULL => "NULL", MYSQLI_TYPE_NEWDATE => "NEWDATE", - MYSQLI_TYPE_INTERVAL => "INTERVAL", MYSQLI_TYPE_GEOMETRY => "GEOMETRY", ); diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index 18e4902624ee8..9aee7126b3eb3 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -16,14 +16,10 @@ $db = getenv("MYSQL_TEST_DB") ?: "test"; $engine = getenv("MYSQL_TEST_ENGINE") ?: "InnoDB"; $socket = getenv("MYSQL_TEST_SOCKET") ?: null; - $skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ?: true; if ($socket) { ini_set('mysqli.default_socket', $socket); } - /* Development setting: test experimental features and/or feature requests that never worked before? */ - $TEST_EXPERIMENTAL = 1 == getenv("MYSQL_TEST_EXPERIMENTAL"); - function get_environment_connection_flags(): int { static $connect_flags = null; if ($connect_flags === null) { diff --git a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt index a7383ec48dc16..69fc427001fd0 100644 --- a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt +++ b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt @@ -44,8 +44,6 @@ function func_mysqli_fetch_all( $tmp = mysqli_fetch_all($result, MYSQLI_BOTH); $row = $tmp[0]; - $fields = mysqli_fetch_fields($result); - if ($regexp_comparison) { if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, diff --git a/ext/mysqli/tests/gh14255.phpt b/ext/mysqli/tests/gh14255.phpt index 375eda0c5b52c..bdf63e36dfb24 100644 --- a/ext/mysqli/tests/gh14255.phpt +++ b/ext/mysqli/tests/gh14255.phpt @@ -16,13 +16,13 @@ mysqli_report(MYSQLI_REPORT_STRICT|MYSQLI_REPORT_ERROR); $mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $ca = $mysqli->query('SELECT 1 '); -$c = $ca->fetch_assoc(); +$ca->fetch_assoc(); try { $mysqli->query('SELECT non_existent_column'); } catch (Exception $e) { echo "Caught exception"."\n"; } -$c = $ca->fetch_assoc(); +$ca->fetch_assoc(); print "done!"; ?> diff --git a/ext/mysqli/tests/gh15432.phpt b/ext/mysqli/tests/gh15432.phpt new file mode 100644 index 0000000000000..5428fb2d14168 --- /dev/null +++ b/ext/mysqli/tests/gh15432.phpt @@ -0,0 +1,64 @@ +--TEST-- +Bug GH-15432 (Heap corruption when querying a vector/PHP crashes when processing a MySQL DB query with a new Vector format introduced in MySQL 9.0) +--EXTENSIONS-- +mysqli +--SKIPIF-- +server_version < 90000 || $link->server_version >= 10_00_00) { + die("skip MySQL 9.0.0+ needed"); +} +?> +--FILE-- +fetch_column(); +$value = bin2hex($result); +if($value !== $expected) { + printf("[001] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($value), $value); +} + +// Binary protocol +$result = $link->execute_query("SELECT vectorfield FROM test")->fetch_column(); +$value = bin2hex($result); +if($value !== $expected) { + printf("[002] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($value), $value); +} + +// Testing inverse to make sure the value hasn't been changed +$expected = '[2.00000e+00,3.00000e+00,5.00000e+00]'; +$result = $link->execute_query("SELECT VECTOR_TO_STRING(0x". $value .")")->fetch_column(); +if($result !== $expected) { + printf("[002] Expecting %s/%s, got %s/%s\n", + gettype($expected), $expected, + gettype($result), $result); +} + +echo "OK"; +?> +--CLEAN-- + +--EXPECT-- +OK diff --git a/ext/mysqli/tests/gh9590.phpt b/ext/mysqli/tests/gh9590.phpt index df373f7d3b319..7f795e774229d 100644 --- a/ext/mysqli/tests/gh9590.phpt +++ b/ext/mysqli/tests/gh9590.phpt @@ -5,11 +5,8 @@ mysqli posix --SKIPIF-- real_query("SELECT ( UNION ALL SELECT 2 ) FROM dual"); -$result = new mysqli_result($mysqli); +new mysqli_result($mysqli); // now make sure the errors are thrown when not using silent mode mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); @@ -65,7 +65,7 @@ $mysqli->real_query("SELECT ( SELECT 2 ) FROM dual"); try { - $result = new mysqli_result($mysqli); + new mysqli_result($mysqli); } catch (mysqli_sql_exception $e) { echo $e->getMessage()."\n"; } diff --git a/ext/mysqli/tests/mysqli_affected_rows.phpt b/ext/mysqli/tests/mysqli_affected_rows.phpt index 2547720b31462..3a56884d148b2 100644 --- a/ext/mysqli/tests/mysqli_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows.phpt @@ -78,8 +78,7 @@ mysqli if (1 !== ($tmp = mysqli_affected_rows($link))) printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); - $charsets = array('utf8'); - foreach ($charsets as $k => $charset) { + foreach (['utf8'] as $charset) { if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $charset)))) continue; mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_begin_transaction.phpt b/ext/mysqli/tests/mysqli_begin_transaction.phpt index 7a7d7e36fba4e..87663ec211d0a 100644 --- a/ext/mysqli/tests/mysqli_begin_transaction.phpt +++ b/ext/mysqli/tests/mysqli_begin_transaction.phpt @@ -4,12 +4,8 @@ mysqli_begin_transaction() mysqli --SKIPIF-- errno, $link->error)); ?> @@ -31,7 +27,7 @@ if (!have_innodb($link)) /* overrule autocommit */ if (true !== ($tmp = mysqli_begin_transaction($link))) - printf("[011] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[011] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -72,7 +68,7 @@ if (!have_innodb($link)) } else if (!mysqli_commit($link)) { printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } else { - $res = mysqli_query($link, "SELECT id FROM test WHERE id = 2"); + mysqli_query($link, "SELECT id FROM test WHERE id = 2"); } } diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt deleted file mode 100644 index 3026cb369b317..0000000000000 --- a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt +++ /dev/null @@ -1,106 +0,0 @@ ---TEST-- -mysqli_change_user() - GET_LOCK() ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---INI-- -max_execution_time=240 ---FILE-- - ---CLEAN-- - ---EXPECTF-- -Testing GET_LOCK()... -... lock 'phptest_%d' acquired by thread %d -... calling IS_USED_LOCK() on 'phptest_%d' using thread '%d' -... calling IS_FREE_LOCK() on 'phptest_%d' using thread '%d' -... calling IS_USED_LOCK() on 'phptest_%d' using new connection with thread '%d' -done! diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt index 36f5ec0329ca3..f758fa8d16446 100644 --- a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -5,7 +5,6 @@ mysqli --SKIPIF-- --FILE-- = 10_00_00) = 50600 && mysqli_get_server_version($link) < 10_00_00) die("SKIP For MySQL < 5.6.0"); ?> @@ -17,9 +13,6 @@ if (mysqli_get_server_version($link) >= 50600 && mysqli_get_server_version($link = 50600) change_user($user . '_unknown_really', $passwd . 'non_empty', $db))) diff --git a/ext/mysqli/tests/mysqli_change_user_rollback.phpt b/ext/mysqli/tests/mysqli_change_user_rollback.phpt index bcef28cd1d51c..2185a3083d6f7 100644 --- a/ext/mysqli/tests/mysqli_change_user_rollback.phpt +++ b/ext/mysqli/tests/mysqli_change_user_rollback.phpt @@ -30,7 +30,7 @@ if (!have_innodb($link)) $num = $row['_num']; assert($num > 0); - if (!$res = mysqli_query($link, 'DELETE FROM test')) + if (false === mysqli_query($link, 'DELETE FROM test')) printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) diff --git a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt index 46ccbf61a9da3..0c0b012d8702c 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt @@ -15,7 +15,7 @@ require_once 'skipifconnectfailure.inc'; printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($mysqli))); sort($variables); - foreach ($variables as $k => $var) { + foreach ($variables as $var) { try { printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); } catch (Error $exception) { @@ -25,7 +25,7 @@ require_once 'skipifconnectfailure.inc'; printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($mysqli)); - foreach ($variables as $k => $var) { + foreach ($variables as $var) { try { printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); } catch (Error $exception) { diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt index 4e23de5cab541..1a2a6c9718dc0 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -69,12 +69,12 @@ require_once 'skipifconnectfailure.inc'; printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($mysqli_result))); sort($variables); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($mysqli_result)); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nMagic, magic properties:\n"); @@ -121,22 +121,19 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_query($link, "SELECT id FROM test ORDER BY id")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $res = new mysqli_result($link); - $res = new mysqli_result($link, MYSQLI_STORE_RESULT); - $res = new mysqli_result($link, MYSQLI_USE_RESULT); + new mysqli_result($link); + new mysqli_result($link, MYSQLI_STORE_RESULT); + new mysqli_result($link, MYSQLI_USE_RESULT); $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); do { $mode = mt_rand(-1000, 1000); } while (in_array($mode, $valid)); - if ($TEST_EXPERIMENTAL) { - ob_start(); - $res = new mysqli_result($link, $mode); - $content = ob_get_contents(); - ob_end_clean(); - if (!stristr($content, 'Invalid value for resultmode')) - printf("[009] Expecting warning because of invalid resultmode\n"); + try { + new mysqli_result($link, $mode); + } catch (ValueError $ex) { + echo $ex->getMessage(), "\n"; } print "done!"; @@ -169,4 +166,5 @@ mysqli_result->unknown = '' Constructor: mysqli_result object is already closed +mysqli_result::__construct(): Argument #2 ($result_mode) must be either MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt index 09d08de7d2957..cc7e36727639d 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt @@ -68,12 +68,12 @@ mysqli printf("\nClass variables:\n"); $variables = array_keys(get_class_vars(get_class($stmt))); sort($variables); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($stmt)); - foreach ($variables as $k => $var) + foreach ($variables as $var) printf("%s\n", $var); printf("\nMagic, magic properties:\n"); diff --git a/ext/mysqli/tests/mysqli_connect.phpt b/ext/mysqli/tests/mysqli_connect.phpt index cf276d6886f67..ad903c9e1e5dd 100644 --- a/ext/mysqli/tests/mysqli_connect.phpt +++ b/ext/mysqli/tests/mysqli_connect.phpt @@ -10,15 +10,13 @@ require_once 'skipifconnectfailure.inc'; true, "MYSQLI_TYPE_ENUM" => true, "MYSQLI_TYPE_SET" => true, + "MYSQLI_TYPE_VECTOR" => true, + "MYSQLI_TYPE_JSON" => true, "MYSQLI_TYPE_TINY_BLOB" => true, "MYSQLI_TYPE_MEDIUM_BLOB" => true, "MYSQLI_TYPE_LONG_BLOB" => true, @@ -73,7 +75,6 @@ $expected_constants = array( "MYSQLI_TYPE_VAR_STRING" => true, "MYSQLI_TYPE_STRING" => true, "MYSQLI_TYPE_CHAR" => true, - "MYSQLI_TYPE_INTERVAL" => true, "MYSQLI_TYPE_GEOMETRY" => true, "MYSQLI_NO_DATA" => true, "MYSQLI_REPORT_INDEX" => true, @@ -107,7 +108,6 @@ $expected_constants['MYSQLI_STORE_RESULT_COPY_DATA'] = true; $expected_constants['MYSQLI_REFRESH_BACKUP_LOG'] = true; -$version = 50007 + 1; $expected_constants['MYSQLI_OPT_NET_CMD_BUFFER_SIZE'] = true; $expected_constants['MYSQLI_OPT_NET_READ_BUFFER_SIZE'] = true; $expected_constants['MYSQLI_ASYNC'] = true; @@ -134,12 +134,6 @@ $expected_constants = array_merge($expected_constants, array( "MYSQLI_STMT_ATTR_CURSOR_TYPE" => true, "MYSQLI_CURSOR_TYPE_NO_CURSOR" => true, "MYSQLI_CURSOR_TYPE_READ_ONLY" => true, - "MYSQLI_CURSOR_TYPE_FOR_UPDATE" => true, - "MYSQLI_CURSOR_TYPE_SCROLLABLE" => true, -)); - -$expected_constants = array_merge($expected_constants, array( - "MYSQLI_STMT_ATTR_PREFETCH_ROWS" => true, )); $expected_constants['MYSQLI_OPT_SSL_VERIFY_SERVER_CERT'] = true; @@ -150,11 +144,9 @@ $expected_constants["MYSQLI_DATA_TRUNCATED"] = true; $expected_constants["MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true; $expected_constants["MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true; -$expected_constants["MYSQLI_TYPE_JSON"] = true; - $unexpected_constants = array(); -foreach ($constants as $group => $consts) { +foreach ($constants as $consts) { foreach ($consts as $name => $value) { if (stristr($name, 'mysqli')) { $name = strtoupper($name); diff --git a/ext/mysqli/tests/mysqli_debug_control_string.phpt b/ext/mysqli/tests/mysqli_debug_control_string.phpt index b745ed2ebce8b..a589155c2a98e 100644 --- a/ext/mysqli/tests/mysqli_debug_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_control_string.phpt @@ -31,7 +31,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) return false; } - if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + if (false === mysqli_query($link, 'SELECT * FROM test')) { printf("[%03d][control string '%s'] [%d] %s.\n", $offset + 2, $control_string, diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt index e46f4aed19845..b6876e31f1a8e 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt @@ -40,7 +40,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) mysqli_error($link)); return false; } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -97,7 +97,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // -t,[N] - maximum nesting level $trace = try_control_string($link, 't,1:n:O,' . $trace_file, $trace_file, 70); $lines = explode("\n", $trace); - foreach ($lines as $k => $line) { + foreach ($lines as $line) { $line = trim($line); if (!preg_match("@^(\d+):+@ismU", $line, $matches)) { printf("[075] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($line, 0, 80)); @@ -113,7 +113,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // omitting t $trace = try_control_string($link, 'n:O,' . $trace_file, $trace_file, 80); $lines = explode("\n", $trace); - foreach ($lines as $k => $line) { + foreach ($lines as $line) { $line = trim($line); if (preg_match("@^[|\s]*>[\w]+@ism", $line, $matches)) { printf("[085] Looks like a function call, but there should be none in the trace file, first characters from trace are '%s'\n", @@ -124,7 +124,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) // -f[,functions] - Limit debugger list to specified functions. Empty list -> all functions $lines_all_funcs = explode("\n", try_control_string($link, 't:O,' . $trace_file, $trace_file, 90)); $functions_all_funcs = array(); - foreach ($lines_all_funcs as $k => $line) { + foreach ($lines_all_funcs as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_all_funcs[$matches[1]] = $matches[1]; @@ -133,7 +133,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", try_control_string($link, 't:f:O,' . $trace_file, $trace_file, 100)); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -169,7 +169,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", try_control_string($link, $control_string, $trace_file, 110)); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index ccee53b02cf92..5327042127c3e 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -39,7 +39,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) mysqli_error($link)); return false; } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -73,7 +73,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", $trace); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -81,7 +81,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) } $found = 0; - foreach ($memory_funcs as $k => $name) + foreach ($memory_funcs as $name) if (isset($functions_trace[$name])) $found++; @@ -97,7 +97,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) $lines_trace = explode("\n", $trace); $functions_trace = array(); - foreach ($lines_trace as $k => $line) { + foreach ($lines_trace as $line) { $line = trim($line); if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { $functions_trace[$matches[1]] = $matches[1]; @@ -105,7 +105,7 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) } $found = 0; - foreach ($memory_funcs as $k => $name) + foreach ($memory_funcs as $name) if (isset($functions_trace[$name])) $found++; diff --git a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt index 40c53827a752a..fba8032823f55 100644 --- a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt +++ b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt @@ -10,9 +10,6 @@ require_once 'skipifconnectfailure.inc'; errno)) printf("[001] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_error_oo.phpt b/ext/mysqli/tests/mysqli_error_oo.phpt index 2e8473bb53ed0..4f1a971043f91 100644 --- a/ext/mysqli/tests/mysqli_error_oo.phpt +++ b/ext/mysqli/tests/mysqli_error_oo.phpt @@ -10,9 +10,6 @@ require_once 'skipifconnectfailure.inc'; error)) printf("[001] Expecting empty string, got %s/'%s'\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_execute_query.phpt b/ext/mysqli/tests/mysqli_execute_query.phpt index dafb37116c2f3..5730d827a4069 100644 --- a/ext/mysqli/tests/mysqli_execute_query.phpt +++ b/ext/mysqli/tests/mysqli_execute_query.phpt @@ -36,7 +36,7 @@ if (!($tmp = $link->execute_query("SELECT ? AS a, ? AS b, ? AS c", [42, "foo", n assert($tmp->fetch_assoc() === ['a' => '42', 'b' => 'foo', 'c' => null]); // prepare error -if (!($tmp = $link->execute_query("some random gibberish", [1, "foo"]))) { +if (false === $link->execute_query("some random gibberish", [1, "foo"])) { printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt index a5ddf5462a511..36067365ff67b 100644 --- a/ext/mysqli/tests/mysqli_explain_metadata.phpt +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -26,7 +26,7 @@ require_once 'skipifconnectfailure.inc'; $field_names[$name] = gettype($value); } - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) $num_rows++; if (($tmp = mysqli_num_rows($res)) !== $num_rows) { @@ -43,12 +43,12 @@ require_once 'skipifconnectfailure.inc'; $num_fields, gettype($tmp), $tmp); } - foreach ($fields as $k => $field) { + foreach ($fields as $field) { $field->max_length = 0;// change it or we will get diff error if (isset($field_names[$field->name])) { unset($field_names[$field->name]); } else { - printf("[006] Unexpected field '%s', dumping info\n"); + printf("[006] Unexpected field '%s', dumping info\n", $field->name); var_dump($field); } } diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index 6bb2fd80bb12d..8cd3984d70376 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -86,14 +86,14 @@ require_once 'skipifconnectfailure.inc'; return false; } - if (!$link->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + if (!$link->query(sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { // don't bail, engine might not support the datatype return false; } if (is_null($php_value)) { if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { - printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error); + printf("[%04d] [%d] %s - %s\n", $offset + 1, $link->errno, $link->error, $sql); return false; } } else { @@ -104,7 +104,7 @@ require_once 'skipifconnectfailure.inc'; } } else { if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { - printf("[%04di] [%d] %s\n", $offset + 1, $link->errno, $link->error); + printf("[%04di] [%d] %s - %s\n", $offset + 1, $link->errno, $link->error, $sql); return false; } } @@ -121,25 +121,21 @@ require_once 'skipifconnectfailure.inc'; } $row = $tmp[0]; - $fields = mysqli_fetch_fields($res); - - if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { - if ($regexp_comparison) { - if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { - printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, $regexp_comparison, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $link->errno, $link->error); - return false; - } - } else { - if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $link->errno, $link->error); - return false; - } + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; } } diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt index ed1c76f3dedd2..6b3fe79a582b7 100644 --- a/ext/mysqli/tests/mysqli_fetch_array.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array.phpt @@ -31,7 +31,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { - printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link)); + printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } print "[011]\n"; var_dump(mysqli_fetch_array($res, MYSQLI_BOTH)); @@ -39,7 +39,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { printf("[012] Cannot run query, [%d] %s\n", - mysqli_errno($link), $mysqli_error($link)); + mysqli_errno($link), mysqli_error($link)); exit(1); } @@ -61,7 +61,7 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); - function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL, $binary_type = false) { + function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); @@ -109,22 +109,6 @@ require_once 'skipifconnectfailure.inc'; gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); return false; } - } else if ((gettype($php_value) == 'unicode') && $binary_type) { - // Unicode is on and we are told that the MySQL column type is a binary type. - // Don't expect a unicode value from the database, you'll get binary string - if (($row['label'] != $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 5, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); - return false; - } - if (gettype($row['label']) == 'unicode') { - var_dump(mysqli_fetch_field_direct($res, 1), $row['label']); - printf("[%04d] SQL Type: '%s', binary columns are supposed to return binary string and not unicode\n", - $offset + 6, $sql_type); - return false; - } } else { if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 7, diff --git a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt index 4650475e73337..cb11d2793035a 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt @@ -12,7 +12,6 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; // do as much as we can do in 5 seconds - $start = microtime(true); for ($id = 100, $start = microtime(true); (microtime(true) - $start) < 5; $id++) { if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, '%s')", $id, mysqli_real_escape_string($link, chr(65 + ($id % 26)))))) { @@ -52,7 +51,7 @@ require_once 'skipifconnectfailure.inc'; } if ($row[0] !== $row['id']) { printf("[005] Unexpected result row[0] = '%s', row[id] = '%s', [%d] %s\n", - $row[0], $row[id], mysqli_errno($link), mysqli_error($link)); + $row[0], $row['id'], mysqli_errno($link), mysqli_error($link)); break; } diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt index 23ae16cdd2e23..225ac6711bd2c 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -70,14 +70,14 @@ require_once 'skipifconnectfailure.inc'; return false; } - if (!$mysqli->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + if (!$mysqli->query(sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { // don't bail, engine might not support the datatype return false; } if (is_null($php_value)) { if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { - printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + printf("[%04d] [%d] %s - %s\n", $offset + 1, $mysqli->errno, $mysqli->error, $sql); return false; } } else { @@ -88,7 +88,7 @@ require_once 'skipifconnectfailure.inc'; } } else { if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { - printf("[%04di] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + printf("[%04di] [%d] %s - %s\n", $offset + 1, $mysqli->errno, $mysqli->error, $sql); return false; } } @@ -103,27 +103,25 @@ require_once 'skipifconnectfailure.inc'; printf("[%04d] [%d] %s\n", $offset + 3, $mysqli->errno, $mysqli->error); return false; } - $fields = mysqli_fetch_fields($res); - - if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { - if ($regexp_comparison) { - if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { - printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, $regexp_comparison, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); return false; - } - } else { - if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { - printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, - gettype($php_value), $php_value, - gettype($row[1]), $row[1], - gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); - return false; - } } } + return true; } diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index 76b6e6fb1bc30..ff1cbb7a5bc90 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -4,9 +4,8 @@ mysqli_fetch_assoc() - BIT mysqli --SKIPIF-- 'MULTIPLE_KEY PART_KEY', 'col2' => 'PART_KEY'); $create = 'CREATE TABLE test(id INT, '; - foreach ($column_def as $k => $v) { + foreach ($column_def as $v) { $create .= sprintf('%s, ', $v); } $create = sprintf('%s)', substr($create, 0, -2)); @@ -198,7 +198,7 @@ mysqli_close($link); mysqli_errno($link), mysqli_error($link)); } // id column - skip it - $field = mysqli_fetch_field($res); + mysqli_fetch_field($res); while ($field = mysqli_fetch_field($res)) { if (!isset($expected_flags[$field->name])) { printf("[010] Found unexpected field '%s'\n", $field->name); diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt index 041eb16694a7c..feb72cabf7a6c 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -30,7 +30,7 @@ require_once 'skipifconnectfailure.inc'; $sql = sprintf("INSERT INTO test(id) VALUES (%s)", $php_value); if (!mysqli_query($link, $sql)) { - printf("[003] '%s' - '%s' - '%s', [%d] %s\n", $sql_type, $create, $sql, + printf("[003] '%s' - '%s', [%d] %s\n", $sql_type, $sql, mysqli_errno($link), mysqli_error($link)); return false; } @@ -67,7 +67,7 @@ require_once 'skipifconnectfailure.inc'; $datatypes = array( MYSQLI_TYPE_TINY => array('TINYINT', 5), MYSQLI_TYPE_SHORT => array('SMALLINT', 10), - MYSQLI_TYPE_LONG => 'MYSQLI_TYPE_LONG - TODO add testing', + MYSQLI_TYPE_LONG => array('INT', 15), MYSQLI_TYPE_FLOAT => array('FLOAT', '1.3'), MYSQLI_TYPE_DOUBLE => array('DOUBLE', '1.4'), MYSQLI_TYPE_TIMESTAMP => array('TIMESTAMP', '2007-08-20 18:34:00'), @@ -77,31 +77,23 @@ require_once 'skipifconnectfailure.inc'; MYSQLI_TYPE_TIME => array('TIME', '18:41:38'), MYSQLI_TYPE_DATETIME => array('DATETIME', '2007-08-20 18:42:01'), MYSQLI_TYPE_YEAR => array('YEAR', '2007'), - MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'), - // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), - string - // MYSQLI_TYPE_TINY_BLOB => array("TINYBLOB", "I got a tiny blog"), - blob - // MYSQLI_TYPE_MEDIUM_BLOB => array("MEDIUMBLOB", "No blob for masses"), - blob - // MYSQLI_TYPE_LONG_BLOB => array("LONGBLOB", "Small is beautiful?"), - blob - MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), - MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), - MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'), // We cannot test ENUM because every ENUM value is just a plain string => MYSQLI_TYPE_STRING + // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), // We cannot test SET because every SET value is just a plain string => MYSQLI_TYPE_STRING + // MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + // MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), MYSQLI_TYPE_BLOB => array("BLOB", 'silly'), MYSQLI_TYPE_VAR_STRING => array("VARCHAR(32768)", 'varchar'), - MYSQLI_TYPE_STRING => 'MYSQLI_TYPE_STRING - TODO add testing', MYSQLI_TYPE_STRING => array('CHAR(1)', 'a'), - MYSQLI_TYPE_STRING => array("SET('I', 'smash', 'the')", 'smash'), - MYSQLI_TYPE_NULL => 'MYSQLI_TYPE_NULL - TODO add testing', - MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', - MYSQLI_TYPE_INTERVAL => 'MYSQLI_TYPE_INTERVAL - TODO add testing', - MYSQLI_TYPE_GEOMETRY => 'MYSQLI_TYPE_GEOMETRY - TODO add testing', + // MYSQLI_TYPE_NULL => array('CHAR(1) NULL', null), // We cannot test NULL because MySQL doesn't have standalone NULL type, only nullable types + // MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', // This is an internal type, not a real MySQL type + // MYSQLI_TYPE_GEOMETRY => array('GEOMETRY', 'TODO add testing'), + MYSQLI_TYPE_NEWDECIMAL => array('DECIMAL', '1.1'), + MYSQLI_TYPE_BIT => array('BIT', 0), ); - $datatypes[MYSQLI_TYPE_NEWDECIMAL] = array('DECIMAL', '1.1'); - $datatypes[MYSQLI_TYPE_BIT] = array('BIT', 0); - foreach ($datatypes as $php_type => $datatype) { - if (is_array($datatype)) - mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes); + mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes); } mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt index 8a31ae25af3eb..39d7cb861d290 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt @@ -9,13 +9,12 @@ require_once 'skipifconnectfailure.inc'; --FILE-- lengths); - while ($row = $res->fetch_assoc()) + while ($res->fetch_assoc()) var_dump($res->lengths); var_dump($res->lengths); diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt index e6ab9245152fa..28e945db52f68 100644 --- a/ext/mysqli/tests/mysqli_fetch_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -122,7 +122,7 @@ require_once 'skipifconnectfailure.inc'; var_dump($obj = new mysqli_fetch_object_private_constructor(1, 2)); This does not fail. */ - $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b')); + mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b')); mysqli_free_result($res); try { diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index f8ba36edafb4b..f912e993a12ec 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -32,7 +32,6 @@ if (!have_innodb($link)) case 0: /* child */ exit(0); - break; default: /* parent */ @@ -123,8 +122,8 @@ if (!have_innodb($link)) if (!mysqli_query($plink, sprintf($sql, 'stop')) || !mysqli_commit($link)) exit(mysqli_errno($plink)); + exit(0); - break; default: /* parent */ diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index 7718263bc451b..14f655f8b0b23 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -24,13 +24,9 @@ require_once 'skipifconnectfailure.inc'; if (!$res = mysqli_query($link, $sql = sprintf("SHOW CHARACTER SET LIKE '%s'", $character_set_connection))) printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_fetch_assoc($res); - if (empty($tmp)) + if (!mysqli_fetch_assoc($res)) printf("[010] Cannot fetch Maxlen and/or Comment, test will fail: $sql\n"); - $maxlen = (isset($tmp['Maxlen'])) ? $tmp['Maxlen'] : ''; - $comment = (isset($tmp['Description'])) ? $tmp['Description'] : ''; - if (!$res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $collation_connection))) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); $tmp = mysqli_fetch_assoc($res); @@ -49,12 +45,12 @@ require_once 'skipifconnectfailure.inc'; printf("[015] Expecting object/std_class, got %s/%s\n", gettype($charset), $charset); if (!isset($charset->charset) || - !in_array(gettype($charset->charset), array("string", "unicode")) || - ($character_set_connection !== $charset->charset)) + !is_string($charset->charset) || + $character_set_connection !== $charset->charset) printf("[016] Expecting string/%s, got %s/%s\n", $character_set_connection, gettype($charset->charset), $charset->charset); if (!isset($charset->collation) || - !in_array(gettype($charset->collation), array("string", "unicode")) || - ($collation_connection !== $charset->collation)) + !is_string($charset->collation) || + $collation_connection !== $charset->collation) printf("[017] Expecting string/%s, got %s/%s\n", $collation_connection, gettype($charset->collation), $charset->collation); if (!isset($charset->dir) || diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt index a8d509eb62760..17900c5ad6090 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -85,7 +85,7 @@ mysqli.allow_local_infile=1 var_dump($info); - if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (false === my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); exit(1); @@ -112,7 +112,6 @@ mysqli.allow_local_infile=1 // we assume the above as tested and in the following we check only those mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter); - /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */ mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter); @@ -244,7 +243,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); @@ -271,7 +270,7 @@ mysqli.allow_local_infile=1 ++$test_counter, mysqli_errno($link), mysqli_error($link)); for ($i = 0; $i < $num_rows - 1; $i++) - $row = mysqli_fetch_assoc($res); + mysqli_fetch_assoc($res); $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows - 1); $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows - 1); @@ -552,7 +551,7 @@ mysqli.allow_local_infile=1 mysqli_errno($link), mysqli_error($link)); $rows = 0; - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) $rows++; if (0 == $rows) @@ -618,7 +617,6 @@ mysqli.allow_local_infile=1 ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'DROP INDEX'); } - $info = $new_info; // RENAME TABLE if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test")) @@ -641,7 +639,6 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'RENAME TABLE'); } - $info = $new_info; if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test")) printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter, @@ -676,7 +673,6 @@ mysqli.allow_local_infile=1 printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE'); - $info = $new_info; if (!mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats_")) printf("[%03d] CREATE DATABASE failed, [%d] %s\n", ++$test_counter, @@ -694,7 +690,6 @@ mysqli.allow_local_infile=1 printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", ++$test_counter, gettype($new_info), $new_info); mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP DATABASE'); - $info = $new_info; } // CREATE SERVER, ALTER SERVER, DROP SERVER @@ -813,7 +808,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DELETE'); $info = $new_info; - if (!$res = mysqli_query($link, "TRUNCATE TABLE test")) + if (false === mysqli_query($link, "TRUNCATE TABLE test")) printf("[%03d] TRUNCATE failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -855,7 +850,7 @@ mysqli.allow_local_infile=1 printf("[%03d] Cannot insert new records, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + if (false === mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[%03d] Cannot SELECT with mysqli_real_query(), [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -863,7 +858,7 @@ mysqli.allow_local_infile=1 printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) @@ -872,7 +867,7 @@ mysqli.allow_local_infile=1 mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, (string)($info['unbuffered_sets'] + 1), $test_counter, 'mysqli_use_result()'); $info = $new_info; - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + if (false === mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[%03d] Cannot SELECT with mysqli_real_query() II, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); @@ -880,7 +875,7 @@ mysqli.allow_local_infile=1 printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, mysqli_errno($link), mysqli_error($link)); - while ($row = mysqli_fetch_assoc($res)) + while (mysqli_fetch_assoc($res)) ; mysqli_free_result($res); if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) diff --git a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt index aaf4098859132..a302e0bbf9998 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt @@ -29,7 +29,7 @@ require_once 'skipifconnectfailure.inc'; /* fetch all rows but the last one */ for ($i = 0; $i < $num_rows - 1; $i++) - $row = mysqli_fetch_assoc($res); + mysqli_fetch_assoc($res); /* enforce implicit cleaning of the wire and skipping the last row */ mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt deleted file mode 100644 index 08831200648d5..0000000000000 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ /dev/null @@ -1,153 +0,0 @@ ---TEST-- -mysqli_get_warnings() - TODO ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---FILE-- -message)) || ('' == $warning->message)) /* NULL or not there at all */ - printf("[011] Expecting string/not empty, got %s/%s\n", gettype($warning->message), $warning->message); - - if ((!is_string($warning->sqlstate)) || ('' == $warning->sqlstate)) /* NULL or not there at all */ - printf("[012] Expecting string/not empty, got %s/%s\n", gettype($warning->sqlstate), $warning->sqlstate); - - if ((!is_int($warning->errno)) || (0 == $warning->errno)) /* NULL or not there at all */ - printf("[013] Expecting int/not 0, got %s/%s\n", gettype($warning->errno), $warning->errno); - - if (false !== ($tmp = $warning->next())) - printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - - if (!mysqli_query($link, "INSERT INTO test (id) VALUES (1000000), (1000001)")) - printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (($tmp = mysqli_warning_count($link)) !== 2) - printf("[016] Expecting 2 warnings, got %d warnings", $tmp); - - if (!is_object($warning = mysqli_get_warnings($link)) || 'mysqli_warning' != get_class($warning)) { - printf("[017] Expecting object/mysqli_warning, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); - } - - if (true !== ($tmp = $warning->next())) - printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - - if (false !== ($tmp = $warning->next())) - printf("[020] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - mysqli_close($link); - - - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - if (!$mysqli->query("DROP TABLE IF EXISTS t1")) - printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) - printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - $warning = new mysqli_warning($mysqli); - - if (!is_string($warning->message) || ('' == $warning->message)) - printf("[025] Expecting string, got %s/%s", gettype($warning->message), $warning->message); - - if (!$mysqli->query("DROP TABLE t1")) - printf("[026] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - /* Yes, I really want to check if the object property is empty */ - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - $warning = new mysqli_warning($mysqli); - if (false !== ($tmp = $warning->next())) - printf("[028] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - if ('' != ($tmp = $warning->message)) - printf("[029] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); - - $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); - - if (!$mysqli->query("DROP TABLE IF EXISTS t1")) - printf("[031] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) - printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - /* out of range, three warnings */ - if (!$mysqli->query("INSERT IGNORE INTO t1(a) VALUES (65536), (65536), (65536)")) - printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - $warning = new mysqli_warning($mysqli); - $i = 1; - while ($warning->next() && ('' != ($tmp = $warning->message))) { - $i++; - } - if (3 != $i) - printf("[034] Expecting three warnings, got %d warnings\n", $i); - - $stmt = mysqli_stmt_init(); - $warning = new mysqli_warning($stmt); - if (false !== ($tmp = $warning->next())) - printf("[035] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - print "done!"; -?> - ---EXPECT-- -done! diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt index ce1d055075397..6b4c5be41a7d4 100644 --- a/ext/mysqli/tests/mysqli_info.phpt +++ b/ext/mysqli/tests/mysqli_info.phpt @@ -11,43 +11,42 @@ mysqli.allow_local_infile=1 --FILE-- = 100")) + if (false === mysqli_query($link, "UPDATE test SET label = 'b' WHERE id >= 100")) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) printf("[012] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "SELECT 1")) + if (false === mysqli_query($link, "SELECT 1")) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp)) printf("[014] Expecting null, got %s/%s\n", gettype($tmp), $tmp); - mysqli_free_result($res); // NOTE: no LOAD DATA INFILE test if ($dir = sys_get_temp_dir()) { diff --git a/ext/mysqli/tests/mysqli_insert_id.phpt b/ext/mysqli/tests/mysqli_insert_id.phpt index 7a2add8eb31fd..484bfc4b4d90c 100644 --- a/ext/mysqli/tests/mysqli_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_insert_id.phpt @@ -13,25 +13,24 @@ require_once 'skipifconnectfailure.inc'; if (0 !== ($tmp = mysqli_insert_id($link))) printf("[003] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { + if (false === mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (0 !== ($tmp = mysqli_insert_id($link))) printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - mysqli_free_result($res); // no auto_increment column - if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) { + if (false === mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) { printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (0 !== ($tmp = mysqli_insert_id($link))) printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) { + if (false === mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) { printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) { + if (false === mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) { printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (($last_id = mysqli_insert_id($link)) <= 0) @@ -101,13 +100,13 @@ require_once 'skipifconnectfailure.inc'; mysqli_query($link, "UNLOCK TABLE test"); } - if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) { + if (false === mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) { printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (1000 !== ($tmp = mysqli_insert_id($link))) printf("[021] Expecting int/1000, got %s/%s\n", gettype($tmp), $tmp); - if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) { + if (false === mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) { printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } if (1000 >= ($tmp = mysqli_insert_id($link))) diff --git a/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt index d8cdd633121ec..feb890a869e4f 100644 --- a/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt +++ b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt @@ -4,19 +4,7 @@ INSERT and packet overflow mysqli --SKIPIF-- --INI-- memory_limit=256M diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index 19e34caa19f40..0ed58d2ad04aa 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -19,12 +19,10 @@ require_once 'skipifconnectfailure.inc'; if (!$thread_id = mysqli_thread_id($link)) printf("[004] Cannot determine thread id, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_kill($link, $thread_id); - if (!is_bool($tmp)) - printf("[005] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + mysqli_kill($link, $thread_id); if ($res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) - pintf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); var_dump($error = mysqli_error($link)); if (!is_string($error) || ('' === $error)) diff --git a/ext/mysqli/tests/mysqli_more_results.phpt b/ext/mysqli/tests/mysqli_more_results.phpt index 5c1f453cb9b0f..4cf99b801eb4c 100644 --- a/ext/mysqli/tests/mysqli_more_results.phpt +++ b/ext/mysqli/tests/mysqli_more_results.phpt @@ -39,7 +39,7 @@ require_once 'skipifconnectfailure.inc'; // NOTE: if you use mysqli_use_result() with mysqli_more_results() or any other info function, // you must fetch all rows before you can loop to the next result set! // See also the MySQL Reference Manual: mysql_use_result() - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); if (mysqli_more_results($link)) diff --git a/ext/mysqli/tests/mysqli_multi_query.phpt b/ext/mysqli/tests/mysqli_multi_query.phpt index 618ffe2085e3a..69950aec4c04e 100644 --- a/ext/mysqli/tests/mysqli_multi_query.phpt +++ b/ext/mysqli/tests/mysqli_multi_query.phpt @@ -19,7 +19,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; do { $res = mysqli_store_result($link); - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); $i++; @@ -33,7 +33,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) ; mysqli_free_result($res); printf("%d/%d\n", $i, mysqli_insert_id($link)); @@ -46,7 +46,7 @@ require_once 'skipifconnectfailure.inc'; $i = 0; while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { - while ($row = mysqli_fetch_array($res)) + while (mysqli_fetch_array($res)) $i++; mysqli_free_result($res); } @@ -77,7 +77,7 @@ require_once 'skipifconnectfailure.inc'; printf("[015 - %d] [%d] %s\n", $res_num, mysqli_errno($link), mysqli_error($link)); if (count($lengths) != 2) - printf("[016 - %d] Expecting 2 column lengths got %d [%d] %s\n", $res_num, count($lengths)); + printf("[016 - %d] Expecting 2 column lengths got %d\n", $res_num, count($lengths)); foreach ($lengths as $k => $length) if ($length <= 0) @@ -87,7 +87,7 @@ require_once 'skipifconnectfailure.inc'; } if ($num_rows != 1) - printf("[018 - %d] Expecting 1 row, got %d rows\n", $num_rows); + printf("[018 - %d] Expecting 1 row, got %d rows\n", $res_num, $num_rows); $res_num++; diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt index 59a8719cbbe6b..11049dfa09ecb 100644 --- a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -18,7 +18,7 @@ mysqlnd.net_read_timeout=1 printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); } - if (!$res = mysqli_query($link, "SELECT SLEEP(5)")) + if (false === mysqli_query($link, "SELECT SLEEP(5)")) printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_no_reconnect.phpt b/ext/mysqli/tests/mysqli_no_reconnect.phpt index d74f57557b229..929cb1dcd0c23 100644 --- a/ext/mysqli/tests/mysqli_no_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_no_reconnect.phpt @@ -67,7 +67,7 @@ require_once 'skipifconnectfailure.inc'; if (false !== @mysqli_ping($link)) printf("[010] Reconnect should not have happened"); - if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + if (@mysqli_query($link, "SELECT DATABASE() as _dbname")) printf("[011] Executing a query should not be possible, connection should be closed, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -111,7 +111,7 @@ require_once 'skipifconnectfailure.inc'; if (false !== ($tmp = @mysqli_ping($link))) printf("[016] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); - if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + if (@mysqli_query($link, "SELECT DATABASE() as _dbname")) printf("[017] Running a query should not be possible, connection should be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_num_fields.phpt b/ext/mysqli/tests/mysqli_num_fields.phpt index 3022a89115249..cd24d90085c12 100644 --- a/ext/mysqli/tests/mysqli_num_fields.phpt +++ b/ext/mysqli/tests/mysqli_num_fields.phpt @@ -10,7 +10,7 @@ require_once 'skipifconnectfailure.inc'; query("SELECT id FROM test WHERE id = 1")) + if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) { printf("[%03d + 003] [%d] %s\n", $offset, $link->errno, $link->error); return false; + } if (!$row = mysqli_fetch_assoc($res)) { printf("[%03d + 004] [%d] %s\n", $offset, $link->errno, $link->error); diff --git a/ext/mysqli/tests/mysqli_pconn_max_links.phpt b/ext/mysqli/tests/mysqli_pconn_max_links.phpt index 4cf28f6819e0b..88b89228e1116 100644 --- a/ext/mysqli/tests/mysqli_pconn_max_links.phpt +++ b/ext/mysqli/tests/mysqli_pconn_max_links.phpt @@ -29,7 +29,7 @@ mysqli die("skip GRANT failed"); } - if (!($link_pcontest = @my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { + if (!@my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket)) { mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); mysqli_query($link, 'DROP USER pcontest@localhost'); @@ -56,7 +56,7 @@ mysqli.rollback_on_cached_plink=1 !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { printf("[000] Init failed, [%d] %s\n", - mysqli_errno($plink), mysqli_error($plink)); + mysqli_errno($link), mysqli_error($link)); } try { @@ -129,9 +129,10 @@ mysqli.rollback_on_cached_plink=1 var_dump(mysqli_get_links_stats()); // this fails and we have 0 (<= $num_plinks) connections + // Do not remove the variable assignment as it is important that we have 2 active connections if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) printf("[010] Can connect using the old password, [%d] %s\n", - mysqli_connect_errno($link), mysqli_connect_error($link)); + mysqli_connect_errno(), mysqli_connect_error()); echo "After second pconnect:"; var_dump(mysqli_get_links_stats()); @@ -168,6 +169,7 @@ mysqli.rollback_on_cached_plink=1 mysqli_free_result($res); var_dump($row); + // Do not remove the variable assignment as it is important that we have 2 active connections if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) { printf("[015] Can open more persistent connections than allowed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); diff --git a/ext/mysqli/tests/mysqli_phpinfo.phpt b/ext/mysqli/tests/mysqli_phpinfo.phpt index d4a464e99f169..6df4e82dfd543 100644 --- a/ext/mysqli/tests/mysqli_phpinfo.phpt +++ b/ext/mysqli/tests/mysqli_phpinfo.phpt @@ -46,7 +46,7 @@ require_once 'skipifconnectfailure.inc'; 'mysqli.allow_local_infile', 'mysqli.local_infile_directory', 'mysqli.allow_persistent', 'mysqli.max_persistent' ); - foreach ($expected as $k => $entry) + foreach ($expected as $entry) if (!stristr($phpinfo, $entry)) printf("[010] Could not find entry for '%s'\n", $entry); diff --git a/ext/mysqli/tests/mysqli_ping.phpt b/ext/mysqli/tests/mysqli_ping.phpt index ef1a3e055969e..626f2330dcb38 100644 --- a/ext/mysqli/tests/mysqli_ping.phpt +++ b/ext/mysqli/tests/mysqli_ping.phpt @@ -18,7 +18,7 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_ping($link)); // provoke an error to check if mysqli_ping resets it - $res = mysqli_query($link, 'SELECT * FROM unknown_table'); + mysqli_query($link, 'SELECT * FROM unknown_table'); if (!($errno = mysqli_errno($link))) printf("[003] Statement should have caused an error\n"); diff --git a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt index 30325aa044f2b..f95bc99276e24 100644 --- a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt +++ b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt @@ -44,11 +44,11 @@ require_once 'skipifconnectfailure.inc'; mysqli_close($link); $links = array(); - for ($i = 0; $i < count($queries); $i++) { + foreach ($queries as $query) { $link = get_connection(); - if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + if (true !== ($tmp = mysqli_query($link, $query, MYSQLI_ASYNC | MYSQLI_USE_RESULT))) printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); // WARNING KLUDGE NOTE @@ -57,7 +57,7 @@ require_once 'skipifconnectfailure.inc'; usleep(20000); $links[mysqli_thread_id($link)] = array( - 'query' => $queries[$i], + 'query' => $query, 'link' => $link, 'processed' => false, ); @@ -66,7 +66,7 @@ require_once 'skipifconnectfailure.inc'; $saved_errors = array(); do { $poll_links = $poll_errors = $poll_reject = array(); - foreach ($links as $thread_id => $link) { + foreach ($links as $link) { if (!$link['processed']) { $poll_links[] = $link['link']; $poll_errors[] = $link['link']; @@ -93,7 +93,7 @@ require_once 'skipifconnectfailure.inc'; if (is_object($res = mysqli_reap_async_query($link))) { // result set object - while ($row = mysqli_fetch_assoc($res)) { + while (mysqli_fetch_assoc($res)) { // eat up all results ; } @@ -120,9 +120,9 @@ require_once 'skipifconnectfailure.inc'; } if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) - printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + printf("[005] Expecting true got %s/%s\n", gettype($res), var_export($res, true)); if (!$row = mysqli_fetch_row($res)) - printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + printf("[006] Expecting true got %s/%s\n", gettype($row), var_export($row, true)); mysqli_free_result($res); } diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt index 8fcb9b2fbbac4..93cdc77be4005 100644 --- a/ext/mysqli/tests/mysqli_poll_reference.phpt +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -42,7 +42,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! // The behaviour is in line with stream_select(). Be warned, be careful. $links = $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } @@ -73,7 +73,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! $links = $errors = array($mysqli1, $mysqli2); $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } foreach ($links as $link) { @@ -103,7 +103,7 @@ if (mysqli_get_server_version($link) < 50012) // WARNING: All arrays point to the same object - this will give bogus results! $links = array($mysqli1, $mysqli2); $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } foreach ($links as $link) { @@ -133,7 +133,7 @@ if (mysqli_get_server_version($link) < 50012) break; } $links = $errors = $reject = array($mysqli1, $mysqli2); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { continue; } // WARNING: Due to the reference issue none of these should ever fire! @@ -176,7 +176,7 @@ if (mysqli_get_server_version($link) < 50012) } $links = $errors = $reject = $all; ob_start(); - if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + if (0 == mysqli_poll($links, $errors, $reject, 0, 50000)) { $tmp = ob_get_contents(); ob_end_clean(); if ($tmp != '') { @@ -193,7 +193,7 @@ if (mysqli_get_server_version($link) < 50012) } } while ($processed < 2); - $ready = mysqli_poll($links, $errors, $reject, 0, 50000); + mysqli_poll($links, $errors, $reject, 0, 50000); mysqli_close($mysqli1); mysqli_close($mysqli2); diff --git a/ext/mysqli/tests/mysqli_prepare_no_object.phpt b/ext/mysqli/tests/mysqli_prepare_no_object.phpt index c488cbe50591f..7ef3728535fe5 100644 --- a/ext/mysqli/tests/mysqli_prepare_no_object.phpt +++ b/ext/mysqli/tests/mysqli_prepare_no_object.phpt @@ -11,11 +11,11 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; if (false !== ($tmp = mysqli_prepare($link, false))) - printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("a) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); if (false !== ($tmp = mysqli_prepare($link, ''))) - printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("b) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); @@ -23,11 +23,11 @@ require_once 'skipifconnectfailure.inc'; $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); if (false !== ($tmp = $mysqli->prepare(false))) - printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); if (false !== ($tmp = $mysqli->prepare(''))) - printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); print "done!"; diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index adb416708fc06..49324aeb01df0 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -45,7 +45,7 @@ require_once 'skipifconnectfailure.inc'; // let's try to play with stored procedures mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); if (mysqli_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { - $res = mysqli_query($link, 'CALL p(@version)'); + mysqli_query($link, 'CALL p(@version)'); $res = mysqli_query($link, 'SELECT @version AS p_version'); $tmp = mysqli_fetch_assoc($res); @@ -114,7 +114,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) mysqli_close($link); ?> --EXPECTF-- -mysqli_query(): Argument #2 ($query) cannot be empty +mysqli_query(): Argument #2 ($query) must not be empty array(1) { ["valid"]=> string(30) "this is sql but with semicolon" diff --git a/ext/mysqli/tests/mysqli_query_iterators.phpt b/ext/mysqli/tests/mysqli_query_iterators.phpt index ea48fa864db99..91acc529f90cf 100644 --- a/ext/mysqli/tests/mysqli_query_iterators.phpt +++ b/ext/mysqli/tests/mysqli_query_iterators.phpt @@ -25,7 +25,8 @@ require_once 'skipifconnectfailure.inc'; mysqli_free_result($res); try { foreach ($res as $row) { - $row; + echo "Iterating over a closed result set should not work\n"; + var_dump($row); } } catch (Error $exception) { echo $exception->getMessage() . "\n"; diff --git a/ext/mysqli/tests/mysqli_query_stored_proc.phpt b/ext/mysqli/tests/mysqli_query_stored_proc.phpt index dbd22fbb38f43..e9590e4a5540b 100644 --- a/ext/mysqli/tests/mysqli_query_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_query_stored_proc.phpt @@ -107,8 +107,7 @@ END;')) { if (!$res = mysqli_query($link, 'SELECT @version as _vers')) printf("[014] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!$row = mysqli_fetch_assoc($res) || - $row['_vers'] == 'unknown') + if (!($row = mysqli_fetch_assoc($res)) || $row['_vers'] == 'unknown') printf("[015] Results seem wrong, got %s, [%d] %s\n", $row['_vers'], mysqli_errno($link), mysqli_error($link)); @@ -135,8 +134,7 @@ END;')) { if (!$res = mysqli_query($link, 'SELECT @version as _vers')) printf("[021] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!$row = mysqli_fetch_assoc($res) || - $row['_vers'] == 'myversion') + if (!($row = mysqli_fetch_assoc($res)) || $row['_vers'] !== 'myversion') printf("[022] Results seem wrong, got %s, [%d] %s\n", $row['_vers'], mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_query_unicode.phpt b/ext/mysqli/tests/mysqli_query_unicode.phpt index c8c9e052de945..6f01aff57084f 100644 --- a/ext/mysqli/tests/mysqli_query_unicode.phpt +++ b/ext/mysqli/tests/mysqli_query_unicode.phpt @@ -5,11 +5,6 @@ mysqli --SKIPIF-- --FILE-- query("DROP TABLE IF EXISTS test"); $mysqli->query("CREATE TABLE test (`blob` LONGBLOB NOT NULL) ENGINE=MyISAM"); @@ -37,7 +37,7 @@ $mysqli->close(); // Insert with compression enabled: $mysqli = mysqli_init(); -$result = my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS); +my_mysqli_real_connect($mysqli, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS); $data = str_repeat("x", $data_size); $mysqli->query("INSERT INTO $db.test(`blob`) VALUE ('$data')"); diff --git a/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt b/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt index eb6ee00835cda..d5e17d26899bb 100644 --- a/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt +++ b/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt @@ -4,16 +4,10 @@ mysqli_real_escape_string() - big5 mysqli --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- reap_async_query(); + $link->reap_async_query(); } catch (mysqli_sql_exception $exception) { echo $exception->getMessage() . "\n"; } diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index 8c896af7657af..3e02bed816a26 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -36,7 +36,7 @@ if (!have_innodb($link)) /* note that there is no savepoint my... */ if (false !== ($tmp = mysqli_release_savepoint($link, 'my'))) - printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[010] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -46,13 +46,13 @@ if (!have_innodb($link)) printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); if (true !== ($tmp = mysqli_savepoint($link, 'my'))) - printf("[013] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[013] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); $res = mysqli_query($link, "SELECT * FROM test"); var_dump($res->fetch_assoc()); if (true !== ($tmp = mysqli_release_savepoint($link, 'my'))) - printf("[014] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[014] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); print "done!"; ?> @@ -61,7 +61,7 @@ if (!have_innodb($link)) require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_release_savepoint(): Argument #2 ($name) cannot be empty +mysqli_release_savepoint(): Argument #2 ($name) must not be empty array(1) { ["id"]=> string(1) "1" diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index afde537aee4d4..da400ae4eee46 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -55,13 +55,10 @@ require_once 'skipifconnectfailure.inc'; mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); while(mysqli_more_results($link)) { mysqli_next_result($link); - $res = mysqli_store_result($link); + mysqli_store_result($link); } mysqli_next_result($link); - $stmt = mysqli_prepare($link, "SELECT 1"); - mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE); - // Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would // not have been set. If that would be the case, the test would be broken. mysqli_report(MYSQLI_REPORT_OFF); @@ -85,13 +82,10 @@ require_once 'skipifconnectfailure.inc'; mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); while(mysqli_more_results($link)) { mysqli_next_result($link); - $res = mysqli_store_result($link); + mysqli_store_result($link); } mysqli_next_result($link); - $stmt = mysqli_prepare($link, "SELECT 1"); - mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE); - /* Internal macro MYSQL_REPORT_STMT_ERROR */ @@ -211,8 +205,6 @@ require_once 'skipifconnectfailure.inc'; TODO: */ - $log_slow_queries = false; - $log_queries_not_using_indexes = false; mysqli_report(MYSQLI_REPORT_OFF); mysqli_report(MYSQLI_REPORT_INDEX); @@ -227,7 +219,7 @@ require_once 'skipifconnectfailure.inc'; if (!$row = mysqli_fetch_assoc($res)) printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $log_slow_query = ('ON' == $row['Value']); + $log_slow_queries = ('ON' == $row['Value']); if (mysqli_get_server_version($link) >= 50111) { // this might cause a warning - no index used @@ -301,8 +293,6 @@ require_once 'skipifconnectfailure.inc'; !mysqli_query($link, 'DELETE FROM test WHERE id > 50', MYSQLI_USE_RESULT)) printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_thread_id($link); - mysqli_close($link); print "done!"; ?> @@ -334,8 +324,6 @@ Warning: mysqli_next_result(): (%s/%d): You have an error in your SQL syntax; ch Warning: mysqli_store_result(): (%s/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d -Warning: mysqli_stmt_attr_set(): (%s/%d): Not implemented in %s on line %d - Deprecated: Function mysqli_kill() is deprecated since 8.4, use KILL CONNECTION/QUERY SQL statement instead in %s mysqli_kill(): Argument #2 ($process_id) must be greater than 0 diff --git a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt index f0799120742b1..1b9c8601ba7ca 100644 --- a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt +++ b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt @@ -15,7 +15,6 @@ require_once 'skipifconnectfailure.inc'; exit(1); } - $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); $invalidModes = [-1, 152]; foreach ($invalidModes as $mode) { try { diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index 810a0842498eb..f1bc787312fa5 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -36,7 +36,7 @@ if (!have_innodb($link)) /* overrule autocommit */ if (true !== ($tmp = mysqli_savepoint($link, 'my'))) - printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link)); + printf("[010] Got %s - [%d] %s\n", $tmp, mysqli_errno($link), mysqli_error($link)); if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -52,5 +52,5 @@ if (!have_innodb($link)) require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_savepoint(): Argument #2 ($name) cannot be empty +mysqli_savepoint(): Argument #2 ($name) must not be empty done! diff --git a/ext/mysqli/tests/mysqli_select_db.phpt b/ext/mysqli/tests/mysqli_select_db.phpt index 33c55c12409c7..a0c38ebbb676c 100644 --- a/ext/mysqli/tests/mysqli_select_db.phpt +++ b/ext/mysqli/tests/mysqli_select_db.phpt @@ -45,7 +45,7 @@ require_once 'skipifconnectfailure.inc'; } if (!$link->select_db($db)) - printf("[012] Failed to set '%s' as current DB; [%d] %s\n", $link->errno, $link->error); + printf("[012] Failed to set '%s' as current DB; [%d] %s\n", $db, $link->errno, $link->error); if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -81,9 +81,9 @@ require_once 'skipifconnectfailure.inc'; if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) - printf("[018] [%d] %s\n"); + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $row = $res->fetch_assoc(); + $res->fetch_assoc(); $res->free(); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 4dff9668b5315..4a873f65eb439 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -17,7 +17,6 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR mysqli_close($link); } else { die(sprintf("skip Requires character set latin1 or latin2\n")); - mysqli_close($link); } ?> --FILE-- diff --git a/ext/mysqli/tests/mysqli_stat.phpt b/ext/mysqli/tests/mysqli_stat.phpt index d58aa0863d87e..4417cb265b809 100644 --- a/ext/mysqli/tests/mysqli_stat.phpt +++ b/ext/mysqli/tests/mysqli_stat.phpt @@ -17,7 +17,7 @@ require_once 'skipifconnectfailure.inc'; if ((!is_string($tmp = mysqli_stat($link))) || ('' === $tmp)) printf("[004] Expecting non empty string, got %s/'%s', [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysql_error($link)); + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index 942711faa141c..0c6f43e2ee8ba 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -11,9 +11,8 @@ require_once 'skipifconnectfailure.inc'; require 'table.inc'; $valid_attr = array( - "max_length" => MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, - "cursor_type" => MYSQLI_STMT_ATTR_CURSOR_TYPE, - "prefetch_rows" => MYSQLI_STMT_ATTR_PREFETCH_ROWS, + MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, + MYSQLI_STMT_ATTR_CURSOR_TYPE, ); $stmt = mysqli_stmt_init($link); @@ -25,17 +24,17 @@ require_once 'skipifconnectfailure.inc'; echo $e->getMessage() . \PHP_EOL; } - foreach ($valid_attr as $k => $attr) { - /* This can't happen anymore as it only returns int */ - if (false === ($tmp = mysqli_stmt_attr_get($stmt, $attr))) { - printf("[006] Expecting any type, but not boolean/false, got %s/%s for attribute %s/%s\n", - gettype($tmp), $tmp, $k, $attr); + foreach ($valid_attr as $attr) { + try { + mysqli_stmt_attr_get($stmt, $attr); + } catch (Throwable $exception) { + echo $exception->getMessage() . "\n"; } } $stmt->close(); - foreach ($valid_attr as $k => $attr) { + foreach ($valid_attr as $attr) { try { mysqli_stmt_attr_get($stmt, $attr); } catch (Throwable $exception) { @@ -51,8 +50,7 @@ require_once 'skipifconnectfailure.inc'; require_once 'clean_table.inc'; ?> --EXPECT-- -mysqli_stmt_attr_get(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE -mysqli_stmt object is already closed +mysqli_stmt_attr_get(): Argument #2 ($attribute) must be either MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE mysqli_stmt object is already closed mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt deleted file mode 100644 index d125d5d1e8917..0000000000000 --- a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -mysqli_stmt_attr_get() - prefetch ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---FILE-- -close(); - mysqli_close($link); - print "done!"; -?> ---CLEAN-- - ---EXPECT-- -done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 304046919a1ab..f9cd1bac611a9 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -10,15 +10,6 @@ require_once 'skipifconnectfailure.inc'; store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[007] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } @@ -71,9 +60,7 @@ require_once 'skipifconnectfailure.inc'; $stmt->store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[008] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } @@ -91,9 +78,7 @@ require_once 'skipifconnectfailure.inc'; $stmt->store_result(); $res = $stmt->result_metadata(); $fields = $res->fetch_fields(); - $max_lengths = array(); - foreach ($fields as $k => $meta) { - $max_lengths[$meta->name] = $meta->max_length; + foreach ($fields as $meta) { if ($meta->max_length !== 0) printf("[009] max_length should not be set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); } @@ -115,12 +100,6 @@ require_once 'skipifconnectfailure.inc'; echo $e->getMessage() . \PHP_EOL; } - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE))) - printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_SCROLLABLE))) - printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); @@ -175,63 +154,6 @@ require_once 'skipifconnectfailure.inc'; var_dump($results2); } - - // - // MYSQLI_STMT_ATTR_PREFETCH_ROWS - // - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT id, label FROM test"); - // Invalid prefetch value - try { - $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 0); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; - } - - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 1))) - printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->execute(); - $id = $label = NULL; - $stmt->bind_result($id, $label); - $results = array(); - while ($stmt->fetch()) - $results[$id] = $label; - $stmt->close(); - if (empty($results)) - printf("[021] Results should not be empty, subsequent tests will probably fail!\n"); - - /* prefetch is not supported - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT label FROM test"); - if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, -1))) - printf("[022] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - $stmt->close(); - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT label FROM test"); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, PHP_INT_MAX))) - printf("[023] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->close(); - - $stmt = mysqli_stmt_init($link); - $stmt->prepare("SELECT id, label FROM test"); - if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 2))) - printf("[024] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - $stmt->execute(); - $id = $label = NULL; - $stmt->bind_result($id, $label); - $results2 = array(); - while ($stmt->fetch()) - $results2[$id] = $label; - $stmt->close(); - if ($results != $results2) { - printf("[025] Results should not differ. Dumping both result sets.\n"); - var_dump($results); - var_dump($results2); - } - */ - mysqli_close($link); print "done!"; ?> @@ -241,9 +163,8 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- Error: mysqli_stmt object is not fully initialized -mysqli_stmt_attr_set(): Argument #2 ($attribute) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE +mysqli_stmt_attr_set(): Argument #2 ($attribute) must be either MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE mysqli_stmt::attr_set(): Argument #2 ($value) must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH bool(true) mysqli_stmt::attr_set(): Argument #2 ($value) must be one of the MYSQLI_CURSOR_TYPE_* constants for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE -mysqli_stmt::attr_set(): Argument #2 ($value) must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt index 180de7cc43f26..573a88689d667 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -382,14 +382,14 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) printf("[2010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - foreach ($value_list as $k => $values) { + foreach ($value_list as $values) { if (!mysqli_stmt_bind_param($stmt, 'is', $values['id'], $values['label'])) { printf("[2011] bind_param() failed for id = %d, [%d] %s\n", $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); continue; } if (!$stmt->execute()) - printf("[2012] [%d] execute() failed for id = %d, [%d] %s\n", + printf("[2012] execute() failed for id = %d, [%d] %s\n", $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (!$res = mysqli_query($link, sprintf("SELECT label FROM test WHERE id = %d", $values['id']))) @@ -413,7 +413,7 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- The number of variables must match the number of parameters in the prepared statement -mysqli_stmt_bind_param(): Argument #2 ($types) cannot be empty +mysqli_stmt_bind_param(): Argument #2 ($types) must not be empty The number of elements in the type definition string must match the number of bind variables The number of variables must match the number of parameters in the prepared statement The number of elements in the type definition string must match the number of bind variables diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt index 40296ad63d2d4..844d2974af00c 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt @@ -309,7 +309,6 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) printf("[050] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - $types = 'i'; $id = 1; $params = array( 0 => $stmt, diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index 11d8e64e9660e..d4d61380ff2ea 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -80,14 +80,12 @@ require_once 'skipifconnectfailure.inc'; $id = null; if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } for ($id = 1; $id < 4; $id++) { if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } } @@ -97,37 +95,28 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } - $result = mysqli_stmt_result_metadata($stmt); - $bind_res = null; if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - mysqli_stmt_close($stmt); return false; } $num = 0; - $fields = mysqli_fetch_fields($result); while (mysqli_stmt_fetch($stmt)) { - if (!gettype($bind_res)=="unicode") { - if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { - printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", - $offset + 10, $num, - gettype($bind_value), $bind_value, $type_hint, - gettype($bind_res), $bind_res); - mysqli_stmt_close($stmt); - return false; - } + if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { + printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", + $offset + 10, $num, + gettype($bind_value), $bind_value, $type_hint, + gettype($bind_res), $bind_res); + return false; } $num++; } @@ -135,11 +124,9 @@ require_once 'skipifconnectfailure.inc'; if ($num != 3) { printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); - mysqli_stmt_close($stmt); return false; } - mysqli_stmt_close($stmt); return true; } @@ -193,26 +180,20 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); - func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); - func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); - func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9237.21, 600); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", NULL, 620); - func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18467.5, 640); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); // Yes, we need the temporary variable. The PHP casting will foul us otherwise. - $tmp = strval('-99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", '-99999999.99', 680, "double"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); - $tmp = strval('99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", '99999999.99' , 720, "double"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); - $tmp = strval('-99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", '-99999999.99', 760, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); - $tmp = strval('99999999.99'); - func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", '99999999.99', 800, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); // don't care about date() strict TZ warnings... @@ -231,8 +212,8 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", NULL, 1020); $tmp = intval(@date('Y')); - func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); - func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "string"); // YEAR is a string with implicit display width of 4 + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "string"); func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", NULL, 1080); $string255 = func_mysqli_stmt_bind_make_string(255); @@ -284,7 +265,7 @@ require_once 'skipifconnectfailure.inc'; func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, 'string'); if (mysqli_get_server_version($link) >= 50600) - func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", "13:31:34.123456", 1770, "13:31:34"); + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME(6)", "13:31:34.123456", 1770); $stmt = mysqli_stmt_init($link); if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1000, 'z')")) @@ -294,7 +275,7 @@ require_once 'skipifconnectfailure.inc'; try { mysqli_stmt_bind_result($stmt, $id); } catch (\ArgumentCountError $e) { - $e->getMessage() . \PHP_EOL; + echo $e->getMessage() . \PHP_EOL; } mysqli_stmt_close($stmt); @@ -312,4 +293,5 @@ Number of bind variables doesn't match number of fields in prepared statement Number of bind variables doesn't match number of fields in prepared statement int(1) %s(1) "a" +Number of bind variables doesn't match number of fields in prepared statement done! diff --git a/ext/mysqli/tests/mysqli_stmt_close.phpt b/ext/mysqli/tests/mysqli_stmt_close.phpt index d031077009a09..89d278060161c 100644 --- a/ext/mysqli/tests/mysqli_stmt_close.phpt +++ b/ext/mysqli/tests/mysqli_stmt_close.phpt @@ -23,8 +23,7 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); try { mysqli_stmt_close($stmt); @@ -48,8 +47,7 @@ require_once 'skipifconnectfailure.inc'; $link->query('KILL '.mysqli_thread_id($link)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); mysqli_close($link); @@ -69,8 +67,7 @@ require_once 'skipifconnectfailure.inc'; $link->query('KILL '.mysqli_thread_id($link)); - if (true !== ($tmp = mysqli_stmt_close($stmt))) - printf("[017] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); print "done!"; ?> diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index 21f8286cac087..a36daebc7951f 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -33,24 +33,21 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_store_result($stmt)) printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 2))) - printf("[009] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, 2); if (!mysqli_stmt_fetch($stmt)) printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); var_dump($id); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 0))) - printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, 0); if (!mysqli_stmt_fetch($stmt)) printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); var_dump($id); - if (!is_null($tmp = mysqli_stmt_data_seek($stmt, mysqli_stmt_num_rows($stmt) + 100))) - printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_data_seek($stmt, mysqli_stmt_num_rows($stmt) + 100); if (mysqli_stmt_fetch($stmt)) printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt index bdfc9c348ae28..03c070dad482f 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt @@ -52,7 +52,7 @@ if (mysqli_get_server_version($link) < 50503) { if (!mysqli_stmt_close($stmt)) printf("[012] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!$res = $link->query("SELECT 1")) + if (false === $link->query("SELECT 1")) printf("[013] [%d] %s\n", $link->errno, $link->error); } else { diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt index 48e2e6f8dec62..90348833e57f1 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt @@ -17,7 +17,7 @@ require_once 'skipifconnectfailure.inc'; !mysqli_stmt_execute($stmt) || !($result = mysqli_stmt_result_metadata($stmt)) || !mysqli_stmt_bind_result($stmt, $id, $bind_res) || - !($fields = mysqli_fetch_fields($result))) { + [] === mysqli_fetch_fields($result)) { printf("FAIL 1\n"); } while (mysqli_stmt_fetch($stmt)) { @@ -34,7 +34,7 @@ require_once 'skipifconnectfailure.inc'; printf("FAIL 2\n"); } print "OK: 1\n"; - if (!($fields = mysqli_fetch_fields($result))) + if ([] === mysqli_fetch_fields($result)) printf("Aua 3\n"); print "OK: 2\n"; while (mysqli_stmt_fetch($stmt)) { diff --git a/ext/mysqli/tests/mysqli_stmt_free_result.phpt b/ext/mysqli/tests/mysqli_stmt_free_result.phpt index e049e84104776..d512a23ee037b 100644 --- a/ext/mysqli/tests/mysqli_stmt_free_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_free_result.phpt @@ -28,14 +28,12 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); if (!mysqli_stmt_execute($stmt)) printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); if (false !== ($tmp = mysqli_stmt_store_result($stmt))) printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); @@ -54,8 +52,7 @@ require_once 'skipifconnectfailure.inc'; if (true !== ($tmp = mysqli_stmt_store_result($stmt))) printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_free_result($stmt); mysqli_stmt_close($stmt); diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt index bfaf111dd6a80..e043f198bd378 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt @@ -28,9 +28,8 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - // FIXME - different versions return different values ?! - if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) - printf("[006] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -39,7 +38,7 @@ require_once 'skipifconnectfailure.inc'; printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (is_object($tmp = mysqli_stmt_store_result($stmt))) - printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_stmt_close($stmt); @@ -56,15 +55,14 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - // FIXME - different versions return different values ?! - if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) - printf("[013] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[013] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_object($tmp = mysqli_stmt_get_result($stmt))) - printf("[016] NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (! ($tmp = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[016] Expecting mysqli_result, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_free_result($tmp); mysqli_stmt_close($stmt); @@ -83,25 +81,25 @@ require_once 'skipifconnectfailure.inc'; printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (false !== ($tmp = mysqli_stmt_get_result($stmt))) - printf("[020] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[020] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (!mysqli_stmt_execute($stmt)) printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!is_object($tmp = mysqli_stmt_get_result($stmt))) - printf("[024] Expecting object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (! ($tmp = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[024] Expecting mysqli_result, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) { printf("[026] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); printf("[027] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link)); - printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, true)); } if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysqli_stmt_close($stmt); @@ -135,11 +133,11 @@ require_once 'skipifconnectfailure.inc'; $id = NULL; $label = NULL; if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) - printf("[037] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + printf("[037] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, true)); - if (!is_object($tmp = $result = mysqli_stmt_get_result($stmt))) - printf("[038] Expecting array, got %s/%s, [%d] %s\n", - gettype($tmp), var_export($tmp, 1), + if (! ($result = mysqli_stmt_get_result($stmt)) instanceof mysqli_result) + printf("[038] Expecting mysqli_result, got %s/%s, [%d] %s\n", + gettype($result), var_export($result, true), mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (false !== ($tmp = mysqli_stmt_fetch($stmt))) @@ -155,23 +153,23 @@ require_once 'skipifconnectfailure.inc'; $link->real_query('KILL '.mysqli_thread_id($link)); // We kill our own connection so we should get "Query execution was interrupted" - if ($link->errno !== 1317) - printf("[042] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if ($link->errno !== 1317) + printf("[042] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_get_result($stmt))) - printf("[043] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[043] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); - mysqli_stmt_close($stmt); + mysqli_stmt_close($stmt); - try { + try { mysqli_stmt_fetch($stmt); } catch (Error $exception) { echo $exception->getMessage(), "\n"; } - mysqli_close($link); + mysqli_close($link); - print "done!"; + print "done!"; ?> --CLEAN-- query('DROP PROCEDURE IF EXISTS p123')) { printf("[001] [%d] %s\n", $link->error, $link->errno); } diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt index a29da62893fb3..8d73967777a60 100644 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt @@ -23,7 +23,7 @@ require_once 'skipifconnectfailure.inc'; printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (!is_object(($res = mysqli_stmt_result_metadata($stmt)))) - printf("[006] Expecting object, got %s/%s\n", gettype($tmp), $tmp); + printf("[006] Expecting object, got %s/%s\n", gettype($res), $res); if (2 !== ($tmp = mysqli_num_fields($res))) printf("[007] Expecting int/2, got %s/%s, [%d] %s\n", @@ -45,9 +45,7 @@ require_once 'skipifconnectfailure.inc'; var_dump($field0_fetch); - if (!is_array($tmp = mysqli_fetch_fields($res))) - printf("[011] Expecting array, got %s/%s, [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_fields($res); if (empty($tmp[0]) || empty($tmp[1]) || $tmp[0] != $field0_direct) { printf("[012] mysqli_fetch_fields() return value is suspicious\n"); diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt deleted file mode 100644 index fa1e6264107ba..0000000000000 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt +++ /dev/null @@ -1,228 +0,0 @@ ---TEST-- -mysqli_stmt_result_metadata() - non SELECT statements ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---FILE-- - mysqli_num_fields($res), - 'fetch_field' => mysqli_fetch_field($res), - 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), - 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), - 'fetch_fields' => count(mysqli_fetch_fields($res)), - 'field_count' => $res->field_count, - 'field_seek-1' => @mysqli_field_seek($res, -1), - 'field_seek0' => mysqli_field_seek($res, 0), - 'field_tell' => mysqli_field_tell($res), - ); - if (is_object($meta['fetch_field'])) { - $meta['fetch_field']->charsetnr = 'ignore'; - $meta['fetch_field']->flags = 'ignore'; - } - if (is_object($meta['fetch_field_direct0'])) { - $meta['fetch_field_direct0']->charsetnr = 'ignore'; - $meta['fetch_field_direct0']->flags = 'ignore'; - } - if (is_object($meta['fetch_field_direct1'])) { - $meta['fetch_field_direct1']->charsetnr = 'ignore'; - $meta['fetch_field_direct1']->flags = 'ignore'; - } - mysqli_free_result($res); - - if ($meta != $expected_lib) { - printf("[%04d - %s] Metadata differs from expected values\n", - $offset + 5, $sql); - var_dump($meta); - var_dump($expected_lib); - return false; - } - } - - if (!mysqli_stmt_execute($stmt)) { - printf("[%04d - %s] [%d] %s\n", - $offset + 6, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - - $res = mysqli_stmt_get_result($stmt); - if (false === $res && !empty($expected_mysqlnd)) { - printf("[%04d - %s] Expecting resultset [%d] %s\n", - $offset + 7, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } else if (empty($expected_mysqlnd) && false !== $res) { - printf("[%04d - %s] Unexpected resultset [%d] %s\n", - $offset + 8, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - - if (!is_object($res)) { - printf("[%04d - %s] [%d] %s\n", - $offset + 9, $sql, - mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - return false; - } - if ('mysqli_result' != get_class($res)) { - printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n", - $offset + 10, $sql, - get_class($res)); - return false; - } - - $meta_res = array( - 'num_fields' => mysqli_num_fields($res), - 'fetch_field' => mysqli_fetch_field($res), - 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), - 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), - 'fetch_fields' => count(mysqli_fetch_fields($res)), - 'field_count' => mysqli_field_count($link), - 'field_seek-1' => @mysqli_field_seek($res, -1), - 'field_seek0' => mysqli_field_seek($res, 0), - 'field_tell' => mysqli_field_tell($res), - ); - if (is_object($meta_res['fetch_field'])) { - $meta_res['fetch_field']->charsetnr = 'ignore'; - $meta_res['fetch_field']->flags = 'ignore'; - } - if (is_object($meta_res['fetch_field_direct0'])) { - $meta_res['fetch_field_direct0']->charsetnr = 'ignore'; - $meta_res['fetch_field_direct0']->flags = 'ignore'; - } - if (is_object($meta_res['fetch_field_direct1'])) { - $meta_res['fetch_field_direct1']->charsetnr = 'ignore'; - $meta_res['fetch_field_direct1']->flags = 'ignore'; - } - mysqli_free_result($res); - if ($check_mysqlnd && $meta_res != $expected_mysqlnd) { - printf("[%04d - %s] Metadata differs from expected\n", - $offset + 11, $sql); - var_dump($meta_res); - var_dump($expected_mysqlnd); - } else { - if ($meta_res['field_count'] < 1) { - printf("[%04d - %s] Metadata seems wrong, no fields?\n", - $offset + 12, $sql); - var_dump($meta_res); - var_dump(mysqli_fetch_assoc($res)); - } - } - - if ($compare && $meta_res != $meta) { - printf("[%04d - %s] Metadata returned by mysqli_stmt_result_metadata() and mysqli_stmt_get_result() differ\n", - $offset + 13, $sql); - var_dump($meta_res); - var_dump($meta); - } - - mysqli_stmt_close($stmt); - return true; - } - - /* Note: very weak testing, we accept almost any result */ - - testStatement(100, $link, 'ANALYZE TABLE test', array(), array(1), false, false); - testStatement(120, $link, 'OPTIMIZE TABLE test', array(), array(1), false, false); - testStatement(140, $link, 'REPAIR TABLE test', array(), array(1), false, false); - - testStatement(160, $link, 'SHOW AUTHORS', array(), array(1), false, false); - testStatement(180, $link, 'SHOW CHARACTER SET', array(), array(1), false, false); - testStatement(200, $link, 'SHOW COLLATION', array(), array(1), false, false); - testStatement(220, $link, 'SHOW CONTRIBUTORS', array(), array(1), false, false); - testStatement(240, $link, 'SHOW CREATE DATABASE ' . $db, array(), array(1), false, false); - testStatement(260, $link, 'SHOW DATABASES', array(), array(1), false, false); - testStatement(280, $link, 'SHOW ENGINE InnoDB STATUS', array(), array(1), false, false); - testStatement(300, $link, 'SHOW ENGINES', array(), array(1), false, false); - testStatement(320, $link, 'SHOW PLUGINS', array(), array(1), false, false); - testStatement(340, $link, 'SHOW PROCESSLIST', array(), array(1), false, false); - testStatement(360, $link, 'SHOW FULL PROCESSLIST', array(), array(1), false, false); - testStatement(380, $link, 'SHOW STATUS', array(), array(1), false, false); - testStatement(400, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); - testStatement(420, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); - testStatement(440, $link, 'SHOW TABLES', array(), array(1), false, false); - testStatement(460, $link, 'SHOW OPEN TABLES', array(), array(1), false, false); - testStatement(460, $link, 'SHOW VARIABLES', array(), array(1), false, false); - - $field0 = new stdClass(); - $field0->name = 'id'; - $field0->orgname = 'id'; - $field0->table = 'test'; - $field0->orgtable = 'test'; - $field0->def = ''; - $field0->max_length = 0; - $field0->length = 11; - $field0->charsetnr = 'ignore'; - $field0->flags = 'ignore'; - $field0->type = MYSQLI_TYPE_LONG; - $field0->decimals = 0; - $meta_lib = array( - 'num_fields' => 1, - 'fetch_field' => $field0, - 'fetch_field_direct0' => $field0, - 'fetch_field_direct1' => false, - 'fetch_fields' => 1, - 'field_count' => 1, - 'field_seek-1' => false, - 'field_seek0' => true, - 'field_tell' => 0, - ); - $meta_mysqlnd = $meta_lib; - testStatement(480, $link, 'SELECT id FROM test', $meta_lib, $meta_mysqlnd, true, true); - - testStatement(500, $link, 'CHECKSUM TABLE test', array(), array(1), false, false); - - mysqli_close($link); - print "done!"; -?> ---CLEAN-- - ---EXPECT-- -done! diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt index cc4a927270914..dbf8dddb88e41 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt @@ -64,7 +64,7 @@ require_once 'skipifconnectfailure.inc'; assert(strlen($blob) <= $max_allowed_packet); try { - $tmp = mysqli_stmt_send_long_data($stmt, -1, $blob); + mysqli_stmt_send_long_data($stmt, -1, $blob); } catch (\ValueError $e) { echo $e->getMessage() . \PHP_EOL; } diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt index 5c7ffd9c6da46..79cf0aa794507 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt @@ -40,8 +40,6 @@ require_once 'skipifconnectfailure.inc'; // let's ignore upper limits for LONGBLOB (2^32) ... // maximum packet size up to which we test is 10M - $tmp = ''; - $blob = ''; $tmp = str_repeat('a', 1024); $limit = min(floor($max_allowed_packet / 1024 / 2), 10240); diff --git a/ext/mysqli/tests/mysqli_store_result.phpt b/ext/mysqli/tests/mysqli_store_result.phpt index f3d743916b7ca..2a35320a63aed 100644 --- a/ext/mysqli/tests/mysqli_store_result.phpt +++ b/ext/mysqli/tests/mysqli_store_result.phpt @@ -10,7 +10,7 @@ require_once 'skipifconnectfailure.inc'; --FILE-- --EXPECTF-- -Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d +Fatal error: Uncaught Error: Trying to clone an uncloneable object of class mysqli_warning in %s:%d +Stack trace:%A diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc index 2e770426d4c0b..986f646f8bb92 100644 --- a/ext/mysqli/tests/skipifconnectfailure.inc +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -1,9 +1,7 @@ diff --git a/ext/mysqli/tests/test_setup/test_helpers.inc b/ext/mysqli/tests/test_setup/test_helpers.inc index 42d3e7ad515be..c9ab401e75683 100644 --- a/ext/mysqli/tests/test_setup/test_helpers.inc +++ b/ext/mysqli/tests/test_setup/test_helpers.inc @@ -108,8 +108,11 @@ function default_mysqli_connect(): \mysqli{ ); } function mysqli_check_skip_test(): void { + mysqli_connect_or_skip(); +} +function mysqli_connect_or_skip() { try { - $link = default_mysqli_connect(); + return default_mysqli_connect(); } catch (\mysqli_sql_exception) { die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); } @@ -142,6 +145,4 @@ function setup_table_with_data_on_default_connection(string $table): mysqli { return $link; } -/* Development setting: test experimental features and/or feature requests that never worked before? */ -//$TEST_EXPERIMENTAL = 1 == getenv("MYSQL_TEST_EXPERIMENTAL"); //$engine = getenv("MYSQL_TEST_ENGINE") ?: "InnoDB"; diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index fbe122ab5d36a..9fb58ed50ddf7 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -38,6 +38,7 @@ if (PHP_MYSQLND != "no") { AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "Define to 1 if mysqlnd core SSL is enabled."); if (CHECK_LIB("crypt32.lib", "mysqlnd")) { AC_DEFINE("MYSQLND_HAVE_SSL", 1, "Define to 1 if mysqlnd extended SSL is enabled through OpenSSL."); + ADD_EXTENSION_DEP('mysqlnd', 'hash'); } } PHP_INSTALL_HEADERS("", "ext/mysqlnd"); diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index af242f46d7e2f..1b1d576d440c8 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -36,11 +36,6 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then AC_DEFINE([MYSQLND_SSL_SUPPORTED], [1], [Define to 1 if mysqlnd core SSL is enabled.]) - AS_VAR_IF([PHP_MYSQLND_SSL], [no],, - [PHP_SETUP_OPENSSL([MYSQLND_SHARED_LIBADD], - [AC_DEFINE([MYSQLND_HAVE_SSL], [1], - [Define to 1 if mysqlnd extended SSL is enabled through OpenSSL.])])]) - PHP_NEW_EXTENSION([mysqlnd], m4_normalize([ mysqlnd_alloc.c mysqlnd_auth.c @@ -68,6 +63,13 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + AS_VAR_IF([PHP_MYSQLND_SSL], [no],, + [PHP_SETUP_OPENSSL([MYSQLND_SHARED_LIBADD], [ + AC_DEFINE([MYSQLND_HAVE_SSL], [1], + [Define to 1 if mysqlnd extended SSL is enabled through OpenSSL.]) + PHP_ADD_EXTENSION_DEP(mysqlnd, hash) + ])]) + PHP_INSTALL_HEADERS([ext/mysqlnd/]) PHP_SUBST([MYSQLND_SHARED_LIBADD]) fi diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index efcca57e5c82a..8582e376e92a6 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1444,10 +1444,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c } case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SET_CLIENT_IP: - case MYSQL_REPORT_DATA_TRUNCATION: -#endif /* currently not supported. Todo!! */ break; case MYSQL_SET_CHARSET_NAME: @@ -1475,18 +1471,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c conn->options->protocol = *(unsigned int*) value; } break; -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SET_CHARSET_DIR: - case MYSQL_OPT_RECONNECT: - /* we don't need external character sets, all character sets are - compiled in. For compatibility we just ignore this setting. - Same for protocol, we don't support old protocol */ - case MYSQL_OPT_USE_REMOTE_CONNECTION: - case MYSQL_OPT_USE_EMBEDDED_CONNECTION: - case MYSQL_OPT_GUESS_CONNECTION: - /* todo: throw an error, we don't support embedded */ - break; -#endif case MYSQLND_OPT_MAX_ALLOWED_PACKET: if (*(unsigned int*) value > (1<<16)) { conn->options->max_allowed_packet = *(unsigned int*) value; @@ -1522,12 +1506,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c DBG_INF_FMT("%d left", zend_hash_num_elements(conn->options->connect_attr)); } break; -#ifdef WHEN_SUPPORTED_BY_MYSQLI - case MYSQL_SHARED_MEMORY_BASE_NAME: - case MYSQL_OPT_USE_RESULT: - case MYSQL_SECURE_AUTH: - /* not sure, todo ? */ -#endif default: ret = FAIL; } diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index 6a33a16892436..ff80c620bee14 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -76,22 +76,11 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * self, } if (flags & MYSQLND_DEBUG_DUMP_TIME) { /* The following from FF's DBUG library, which is in the public domain */ -#ifdef PHP_WIN32 - /* FIXME This doesn't give microseconds as in Unix case, and the resolution is - in system ticks, 10 ms intervals. See my_getsystime.c for high res */ - SYSTEMTIME loc_t; - GetLocalTime(&loc_t); - snprintf(time_buffer, sizeof(time_buffer) - 1, - /* "%04d-%02d-%02d " */ - "%02d:%02d:%02d.%06d ", - /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/ - loc_t.wHour, loc_t.wMinute, loc_t.wSecond, loc_t.wMilliseconds); - time_buffer[sizeof(time_buffer) - 1 ] = '\0'; -#else struct timeval tv; struct tm *tm_p; if (gettimeofday(&tv, NULL) != -1) { - if ((tm_p= localtime((const time_t *)&tv.tv_sec))) { + const time_t sec = tv.tv_sec; + if ((tm_p = localtime((const time_t *)&sec))) { snprintf(time_buffer, sizeof(time_buffer) - 1, /* "%04d-%02d-%02d " */ "%02d:%02d:%02d.%06d ", @@ -99,9 +88,10 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * self, tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, (int) (tv.tv_usec)); time_buffer[sizeof(time_buffer) - 1 ] = '\0'; + } else { + time_buffer[0] = '\0'; } } -#endif } if (flags & MYSQLND_DEBUG_DUMP_FILE) { snprintf(file_buffer, sizeof(file_buffer) - 1, "%14s: ", file); @@ -173,22 +163,11 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *self, } if (flags & MYSQLND_DEBUG_DUMP_TIME) { /* The following from FF's DBUG library, which is in the public domain */ -#ifdef PHP_WIN32 - /* FIXME This doesn't give microseconds as in Unix case, and the resolution is - in system ticks, 10 ms intervals. See my_getsystime.c for high res */ - SYSTEMTIME loc_t; - GetLocalTime(&loc_t); - snprintf(time_buffer, sizeof(time_buffer) - 1, - /* "%04d-%02d-%02d " */ - "%02d:%02d:%02d.%06d ", - /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/ - loc_t.wHour, loc_t.wMinute, loc_t.wSecond, loc_t.wMilliseconds); - time_buffer[sizeof(time_buffer) - 1 ] = '\0'; -#else struct timeval tv; struct tm *tm_p; if (gettimeofday(&tv, NULL) != -1) { - if ((tm_p= localtime((const time_t *)&tv.tv_sec))) { + const time_t sec = tv.tv_sec; + if ((tm_p = localtime((const time_t *)&sec))) { snprintf(time_buffer, sizeof(time_buffer) - 1, /* "%04d-%02d-%02d " */ "%02d:%02d:%02d.%06d ", @@ -196,9 +175,10 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *self, tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, (int) (tv.tv_usec)); time_buffer[sizeof(time_buffer) - 1 ] = '\0'; + } else { + time_buffer[0] = '\0'; } } -#endif } if (flags & MYSQLND_DEBUG_DUMP_FILE) { snprintf(file_buffer, sizeof(file_buffer) - 1, "%14s: ", file); diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index 02065739ccd34..2c1d997177aa8 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -206,7 +206,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA stmt->state = MYSQLND_STMT_INITTED; stmt->execute_cmd_buffer.length = MYSQLND_NET_CMD_BUFFER_MIN_SIZE; stmt->execute_cmd_buffer.buffer = mnd_emalloc(stmt->execute_cmd_buffer.length); - stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS; /* Mark that we reference the connection, thus it won't be diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 27846f077a849..851174032c404 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -130,6 +130,7 @@ #define CR_INVALID_PARAMETER_NO 2034 #define CR_INVALID_BUFFER_USE 2035 #define CR_LOAD_DATA_LOCAL_INFILE_REJECTED 2068 +#define CR_CLIENT_INTERACTION_TIMEOUT 4031 #define MYSQLND_EE_FILENOTFOUND 7890 @@ -199,21 +200,21 @@ typedef enum mysqlnd_client_option MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, - MYSQL_SET_CHARSET_DIR, + MYSQL_SET_CHARSET_DIR, /* Unsupported by mysqlnd */ MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_PROTOCOL, - MYSQL_SHARED_MEMORY_BASE_NAME, + MYSQL_SHARED_MEMORY_BASE_NAME, /* Unsupported by mysqlnd */ MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, - MYSQL_OPT_USE_RESULT, - MYSQL_OPT_USE_REMOTE_CONNECTION, - MYSQL_OPT_USE_EMBEDDED_CONNECTION, - MYSQL_OPT_GUESS_CONNECTION, - MYSQL_SET_CLIENT_IP, - MYSQL_SECURE_AUTH, - MYSQL_REPORT_DATA_TRUNCATION, - MYSQL_OPT_RECONNECT, + MYSQL_OPT_USE_RESULT, /* Unsupported by mysqlnd */ + MYSQL_OPT_USE_REMOTE_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_OPT_USE_EMBEDDED_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_OPT_GUESS_CONNECTION, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_SET_CLIENT_IP, /* Unsupported by mysqlnd */ + MYSQL_SECURE_AUTH, /* Unsupported by mysqlnd; removed in MySQL-8.0 */ + MYSQL_REPORT_DATA_TRUNCATION, /* Unsupported by mysqlnd */ + MYSQL_OPT_RECONNECT, /* Unsupported by mysqlnd */ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, @@ -280,6 +281,7 @@ typedef enum mysqlnd_field_types MYSQL_TYPE_NEWDATE = 14, MYSQL_TYPE_VARCHAR = 15, MYSQL_TYPE_BIT = 16, + MYSQL_TYPE_VECTOR=242, MYSQL_TYPE_JSON=245, MYSQL_TYPE_NEWDECIMAL=246, MYSQL_TYPE_ENUM=247, @@ -322,6 +324,7 @@ typedef enum mysqlnd_server_option #define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE #define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM #define FIELD_TYPE_SET MYSQL_TYPE_SET +#define FIELD_TYPE_VECTOR MYSQL_TYPE_VECTOR #define FIELD_TYPE_JSON MYSQL_TYPE_JSON #define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB #define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB @@ -330,7 +333,6 @@ typedef enum mysqlnd_server_option #define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING #define FIELD_TYPE_STRING MYSQL_TYPE_STRING #define FIELD_TYPE_CHAR MYSQL_TYPE_TINY -#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM #define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY #define FIELD_TYPE_BIT MYSQL_TYPE_BIT @@ -399,16 +401,13 @@ typedef enum param_bind_flags enum mysqlnd_stmt_attr { STMT_ATTR_UPDATE_MAX_LENGTH, - STMT_ATTR_CURSOR_TYPE, - STMT_ATTR_PREFETCH_ROWS + STMT_ATTR_CURSOR_TYPE }; enum myslqnd_cursor_type { CURSOR_TYPE_NO_CURSOR= 0, CURSOR_TYPE_READ_ONLY= 1, - CURSOR_TYPE_FOR_UPDATE= 2, - CURSOR_TYPE_SCROLLABLE= 4 }; typedef enum mysqlnd_connection_close_type diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c index ba5a512194d40..570fba24d663a 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c @@ -355,9 +355,6 @@ MYSQLND_METHOD(mysqlnd_pfc, receive)(MYSQLND_PFC * const pfc, MYSQLND_VIO * cons DBG_RETURN(FAIL); } pfc->data->compressed_envelope_packet_no++; -#ifdef MYSQLND_DUMP_HEADER_N_BODY - DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (zend_ulong) net_payload_size); -#endif /* Now let's read from the wire, decompress it and fill the read buffer */ pfc->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(pfc, vio, net_payload_size, conn_stats, error_info); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 5b81eb8e211ea..5fad5281947ea 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -1552,18 +1552,6 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s, stmt->flags = ival; break; } - case STMT_ATTR_PREFETCH_ROWS: { - unsigned long ival = *(unsigned long *) value; - if (ival == 0) { - ival = MYSQLND_DEFAULT_PREFETCH_ROWS; - } else if (ival > 1) { - SET_CLIENT_ERROR(stmt->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented"); - DBG_INF("FAIL"); - DBG_RETURN(FAIL); - } - stmt->prefetch_rows = ival; - break; - } default: SET_CLIENT_ERROR(stmt->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented"); DBG_RETURN(FAIL); @@ -1596,10 +1584,6 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_get)(const MYSQLND_STMT * const s, *(unsigned long *) value = stmt->flags; DBG_INF_FMT("value=%lu", *(unsigned long *) value); break; - case STMT_ATTR_PREFETCH_ROWS: - *(unsigned long *) value = stmt->prefetch_rows; - DBG_INF_FMT("value=%lu", *(unsigned long *) value); - break; default: DBG_RETURN(FAIL); } diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index ca6c2112cffa5..a9c420dd1473b 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -414,6 +414,10 @@ void _mysqlnd_init_ps_fetch_subsystem(void) mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].func = ps_fetch_string; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].pack_len = MYSQLND_PS_SKIP_RESULT_STR; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].php_type = IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].php_type = IS_STRING; diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index ad63147861ea8..ae8dc77b4cd9a 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -183,7 +183,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s) UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); if (FAIL == (ret = PACKET_READ(conn, &rset_header))) { - if (conn->error_info->error_no != CR_SERVER_GONE_ERROR) { + if (conn->error_info->error_no != CR_SERVER_GONE_ERROR && conn->error_info->error_no != CR_CLIENT_INTERACTION_TIMEOUT) { php_error_docref(NULL, E_WARNING, "Error reading result set's header"); } break; @@ -300,7 +300,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s) if (FAIL == (ret = result->m.read_result_metadata(result, conn))) { /* For PS, we leave them in Prepared state */ if (!stmt && conn->current_result) { - mnd_efree(conn->current_result); + conn->current_result->m.free_result(conn->current_result, TRUE); conn->current_result = NULL; } DBG_ERR("Error occurred while reading metadata"); diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index ccf70c3302557..cf99ac706239c 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -1267,7 +1267,6 @@ struct st_mysqlnd_stmt_data MYSQLND_ERROR_INFO error_info_impl; bool update_max_length; - zend_ulong prefetch_rows; bool cursor_exists; mysqlnd_stmt_use_or_store_func default_rset_handler; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 7c785a31d730f..b1f38f01b2180 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -267,6 +267,19 @@ mysqlnd_read_header(MYSQLND_PFC * pfc, MYSQLND_VIO * vio, MYSQLND_PACKET_HEADER pfc->data->packet_no++; DBG_RETURN(PASS); } + // @see https://dev.mysql.com/worklog/task/?id=12999 + if (header->size > 0) { + zend_uchar *buf = mnd_emalloc(header->size); + if ((PASS == pfc->data->m.receive(pfc, vio, buf, header->size, conn_stats, error_info)) && buf[0] == ERROR_MARKER) { + php_mysqlnd_read_error_from_line(buf + 1, header->size - 1, + error_info->error, sizeof(error_info->error), + &error_info->error_no, error_info->sqlstate + ); + mnd_efree(buf); + DBG_RETURN(FAIL); + } + mnd_efree(buf); + } DBG_ERR_FMT("Logical link: packets out of order. Expected %u received %u. Packet size=%zu", pfc->data->packet_no, header->packet_no, header->size); @@ -294,7 +307,9 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, DBG_INF_FMT("buf=%p size=%zu", buf, buf_size); if (FAIL == mysqlnd_read_header(pfc, vio, packet_header, stats, error_info)) { SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT); - SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); + if (error_info->error_no == 0) { + SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); + } DBG_ERR_FMT("Can't read %s's header", packet_type_as_text); DBG_RETURN(FAIL); } @@ -1468,6 +1483,7 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fi case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_LONG_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; + case MYSQL_TYPE_VECTOR: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_VAR_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_GEOMETRY: statistic = STAT_BINARY_TYPE_FETCHED_GEOMETRY; break; @@ -1553,6 +1569,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fiel case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_LONG_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; + case MYSQL_TYPE_VECTOR: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break; case MYSQL_TYPE_VAR_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break; case MYSQL_TYPE_GEOMETRY: statistic = STAT_TEXT_TYPE_FETCHED_GEOMETRY; break; diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index f3480033a0918..4bed0ccb7e6c8 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -510,8 +510,7 @@ static zend_class_entry *register_class_Odbc_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Odbc", "Connection", class_Odbc_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -521,8 +520,7 @@ static zend_class_entry *register_class_Odbc_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Odbc", "Result", class_Odbc_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 0bd55d319e31e..f9514d4807c4e 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -47,10 +47,11 @@ #include "zend_accelerator_hash.h" #include "zend_file_cache.h" #include "ext/pcre/php_pcre.h" -#include "ext/standard/md5.h" +#include "ext/standard/basic_functions.h" #ifdef ZEND_WIN32 # include "ext/hash/php_hash.h" +# include "ext/standard/md5.h" #endif #ifdef HAVE_JIT diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 3700a6ba063fc..44e82d07bdfa0 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -343,6 +343,7 @@ int main(void) { [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, [yes]) + PHP_ADD_EXTENSION_DEP(opcache, date) PHP_ADD_EXTENSION_DEP(opcache, pcre) if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index 0d498ab776891..d0af7258ac66f 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -18,6 +18,7 @@ if (PHP_OPCACHE != "no") { zend_shared_alloc.c \ shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('opcache', 'date'); ADD_EXTENSION_DEP('opcache', 'hash'); ADD_EXTENSION_DEP('opcache', 'pcre'); diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 17333fc0d5067..0499225de7388 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -706,7 +706,7 @@ static bool zend_may_be_dynamic_property(zend_class_entry *ce, zend_string *memb # endif #endif -ZEND_EXT_API void zend_jit_status(zval *ret) +void zend_jit_status(zval *ret) { zval stats; array_init(&stats); @@ -2557,7 +2557,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_GENERATOR_RETURN: case ZEND_RETURN_BY_REF: case ZEND_RETURN: - case ZEND_EXIT: case ZEND_MATCH_ERROR: /* switch through trampoline */ case ZEND_YIELD: @@ -3047,7 +3046,7 @@ static int zend_jit_setup_hot_counters(zend_op_array *op_array) #include "jit/zend_jit_trace.c" -ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) +int zend_jit_op_array(zend_op_array *op_array, zend_script *script) { if (dasm_ptr == NULL) { return FAILURE; @@ -3124,7 +3123,7 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) return FAILURE; } -ZEND_EXT_API int zend_jit_script(zend_script *script) +int zend_jit_script(zend_script *script) { void *checkpoint; zend_call_graph call_graph; @@ -3236,7 +3235,7 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) return FAILURE; } -ZEND_EXT_API void zend_jit_unprotect(void) +void zend_jit_unprotect(void) { #ifdef HAVE_MPROTECT if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3271,7 +3270,7 @@ ZEND_EXT_API void zend_jit_unprotect(void) #endif } -ZEND_EXT_API void zend_jit_protect(void) +void zend_jit_protect(void) { #ifdef HAVE_MPROTECT if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3363,7 +3362,7 @@ static int zend_jit_parse_config_num(zend_long jit) return SUCCESS; } -ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) +int zend_jit_config(zend_string *jit, int stage) { if (stage != ZEND_INI_STAGE_STARTUP && !JIT_G(enabled)) { if (stage == ZEND_INI_STAGE_RUNTIME) { @@ -3419,7 +3418,7 @@ ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) return FAILURE; } -ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) +int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) { if (stage != ZEND_INI_STAGE_STARTUP) { if (((old_val ^ new_val) & ZEND_JIT_DEBUG_PERSISTENT) != 0) { @@ -3432,7 +3431,7 @@ ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int return SUCCESS; } -ZEND_EXT_API void zend_jit_init(void) +void zend_jit_init(void) { #ifdef ZTS jit_globals_id = ts_allocate_id(&jit_globals_id, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); @@ -3441,7 +3440,7 @@ ZEND_EXT_API void zend_jit_init(void) #endif } -ZEND_EXT_API int zend_jit_check_support(void) +int zend_jit_check_support(void) { int i; @@ -3470,7 +3469,6 @@ ZEND_EXT_API int zend_jit_check_support(void) /* JIT has no effect on these opcodes */ case ZEND_BEGIN_SILENCE: case ZEND_END_SILENCE: - case ZEND_EXIT: break; default: if (zend_get_user_opcode_handler(i) != NULL) { @@ -3501,7 +3499,7 @@ ZEND_EXT_API int zend_jit_check_support(void) return SUCCESS; } -ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) +void zend_jit_startup(void *buf, size_t size, bool reattached) { zend_jit_halt_op = zend_get_halt_op(); zend_jit_profile_counter_rid = zend_get_op_array_extension_handle(ACCELERATOR_PRODUCT_NAME); @@ -3584,7 +3582,7 @@ ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) zend_jit_protect(); } -ZEND_EXT_API void zend_jit_shutdown(void) +void zend_jit_shutdown(void) { if (JIT_G(debug) & ZEND_JIT_DEBUG_SIZE && dasm_ptr != NULL) { fprintf(stderr, "\nJIT memory usage: %td\n", (ptrdiff_t)((char*)*dasm_ptr - (char*)dasm_buf)); @@ -3608,7 +3606,7 @@ static void zend_jit_reset_counters(void) } } -ZEND_EXT_API void zend_jit_activate(void) +void zend_jit_activate(void) { zend_jit_profile_counter = 0; if (JIT_G(on)) { @@ -3621,7 +3619,7 @@ ZEND_EXT_API void zend_jit_activate(void) } } -ZEND_EXT_API void zend_jit_deactivate(void) +void zend_jit_deactivate(void) { if (zend_jit_profile_counter && !CG(unclean_shutdown)) { zend_class_entry *ce; @@ -3704,7 +3702,7 @@ static void zend_jit_restart_preloaded_script(zend_persistent_script *script) } ZEND_HASH_FOREACH_END(); } -ZEND_EXT_API void zend_jit_restart(void) +void zend_jit_restart(void) { if (dasm_buf) { zend_jit_unprotect(); diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 99940cf684ed9..1e0176a4f4f55 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -150,20 +150,20 @@ extern int jit_globals_id; extern zend_jit_globals jit_globals; #endif -ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script); -ZEND_EXT_API int zend_jit_script(zend_script *script); -ZEND_EXT_API void zend_jit_unprotect(void); -ZEND_EXT_API void zend_jit_protect(void); -ZEND_EXT_API void zend_jit_init(void); -ZEND_EXT_API int zend_jit_config(zend_string *jit_options, int stage); -ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage); -ZEND_EXT_API int zend_jit_check_support(void); -ZEND_EXT_API void zend_jit_startup(void *jit_buffer, size_t size, bool reattached); -ZEND_EXT_API void zend_jit_shutdown(void); -ZEND_EXT_API void zend_jit_activate(void); -ZEND_EXT_API void zend_jit_deactivate(void); -ZEND_EXT_API void zend_jit_status(zval *ret); -ZEND_EXT_API void zend_jit_restart(void); +int zend_jit_op_array(zend_op_array *op_array, zend_script *script); +int zend_jit_script(zend_script *script); +void zend_jit_unprotect(void); +void zend_jit_protect(void); +void zend_jit_init(void); +int zend_jit_config(zend_string *jit_options, int stage); +int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage); +int zend_jit_check_support(void); +void zend_jit_startup(void *jit_buffer, size_t size, bool reattached); +void zend_jit_shutdown(void); +void zend_jit_activate(void); +void zend_jit_deactivate(void); +void zend_jit_status(zval *ret); +void zend_jit_restart(void); #define ZREG_LOAD (1<<0) #define ZREG_STORE (1<<1) diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 8ed378d7552b0..a1370ea0723a8 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2648,6 +2648,22 @@ static void ZEND_FASTCALL zend_jit_assign_obj_helper(zend_object *zobj, zend_str } } +static zend_always_inline bool verify_readonly_and_avis(zval *property_val, zend_property_info *info, bool indirect) +{ + if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { + zend_readonly_property_modification_error(info); + return false; + } + if ((info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(info)) { + const char *operation = indirect ? "indirectly modify" : "modify"; + zend_asymmetric_visibility_property_modification_error(info, operation); + return false; + } + } + return true; +} + static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend_property_info *info, zval *value, zval *result) { zend_execute_data *execute_data = EG(current_execute_data); @@ -2661,8 +2677,7 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend value = &EG(uninitialized_zval); } - if (UNEXPECTED((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(info); + if (UNEXPECTED(!verify_readonly_and_avis(property_val, info, false))) { if (result) { ZVAL_UNDEF(result); } @@ -2723,8 +2738,7 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_prop zend_execute_data *execute_data = EG(current_execute_data); zval z_copy; - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(zptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(zptr, prop_info, true))) { return; } @@ -2818,8 +2832,7 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { return; } @@ -2851,8 +2864,7 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { return; } @@ -2898,8 +2910,7 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { if (result) { ZVAL_UNDEF(result); } @@ -2933,8 +2944,7 @@ static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED((prop_info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_REINITABLE))) { - zend_readonly_property_modification_error(prop_info); + if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { if (result) { ZVAL_UNDEF(result); } diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index ccc86a4834cf5..2007f28e91fd2 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -265,6 +265,7 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key); _(INNER_LOOP, "inner loop") /* trace it */ \ _(COMPILED_LOOP, "compiled loop") \ _(TRAMPOLINE, "trampoline call") \ + _(PROP_HOOK_CALL, "property hook call") \ _(BAD_FUNC, "bad function call") \ _(COMPILER_ERROR, "JIT compilation error") \ /* no recoverable error (blacklist immediately) */ \ diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 174b07ac10c1d..9b1bf9a71dde1 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -13933,16 +13933,37 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, && (!ce || ce_is_instanceof || (ce->ce_flags & (ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_TRAIT)))) { uint32_t flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS; + ir_ref allowed_inputs = IR_UNUSED; + ir_ref forbidden_inputs = IR_UNUSED; + ir_ref prop_info_ref = ir_LOAD_A( ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2)); ir_ref if_has_prop_info = ir_IF(prop_info_ref); ir_IF_TRUE_cold(if_has_prop_info); - ir_ref if_readonly = ir_IF( - ir_AND_U32(ir_LOAD_U32(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_property_info, flags))), - ir_CONST_U32(ZEND_ACC_READONLY))); + ir_ref prop_flags = ir_LOAD_U32(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_property_info, flags))); + ir_ref if_readonly_or_avis = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))); + + ir_IF_FALSE(if_readonly_or_avis); + ir_END_list(allowed_inputs); + + ir_IF_TRUE_cold(if_readonly_or_avis); + + ir_ref if_readonly = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY))); ir_IF_TRUE(if_readonly); + ir_END_list(forbidden_inputs); + + ir_IF_FALSE(if_readonly); + ir_ref has_avis_access = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_asymmetric_property_has_set_access), prop_info_ref); + ir_ref if_avis_access = ir_IF(has_avis_access); + ir_IF_TRUE(if_avis_access); + ir_END_list(allowed_inputs); + + ir_IF_FALSE(if_avis_access); + ir_END_list(forbidden_inputs); + + ir_MERGE_list(forbidden_inputs); ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); ir_IF_TRUE(if_prop_obj); @@ -13955,19 +13976,27 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_FALSE_cold(if_prop_obj); jit_SET_EX_OPLINE(jit, opline); + if_readonly = ir_IF(ir_AND_U32(prop_flags, ir_CONST_U32(ZEND_ACC_READONLY))); + ir_IF_TRUE(if_readonly); ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_readonly_property_indirect_modification_error), prop_info_ref); jit_set_Z_TYPE_INFO(jit, res_addr, _IS_ERROR); ir_END_list(end_inputs); + ir_IF_FALSE(if_readonly); + ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_asymmetric_visibility_property_modification_error), + prop_info_ref, ir_CONST_ADDR("indirectly modify")); + jit_set_Z_TYPE_INFO(jit, res_addr, _IS_ERROR); + ir_END_list(end_inputs); + + ir_MERGE_list(allowed_inputs); + if (flags == ZEND_FETCH_DIM_WRITE) { - ir_IF_FALSE_cold(if_readonly); jit_SET_EX_OPLINE(jit, opline); ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_check_array_promotion), prop_ref, prop_info_ref); ir_END_list(end_inputs); ir_IF_FALSE(if_has_prop_info); } else if (flags == ZEND_FETCH_REF) { - ir_IF_FALSE_cold(if_readonly); ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_create_typed_ref), prop_ref, prop_info_ref, @@ -13976,10 +14005,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_FALSE(if_has_prop_info); } else { ZEND_ASSERT(flags == 0); - ir_IF_FALSE(if_has_prop_info); - ir_ref no_prop_info_path = ir_END(); - ir_IF_FALSE(if_readonly); - ir_MERGE_WITH(no_prop_info_path); + ir_MERGE_WITH_EMPTY_FALSE(if_has_prop_info); } } } else { @@ -14005,9 +14031,6 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_IF_TRUE(if_def); } if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_READONLY)) { - if (!prop_type_ref) { - prop_type_ref = jit_Z_TYPE_INFO(jit, prop_addr); - } ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); ir_IF_TRUE(if_prop_obj); ir_ref ref = jit_Z_PTR(jit, prop_addr); @@ -14023,6 +14046,28 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, ir_END_list(end_inputs); goto result_fetched; + } else if (opline->opcode == ZEND_FETCH_OBJ_W && (prop_info->flags & ZEND_ACC_PPP_SET_MASK)) { + /* Readonly properties which are also asymmetric are never mutable indirectly, which is + * handled by the previous branch. */ + ir_ref has_access = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_asymmetric_property_has_set_access), ir_CONST_ADDR(prop_info)); + + ir_ref if_access = ir_IF(has_access); + ir_IF_FALSE_cold(if_access); + + ir_ref if_prop_obj = jit_if_Z_TYPE(jit, prop_addr, IS_OBJECT); + ir_IF_TRUE(if_prop_obj); + ir_ref ref = jit_Z_PTR(jit, prop_addr); + jit_GC_ADDREF(jit, ref); + jit_set_Z_PTR(jit, res_addr, ref); + jit_set_Z_TYPE_INFO(jit, res_addr, IS_OBJECT_EX); + ir_END_list(end_inputs); + + ir_IF_FALSE_cold(if_prop_obj); + ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_asymmetric_visibility_property_modification_error), + ir_CONST_ADDR(prop_info), ir_CONST_ADDR("indirectly modify")); + ir_END_list(end_inputs); + + ir_IF_TRUE(if_access); } if (opline->opcode == ZEND_FETCH_OBJ_W @@ -14421,22 +14466,20 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ZEND_ASSERT(slow_inputs == IR_UNUSED); goto slow_path; } - if (!ce || ce_is_instanceof || !(ce->ce_flags & ZEND_ACC_IMMUTABLE) || ce->__get || ce->__set) { - // Undefined property with magic __get()/__set() - if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { - int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); - const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + // Undefined property with potential magic __get()/__set() or lazy object + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } - ir_GUARD(jit_Z_TYPE_INFO(jit, prop_addr), ir_CONST_ADDR(exit_addr)); - } else { - ir_ref if_def = ir_IF(jit_Z_TYPE_INFO(jit, prop_addr)); - ir_IF_FALSE_cold(if_def); - ir_END_list(slow_inputs); - ir_IF_TRUE(if_def); + if (!exit_addr) { + return 0; } + ir_GUARD(jit_Z_TYPE_INFO(jit, prop_addr), ir_CONST_ADDR(exit_addr)); + } else { + ir_ref if_def = ir_IF(jit_Z_TYPE_INFO(jit, prop_addr)); + ir_IF_FALSE_cold(if_def); + ir_END_list(slow_inputs); + ir_IF_TRUE(if_def); } if (ZEND_TYPE_IS_SET(prop_info->type)) { ir_ref ref, arg3, arg4; @@ -16450,8 +16493,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr } else { ir_GUARD(ir_GE(ref, ir_CONST_I32(0)), jit_STUB_ADDR(jit, jit_stub_trace_halt)); } - } else if (opline->opcode == ZEND_EXIT || - opline->opcode == ZEND_GENERATOR_RETURN || + } else if (opline->opcode == ZEND_GENERATOR_RETURN || opline->opcode == ZEND_YIELD || opline->opcode == ZEND_YIELD_FROM) { ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_halt)); diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index de2481fb8d2bc..69187ca3814ee 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -314,7 +314,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op case ZEND_FAST_RET: case ZEND_GENERATOR_CREATE: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_YIELD: case ZEND_YIELD_FROM: case ZEND_INCLUDE_OR_EVAL: @@ -7160,7 +7159,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par for (i = 0; i < op_array->last_var + op_array->T; i++) { SET_STACK_TYPE(stack, i, IS_UNKNOWN, 1); } - exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + exit_point = zend_jit_trace_get_exit_point(zend_jit_traces[t->link].opline, ZEND_JIT_EXIT_TO_VM); timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!timeout_exit_addr) { goto jit_failure; diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 2a7399c185d5f..e9cdeeab9865a 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -503,6 +503,11 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend /* TODO: Can we continue recording ??? */ return -1; } + /* Function is a property hook. */ + if (func->common.prop_info) { + /* TODO: Can we continue recording ??? */ + return -1; + } if (func->type == ZEND_INTERNAL_FUNCTION && (func->op_array.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) { return -1; @@ -966,6 +971,12 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, break; } + if (EX(func)->op_array.prop_info) { + /* TODO: Can we continue recording ??? */ + stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL; + break; + } + TRACE_RECORD(ZEND_JIT_TRACE_ENTER, EX(return_value) != NULL ? ZEND_JIT_TRACE_RETURN_VALUE_USED : 0, op_array); @@ -1069,6 +1080,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, /* TODO: Can we continue recording ??? */ stop = ZEND_JIT_TRACE_STOP_BAD_FUNC; break; + } else if (EX(call)->func->common.prop_info) { + /* TODO: Can we continue recording ??? */ + stop = ZEND_JIT_TRACE_STOP_PROP_HOOK_CALL; + break; } func = EX(call)->func; if (func->type == ZEND_INTERNAL_FUNCTION diff --git a/ext/opcache/tests/jit/gh15490.inc b/ext/opcache/tests/jit/gh15490.inc new file mode 100644 index 0000000000000..e702a9e244028 --- /dev/null +++ b/ext/opcache/tests/jit/gh15490.inc @@ -0,0 +1,9 @@ + +--FILE-- + +--EXPECT-- +Hello world! diff --git a/ext/opcache/tests/jit/ignored_opcodes.phpt b/ext/opcache/tests/jit/ignored_opcodes.phpt index 761a0b699a73a..eac4c237a9c09 100644 --- a/ext/opcache/tests/jit/ignored_opcodes.phpt +++ b/ext/opcache/tests/jit/ignored_opcodes.phpt @@ -9,7 +9,7 @@ opcache.jit=function zend_test.observer.enabled=1 zend_test.observer.show_output=1 zend_test.observer.observe_all=1 -zend_test.observer.show_opcode_in_user_handler=ZEND_EXIT, ZEND_BEGIN_SILENCE, ZEND_END_SILENCE +zend_test.observer.show_opcode_in_user_handler=ZEND_BEGIN_SILENCE, ZEND_END_SILENCE --EXTENSIONS-- opcache zend_test @@ -27,6 +27,9 @@ exit(@test()); - + + + + diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index c09e39579a474..736d644516a04 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -29,6 +29,7 @@ #ifdef ZEND_WIN32 #include "ext/standard/md5.h" #endif +#include "ext/standard/php_filestat.h" #include "ZendAccelerator.h" #include "zend_file_cache.h" diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 8db61ed3f3465..c19d72c63b776 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -53,7 +53,7 @@ static const zend_shared_memory_handlers *g_shared_alloc_handler = NULL; static const char *g_shared_model; /* pointer to globals allocated in SHM and shared across processes */ -zend_smm_shared_globals *smm_shared_globals; +ZEND_EXT_API zend_smm_shared_globals *smm_shared_globals; #ifndef ZEND_WIN32 #ifdef ZTS diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 1283351f2e149..41cba0bb35199 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -119,7 +119,7 @@ typedef struct _zend_smm_shared_globals { size_t reserved_size; } zend_smm_shared_globals; -extern zend_smm_shared_globals *smm_shared_globals; +ZEND_EXT_API extern zend_smm_shared_globals *smm_shared_globals; #define ZSMMG(element) (smm_shared_globals->element) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 4c16279d81856..e0a27a990f904 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -7243,7 +7243,7 @@ PHP_FUNCTION(openssl_seal) pubkeysht = Z_ARRVAL_P(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; if (!nkeys) { - zend_argument_value_error(4, "cannot be empty"); + zend_argument_must_not_be_empty_error(4); RETURN_THROWS(); } @@ -8017,7 +8017,7 @@ PHP_FUNCTION(openssl_decrypt) } if (!method_len) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -8059,7 +8059,7 @@ PHP_FUNCTION(openssl_cipher_iv_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -8088,7 +8088,7 @@ PHP_FUNCTION(openssl_cipher_key_length) } if (ZSTR_LEN(method) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index 45a0593cf966e..e634f92f73d00 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -766,8 +766,7 @@ static zend_class_entry *register_class_OpenSSLCertificate(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLCertificate", class_OpenSSLCertificate_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -777,8 +776,7 @@ static zend_class_entry *register_class_OpenSSLCertificateSigningRequest(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLCertificateSigningRequest", class_OpenSSLCertificateSigningRequest_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -788,8 +786,7 @@ static zend_class_entry *register_class_OpenSSLAsymmetricKey(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OpenSSLAsymmetricKey", class_OpenSSLAsymmetricKey_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt index 8fca1fdd71e66..cdd5f3616fb23 100644 --- a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt @@ -18,4 +18,4 @@ try { Warning: openssl_cipher_iv_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_iv_length(): Argument #1 ($cipher_algo) cannot be empty +openssl_cipher_iv_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_cipher_key_length_error.phpt b/ext/openssl/tests/openssl_cipher_key_length_error.phpt index 08c08d382eb0c..a4e4e8e6bfcff 100644 --- a/ext/openssl/tests/openssl_cipher_key_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_key_length_error.phpt @@ -18,4 +18,4 @@ try { Warning: openssl_cipher_key_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_key_length(): Argument #1 ($cipher_algo) cannot be empty +openssl_cipher_key_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_seal_basic.phpt b/ext/openssl/tests/openssl_seal_basic.phpt index 2d9d2cdd263c8..6c08efa6d70d2 100644 --- a/ext/openssl/tests/openssl_seal_basic.phpt +++ b/ext/openssl/tests/openssl_seal_basic.phpt @@ -40,13 +40,13 @@ var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong), $method)); --EXPECTF-- Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) cannot be empty +openssl_seal(): Argument #4 ($public_key) must not be empty int(32) int(32) Warning: openssl_seal(): Not a public key (2th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) cannot be empty +openssl_seal(): Argument #4 ($public_key) must not be empty Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index cf66057fc8f69..b2fe964e7face 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -860,7 +860,7 @@ static bool php_pcntl_set_user_signal_infos( bool allow_empty_signal_array ) { if (!allow_empty_signal_array && zend_hash_num_elements(user_signals) == 0) { - zend_argument_value_error(arg_num, "cannot be empty"); + zend_argument_must_not_be_empty_error(arg_num); return false; } @@ -1693,8 +1693,9 @@ PHP_FUNCTION(pcntl_setcpuaffinity) Z_PARAM_ARRAY(hmask) ZEND_PARSE_PARAMETERS_END(); + // TODO Why are the arguments optional? if (!hmask || zend_hash_num_elements(Z_ARRVAL_P(hmask)) == 0) { - zend_argument_value_error(2, "must not be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt b/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt index 61370039c17d4..6815b208955da 100644 --- a/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigprocmask_errors.phpt @@ -60,7 +60,7 @@ try { ?> --EXPECTF-- ValueError: pcntl_sigprocmask(): Argument #1 ($mode) must be one of SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK -ValueError: pcntl_sigprocmask(): Argument #2 ($signals) cannot be empty +ValueError: pcntl_sigprocmask(): Argument #2 ($signals) must not be empty ValueError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be between 1 and %d ValueError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be between 1 and %d TypeError: pcntl_sigprocmask(): Argument #2 ($signals) signals must be of type int, string given diff --git a/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt b/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt index 3dbc3c904afef..70cd806a8e8d4 100644 --- a/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigtimedwait_errors.phpt @@ -86,7 +86,7 @@ try { ?> --EXPECTF-- -ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) cannot be empty +ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) must not be empty ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d diff --git a/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt b/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt index a58aa82c57f7d..1e237b4a1993a 100644 --- a/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt +++ b/ext/pcntl/tests/pcntl_sigwaitinfo_errors.phpt @@ -51,7 +51,7 @@ try { } ?> --EXPECTF-- -ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) cannot be empty +ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) must not be empty ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be between 1 and %d ValueError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be between 1 and %d TypeError: pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be of type int, string given diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 3b13ad5400560..7c2a8460cc5d1 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -28,7 +28,12 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then AS_VAR_IF([PHP_PCRE_JIT], [no],, [AC_CACHE_CHECK([whether external PCRE2 library has JIT supported], [php_cv_have_pcre2_jit], - [AC_RUN_IFELSE([AC_LANG_SOURCE([ + [ + CFLAGS_SAVE=$CFLAGS + LIBS_SAVE=$LIBS + CFLAGS="$CFLAGS $PCRE2_CFLAGS" + LIBS="$LIBS $PCRE2_LIBS" + AC_RUN_IFELSE([AC_LANG_SOURCE([ #include #include int main(void) { @@ -42,7 +47,10 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then [AS_CASE([$host_cpu], [arm*|i[[34567]]86|x86_64|mips*|powerpc*|sparc], [php_cv_have_pcre2_jit=yes], - [php_cv_have_pcre2_jit=no])])]) + [php_cv_have_pcre2_jit=no])]) + CFLAGS=$CFLAGS_SAVE + LIBS=$LIBS_SAVE + ]) AS_VAR_IF([php_cv_have_pcre2_jit], [yes], [AC_DEFINE([HAVE_PCRE_JIT_SUPPORT], [1])]) ]) diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index e6beb57bd23e5..eb42a1c9d0d73 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -20,7 +20,7 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDOException", class_PDOException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); zval property_code_default_value; ZVAL_LONG(&property_code_default_value, 0); diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index c67b0eb24e5b4..dce5d64779a2b 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -563,7 +563,7 @@ PHP_METHOD(PDO, prepare) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1030,7 +1030,7 @@ PHP_METHOD(PDO, exec) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1166,7 +1166,7 @@ PHP_METHOD(PDO, query) PDO_CONSTRUCT_CHECK; if (ZSTR_LEN(statement) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pdo/pdo_dbh_arginfo.h b/ext/pdo/pdo_dbh_arginfo.h index ecb21b3e4d917..71df4c519e1a7 100644 --- a/ext/pdo/pdo_dbh_arginfo.h +++ b/ext/pdo/pdo_dbh_arginfo.h @@ -107,8 +107,7 @@ static zend_class_entry *register_class_PDO(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDO", class_PDO_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_PARAM_NULL_value; ZVAL_LONG(&const_PARAM_NULL_value, LONG_CONST(PDO_PARAM_NULL)); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 4674e901da5a5..4fc95aa7d6fee 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1423,7 +1423,7 @@ static void register_bound_param(INTERNAL_FUNCTION_PARAMETERS, int is_param) /* if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; @@ -1471,7 +1471,7 @@ PHP_METHOD(PDOStatement, bindValue) if (param.name) { if (ZSTR_LEN(param.name) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } param.paramno = -1; diff --git a/ext/pdo/pdo_stmt_arginfo.h b/ext/pdo/pdo_stmt_arginfo.h index d0d90899125f4..4d8c1fa4715e4 100644 --- a/ext/pdo/pdo_stmt_arginfo.h +++ b/ext/pdo/pdo_stmt_arginfo.h @@ -141,8 +141,7 @@ static zend_class_entry *register_class_PDOStatement(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDOStatement", class_PDOStatement_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); zval property_queryString_default_value; @@ -159,8 +158,7 @@ static zend_class_entry *register_class_PDORow(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PDORow", class_PDORow_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); zval property_queryString_default_value; ZVAL_UNDEF(&property_queryString_default_value); diff --git a/ext/pdo_dblib/config.m4 b/ext/pdo_dblib/config.m4 index 0adf020c29505..4cfea501c3e37 100644 --- a/ext/pdo_dblib/config.m4 +++ b/ext/pdo_dblib/config.m4 @@ -4,14 +4,14 @@ PHP_ARG_WITH([pdo-dblib], [PDO: DBLIB-DB support. DIR is the FreeTDS home directory])]) if test "$PHP_PDO_DBLIB" != "no"; then - if test "$PHP_PDO_DBLIB" = "yes"; then + AS_VAR_IF([PHP_PDO_DBLIB], [yes], [ dnl FreeTDS must be on the default system include/library path. dnl Only perform a sanity check that this is really the case. PHP_CHECK_LIBRARY([sybdb], [dbsqlexec], [], [AC_MSG_FAILURE([Cannot find FreeTDS in known installation directories.])]) PHP_ADD_LIBRARY([sybdb],, [PDO_DBLIB_SHARED_LIBADD]) - elif test "$PHP_PDO_DBLIB" != "no"; then + ], [ if test -f $PHP_PDO_DBLIB/include/sybdb.h; then PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include @@ -22,8 +22,6 @@ if test "$PHP_PDO_DBLIB" != "no"; then AC_MSG_ERROR([Directory $PHP_PDO_DBLIB is not a FreeTDS installation directory]) fi - AS_VAR_IF([PHP_LIBDIR],, [PHP_LIBDIR=lib]) - if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then AC_MSG_ERROR([[Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so]]]) fi @@ -32,7 +30,7 @@ if test "$PHP_PDO_DBLIB" != "no"; then PHP_ADD_LIBRARY_WITH_PATH([sybdb], [$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR], [PDO_DBLIB_SHARED_LIBADD]) - fi + ]) PHP_CHECK_PDO_INCLUDES diff --git a/ext/pdo_dblib/pdo_dblib_arginfo.h b/ext/pdo_dblib/pdo_dblib_arginfo.h index 3c9e306f3042c..a5105e3da6443 100644 --- a/ext/pdo_dblib/pdo_dblib_arginfo.h +++ b/ext/pdo_dblib/pdo_dblib_arginfo.h @@ -10,8 +10,7 @@ static zend_class_entry *register_class_Pdo_Dblib(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Dblib", class_Pdo_Dblib_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_CONNECTION_TIMEOUT_value; ZVAL_LONG(&const_ATTR_CONNECTION_TIMEOUT_value, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); diff --git a/ext/pdo_firebird/config.m4 b/ext/pdo_firebird/config.m4 index 18db4eda20897..f328dbd03b1b5 100644 --- a/ext/pdo_firebird/config.m4 +++ b/ext/pdo_firebird/config.m4 @@ -13,6 +13,8 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then FB_LIBDIR=$($FB_CONFIG --libs) FB_VERSION=$($FB_CONFIG --version) AC_MSG_RESULT([version $FB_VERSION]) + AS_VERSION_COMPARE([$FB_VERSION], [3.0], + [AC_MSG_ERROR([Firebird required version is at least 3.0])]) PHP_EVAL_LIBLINE([$FB_LIBDIR], [PDO_FIREBIRD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$FB_CFLAGS]) else @@ -26,17 +28,11 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then FIREBIRD_LIBDIR_FLAG=-L$FIREBIRD_LIBDIR ]) - PHP_CHECK_LIBRARY([fbclient], [isc_detach_database], - [FIREBIRD_LIBNAME=fbclient], - [PHP_CHECK_LIBRARY([gds], [isc_detach_database], - [FIREBIRD_LIBNAME=gds], - [PHP_CHECK_LIBRARY([ib_util], [isc_detach_database], - [FIREBIRD_LIBNAME=ib_util], - [AC_MSG_FAILURE([libfbclient, libgds or libib_util not found.])], - [$FIREBIRD_LIBDIR_FLAG])], - [$FIREBIRD_LIBDIR_FLAG])], + PHP_CHECK_LIBRARY([fbclient], [fb_get_master_interface], + [], + [AC_MSG_FAILURE([libfbclient not found.])], [$FIREBIRD_LIBDIR_FLAG]) - PHP_ADD_LIBRARY_WITH_PATH([$FIREBIRD_LIBNAME], + PHP_ADD_LIBRARY_WITH_PATH([fbclient], [$FIREBIRD_LIBDIR], [PDO_FIREBIRD_SHARED_LIBADD]) PHP_ADD_INCLUDE([$FIREBIRD_INCDIR]) diff --git a/ext/pdo_firebird/config.w32 b/ext/pdo_firebird/config.w32 index f7cd342120ff2..003a1a677082a 100644 --- a/ext/pdo_firebird/config.w32 +++ b/ext/pdo_firebird/config.w32 @@ -4,11 +4,12 @@ ARG_WITH("pdo-firebird", "Firebird support for PDO", "no"); if (PHP_PDO_FIREBIRD != "no") { - if ((CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - || CHECK_LIB("gds32_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - ) && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", - PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) - ) { + if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) + && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", + PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) + && CHECK_HEADER_ADD_INCLUDE("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", + PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) + ) { EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c pdo_firebird_utils.cpp"); ADD_FLAG("CFLAGS_PDO_FIREBIRD", "/EHsc"); diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index a044cd6400519..5db0c7f75aa1d 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -463,53 +463,6 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa #if FB_API_VER >= 40 /* set coercing a data type */ -static void set_coercing_input_data_types(XSQLDA* sqlda) -{ - /* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */ - /* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)), */ - /* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. */ - /* This function allows you to ensure minimal performance */ - /* of queries if they contain parameters of the above types. */ - unsigned int i; - short dtype; - short nullable; - XSQLVAR* var; - for (i=0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++) { - dtype = (var->sqltype & ~1); /* drop flag bit */ - nullable = (var->sqltype & 1); - switch(dtype) { - case SQL_INT128: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 46; - var->sqlscale = 0; - break; - - case SQL_DEC16: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 24; - break; - - case SQL_DEC34: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 43; - break; - - case SQL_TIMESTAMP_TZ: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 58; - break; - - case SQL_TIME_TZ: - var->sqltype = SQL_VARYING + nullable; - var->sqllen = 46; - break; - - default: - break; - } - } -} - static void set_coercing_output_data_types(XSQLDA* sqlda) { /* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */ @@ -602,14 +555,12 @@ void php_firebird_set_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *state, einfo->errmsg_length = read_len; einfo->errmsg = pestrndup(buf, read_len, dbh->is_persistent); -#if FB_API_VER >= 25 char sqlstate[sizeof(pdo_error_type)]; fb_sqlstate(sqlstate, H->isc_status); if (sqlstate != NULL && strlen(sqlstate) < sizeof(pdo_error_type)) { strcpy(*error_code, sqlstate); goto end; } -#endif } else if (msg && msg_len) { einfo->errmsg_length = msg_len; einfo->errmsg = pestrndup(msg, einfo->errmsg_length, dbh->is_persistent); @@ -730,11 +681,6 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */ if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->in_sqlda)) { break; } - -#if FB_API_VER >= 40 - /* set coercing a data type */ - set_coercing_input_data_types(S->in_sqlda); -#endif } stmt->driver_data = S; @@ -1043,12 +989,6 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; char *new_sql; - /* Firebird allows SQL statements up to 64k, so bail if it doesn't fit */ - if (ZSTR_LEN(sql) > 65536) { - php_firebird_error_with_info(dbh, "01004", strlen("01004"), NULL, 0); - return 0; - } - /* allocate the statement */ if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) { php_firebird_error(dbh); @@ -1333,7 +1273,6 @@ static int pdo_firebird_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) } /* }}} */ -#if FB_API_VER >= 30 /* called by PDO to check liveness */ static zend_result pdo_firebird_check_liveness(pdo_dbh_t *dbh) /* {{{ */ { @@ -1343,7 +1282,6 @@ static zend_result pdo_firebird_check_liveness(pdo_dbh_t *dbh) /* {{{ */ return fb_ping(H->isc_status, &H->db) ? FAILURE : SUCCESS; } /* }}} */ -#endif /* called by PDO to retrieve driver-specific information about an error that has occurred */ static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */ @@ -1383,11 +1321,7 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */ NULL, /* last_id not supported */ pdo_firebird_fetch_error_func, pdo_firebird_get_attribute, -#if FB_API_VER >= 30 pdo_firebird_check_liveness, -#else - NULL, -#endif NULL, /* get driver methods */ NULL, /* request shutdown */ pdo_firebird_in_manually_transaction, diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 5cc8889c65e79..0fbfe77668b57 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -349,11 +349,9 @@ static int pdo_firebird_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, #endif param_type = PDO_PARAM_INT; break; -#ifdef SQL_BOOLEAN case SQL_BOOLEAN: param_type = PDO_PARAM_BOOL; break; -#endif default: param_type = PDO_PARAM_STR; break; @@ -542,11 +540,9 @@ static int pdo_firebird_stmt_get_col( /* TODO: Why is this not returned as the native type? */ ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.16H", php_get_double_from_sqldata(var->sqldata))); break; -#ifdef SQL_BOOLEAN case SQL_BOOLEAN: ZVAL_BOOL(result, *(FB_BOOLEAN*)var->sqldata); break; -#endif case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE*)var->sqldata, &t); fmt = S->H->date_format ? S->H->date_format : PDO_FB_DEF_DATE_FMT; @@ -744,7 +740,6 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param } } -#ifdef SQL_BOOLEAN /* keep native BOOLEAN type */ if ((var->sqltype & ~1) == SQL_BOOLEAN) { switch (Z_TYPE_P(parameter)) { @@ -797,8 +792,6 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param } break; } -#endif - /* check if a NULL should be inserted */ switch (Z_TYPE_P(parameter)) { @@ -829,6 +822,13 @@ static int pdo_firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param case SQL_TIMESTAMP: case SQL_TYPE_DATE: case SQL_TYPE_TIME: +#if FB_API_VER >= 40 + case SQL_INT128: + case SQL_DEC16: + case SQL_DEC34: + case SQL_TIMESTAMP_TZ: + case SQL_TIME_TZ: +#endif force_null = (Z_STRLEN_P(parameter) == 0); } if (!force_null) { diff --git a/ext/pdo_firebird/pdo_firebird_arginfo.h b/ext/pdo_firebird/pdo_firebird_arginfo.h index a751751edb635..a5a9c562c9c12 100644 --- a/ext/pdo_firebird/pdo_firebird_arginfo.h +++ b/ext/pdo_firebird/pdo_firebird_arginfo.h @@ -16,8 +16,7 @@ static zend_class_entry *register_class_Pdo_Firebird(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Firebird", class_Pdo_Firebird_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_DATE_FORMAT_value; ZVAL_LONG(&const_ATTR_DATE_FORMAT_value, PDO_FB_ATTR_DATE_FORMAT); diff --git a/ext/pdo_mysql/pdo_mysql_arginfo.h b/ext/pdo_mysql/pdo_mysql_arginfo.h index 1ae005d849103..1e6fd32751fe5 100644 --- a/ext/pdo_mysql/pdo_mysql_arginfo.h +++ b/ext/pdo_mysql/pdo_mysql_arginfo.h @@ -16,8 +16,7 @@ static zend_class_entry *register_class_Pdo_Mysql(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Mysql", class_Pdo_Mysql_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_USE_BUFFERED_QUERY_value; ZVAL_LONG(&const_ATTR_USE_BUFFERED_QUERY_value, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt index 556d1f28b0b0a..29074fb5505f5 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt @@ -162,7 +162,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated'); ?> --EXPECTF-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { ["one"]=> string(1) "1" diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt index ea13fa229bb2c..ac4f85949bb17 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt @@ -161,7 +161,7 @@ $db = MySQLPDOTest::factory(); $db->query('DROP TABLE IF EXISTS test_prepare_emulated_anonymous_placeholder'); ?> --EXPECTF-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt index 976219fc2320b..8406be4db6d76 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt @@ -152,5 +152,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated_myisam'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt index f6d02031da3d1..1acc055e12a0c 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt @@ -164,5 +164,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_emulated_myisam_index'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt index 4c7497f69e5d9..02690d4164c69 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt @@ -165,7 +165,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt index c469112c3d06a..db7844b1e6fbf 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt @@ -243,7 +243,7 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_anonymous_placeholder'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty array(1) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt index de40cbdbb0504..c8ede104016a3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt @@ -155,5 +155,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_myisam'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt index 2bb6ea0caa7ee..f1547281438ec 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt @@ -175,5 +175,5 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_prepare_native_myisam_index'); ?> --EXPECT-- -PDO::prepare(): Argument #1 ($query) cannot be empty +PDO::prepare(): Argument #1 ($query) must not be empty done! diff --git a/ext/pdo_odbc/config.m4 b/ext/pdo_odbc/config.m4 index 794743d362f2d..af3668f5adf57 100644 --- a/ext/pdo_odbc/config.m4 +++ b/ext/pdo_odbc/config.m4 @@ -32,8 +32,8 @@ if test "$PHP_PDO_ODBC" != "no"; then AC_MSG_CHECKING([for selected PDO ODBC flavour]) - pdo_odbc_flavour="`echo $PHP_PDO_ODBC | cut -d, -f1`" - pdo_odbc_dir="`echo $PHP_PDO_ODBC | cut -d, -f2`" + pdo_odbc_flavour="$(echo $PHP_PDO_ODBC | cut -d, -f1)" + pdo_odbc_dir="$(echo $PHP_PDO_ODBC | cut -d, -f2)" if test "$pdo_odbc_dir" = "$PHP_PDO_ODBC" ; then pdo_odbc_dir= @@ -41,17 +41,17 @@ if test "$PHP_PDO_ODBC" != "no"; then AS_CASE([$pdo_odbc_flavour], [ibm-db2], [ - pdo_odbc_def_libdir=/home/db2inst1/sqllib/lib - pdo_odbc_def_incdir=/home/db2inst1/sqllib/include - pdo_odbc_def_lib=db2 + pdo_odbc_def_libdir=/home/db2inst1/sqllib/lib + pdo_odbc_def_incdir=/home/db2inst1/sqllib/include + pdo_odbc_def_lib=db2 ], [iODBC|iodbc], [pdo_odbc_pkgconfig_module=libiodbc], [unixODBC|unixodbc], [pdo_odbc_pkgconfig_module=odbc], [generic], [ - pdo_odbc_def_lib="`echo $PHP_PDO_ODBC | cut -d, -f3`" - pdo_odbc_def_ldflags="`echo $PHP_PDO_ODBC | cut -d, -f4`" - pdo_odbc_def_cflags="`echo $PHP_PDO_ODBC | cut -d, -f5`" - pdo_odbc_flavour="generic-$pdo_odbc_def_lib" + pdo_odbc_def_lib="$(echo $PHP_PDO_ODBC | cut -d, -f3)" + pdo_odbc_def_ldflags="$(echo $PHP_PDO_ODBC | cut -d, -f4)" + pdo_odbc_def_cflags="$(echo $PHP_PDO_ODBC | cut -d, -f5)" + pdo_odbc_flavour="generic-$pdo_odbc_def_lib" ], [AC_MSG_ERROR([Unknown ODBC flavour $pdo_odbc_flavour]PDO_ODBC_HELP_TEXT)]) @@ -59,13 +59,13 @@ if test "$PHP_PDO_ODBC" != "no"; then AC_MSG_RESULT([$pdo_odbc_flavour using pkg-config]) PKG_CHECK_MODULES([PDO_ODBC], [$pdo_odbc_pkgconfig_module]) else - if test -n "$pdo_odbc_dir"; then + AS_VAR_IF([pdo_odbc_dir],, [ + PDO_ODBC_INCDIR=$pdo_odbc_def_incdir + PDO_ODBC_LIBDIR=$pdo_odbc_def_libdir + ], [ PDO_ODBC_INCDIR="$pdo_odbc_dir/include" PDO_ODBC_LIBDIR="$pdo_odbc_dir/$PHP_LIBDIR" - else - PDO_ODBC_INCDIR="$pdo_odbc_def_incdir" - PDO_ODBC_LIBDIR="$pdo_odbc_def_libdir" - fi + ]) AC_MSG_RESULT([$pdo_odbc_flavour libs $PDO_ODBC_LIBDIR, diff --git a/ext/pdo_odbc/pdo_odbc_arginfo.h b/ext/pdo_odbc/pdo_odbc_arginfo.h index b74ed6f2917a6..2f281e6922f5b 100644 --- a/ext/pdo_odbc/pdo_odbc_arginfo.h +++ b/ext/pdo_odbc/pdo_odbc_arginfo.h @@ -15,8 +15,7 @@ static zend_class_entry *register_class_Pdo_Odbc(zend_class_entry *class_entry_P zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Odbc", class_Pdo_Odbc_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_USE_CURSOR_LIBRARY_value; ZVAL_LONG(&const_ATTR_USE_CURSOR_LIBRARY_value, PDO_ODBC_ATTR_USE_CURSOR_LIBRARY); diff --git a/ext/pdo_pgsql/pdo_pgsql_arginfo.h b/ext/pdo_pgsql/pdo_pgsql_arginfo.h index 4f70e79f8d5d4..f7f54cb600c72 100644 --- a/ext/pdo_pgsql/pdo_pgsql_arginfo.h +++ b/ext/pdo_pgsql/pdo_pgsql_arginfo.h @@ -86,8 +86,7 @@ static zend_class_entry *register_class_Pdo_Pgsql(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Pgsql", class_Pdo_Pgsql_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zval const_ATTR_DISABLE_PREPARES_value; ZVAL_LONG(&const_ATTR_DISABLE_PREPARES_value, PDO_PGSQL_ATTR_DISABLE_PREPARES); diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index c418e6f5ba986..684f7798a45f8 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -627,7 +627,7 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS) } if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index e2c686ed691ff..bc47c15a1eb5e 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -82,7 +82,7 @@ PHP_METHOD(Pdo_Sqlite, loadExtension) } if (extension_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/pdo_sqlite/pdo_sqlite_arginfo.h b/ext/pdo_sqlite/pdo_sqlite_arginfo.h index d0c006ac2d989..4abbc0bb625c6 100644 --- a/ext/pdo_sqlite/pdo_sqlite_arginfo.h +++ b/ext/pdo_sqlite/pdo_sqlite_arginfo.h @@ -58,8 +58,7 @@ static zend_class_entry *register_class_Pdo_Sqlite(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Pdo", "Sqlite", class_Pdo_Sqlite_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_PDO, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); #if defined(SQLITE_DETERMINISTIC) zval const_DETERMINISTIC_value; diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index f74667b214fdd..af95c81d803af 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4613,7 +4613,7 @@ PHP_FUNCTION(pg_meta_data) /* php_pgsql_meta_data() asserts that table_name is not empty */ if (ZSTR_LEN(table_name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -4799,7 +4799,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * ZEND_ASSERT(Z_TYPE_P(result) == IS_ARRAY); ZEND_ASSERT(!(opt & ~PGSQL_CONV_OPTS)); ZEND_ASSERT(table_name); - /* Table name cannot be empty for php_pgsql_meta_data() */ + /* Table name must not be empty for php_pgsql_meta_data() */ ZEND_ASSERT(ZSTR_LEN(table_name) != 0); array_init(&meta); @@ -5405,7 +5405,7 @@ PHP_FUNCTION(pg_convert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table_name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5618,7 +5618,7 @@ PHP_FUNCTION(pg_insert) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5840,7 +5840,7 @@ PHP_FUNCTION(pg_update) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5939,7 +5939,7 @@ PHP_FUNCTION(pg_delete) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -6095,7 +6095,7 @@ PHP_FUNCTION(pg_select) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(table) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -6143,13 +6143,13 @@ PHP_FUNCTION(pg_change_password) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(user) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } /* it is technically possible, but better to disallow it */ if (ZSTR_LEN(passwd) == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index a164584eb3add..85ca35b6a5a10 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1147,8 +1147,7 @@ static zend_class_entry *register_class_PgSql_Connection(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Connection", class_PgSql_Connection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1158,8 +1157,7 @@ static zend_class_entry *register_class_PgSql_Result(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Result", class_PgSql_Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1169,8 +1167,7 @@ static zend_class_entry *register_class_PgSql_Lob(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PgSql", "Lob", class_PgSql_Lob_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/pgsql/tests/changepassword.phpt b/ext/pgsql/tests/changepassword.phpt index 9c2eed40ef410..3271cd30331c5 100644 --- a/ext/pgsql/tests/changepassword.phpt +++ b/ext/pgsql/tests/changepassword.phpt @@ -24,6 +24,6 @@ try { var_dump(pg_change_password($conn, "inexistent_user", "postitpwd")); ?> --EXPECT-- -pg_change_password(): Argument #2 ($user) cannot be empty -pg_change_password(): Argument #3 ($password) cannot be empty +pg_change_password(): Argument #2 ($user) must not be empty +pg_change_password(): Argument #3 ($password) must not be empty bool(false) diff --git a/ext/pgsql/tests/pg_insert_002.phpt b/ext/pgsql/tests/pg_insert_002.phpt index 533b1762706cf..f304e561bb5f1 100644 --- a/ext/pgsql/tests/pg_insert_002.phpt +++ b/ext/pgsql/tests/pg_insert_002.phpt @@ -21,7 +21,7 @@ foreach (array('', '.', '..') as $table) { ?> Done --EXPECTF-- -pg_insert(): Argument #2 ($table_name) cannot be empty +pg_insert(): Argument #2 ($table_name) must not be empty pg_insert(): Argument #2 ($table_name) must be specified (.) pg_insert(): Argument #2 ($table_name) must be specified (..) Done diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index bd5f59d37e952..66b4b318e92ae 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -18,17 +18,16 @@ if test "$PHP_PHAR" != "no"; then ]), [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + AC_MSG_CHECKING([for phar openssl support]) - if test "$PHP_OPENSSL_SHARED" = "yes"; then - AC_MSG_RESULT([no (shared openssl)]) - else - if test "$PHP_OPENSSL" = "yes"; then + AS_VAR_IF([PHP_OPENSSL_SHARED], [yes], + [AC_MSG_RESULT([no (shared openssl)])], + [AS_VAR_IF([PHP_OPENSSL], [yes], [ AC_MSG_RESULT([yes]) - AC_DEFINE(PHAR_HAVE_OPENSSL,1,[ ]) - else - AC_MSG_RESULT([no]) - fi - fi + AC_DEFINE([PHAR_HAVE_OPENSSL], [1], + [Define to 1 if phar extension has native OpenSSL support.]) + ], [AC_MSG_RESULT([no])])]) + PHP_ADD_EXTENSION_DEP(phar, hash) PHP_ADD_EXTENSION_DEP(phar, spl) PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 4674d868f4905..41f45bd17f185 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -295,7 +295,6 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, zend_ulong unused; phar_archive_data *phar; phar_entry_info *entry = NULL; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path); @@ -320,7 +319,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, return NULL; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ @@ -401,7 +400,6 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo char *error, *arch, *entry2; size_t arch_len, entry_len; php_url *resource = NULL; - uint32_t host_len; /* pre-readonly check, we need to know if this is a data phar */ if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { @@ -438,7 +436,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), host_len, NULL, 0, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); @@ -533,10 +531,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options char *error, *arch, *entry2; size_t arch_len, entry_len; php_url *resource = NULL; - uint32_t host_len; zend_string *str_key; zend_ulong unused; - uint32_t path_len; /* pre-readonly check, we need to know if this is a data phar */ if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { @@ -573,7 +569,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), host_len, NULL, 0, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); @@ -582,7 +578,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - path_len = ZSTR_LEN(resource->path) - 1; + size_t path_len = ZSTR_LEN(resource->path) - 1; if (!(entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, 1))) { if (error) { diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index 4859c69fbe022..4debfecde41a1 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -22,6 +22,8 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); #ifdef PHAR_DIRSTREAM +#include "ext/standard/url.h" + php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); /* directory handlers */ diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index c52ee805b2b12..f1b2b0eba1e63 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -17,11 +17,10 @@ */ #include "phar_internal.h" +#include "ext/standard/php_filestat.h" +#include "ext/standard/file.h" /* For php_le_stream_context() */ -#define PHAR_FUNC(name) \ - static PHP_NAMED_FUNCTION(name) - -PHAR_FUNC(phar_opendir) /* {{{ */ +PHP_FUNCTION(phar_opendir) /* {{{ */ { char *filename; size_t filename_len; @@ -156,7 +155,7 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool return name; } -PHAR_FUNC(phar_file_get_contents) /* {{{ */ +PHP_FUNCTION(phar_file_get_contents) /* {{{ */ { zend_string *filename; zend_string *contents; @@ -233,7 +232,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_readfile) /* {{{ */ +PHP_FUNCTION(phar_readfile) /* {{{ */ { zend_string *filename; bool use_include_path = 0; @@ -277,7 +276,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_fopen) /* {{{ */ +PHP_FUNCTION(phar_fopen) /* {{{ */ { zend_string *filename; char *mode; @@ -653,7 +652,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ /* }}} */ #define PharFileFunction(fname, funcnum, orig) \ -ZEND_NAMED_FUNCTION(fname) { \ +PHP_FUNCTION(fname) { \ if (!PHAR_G(intercepted)) { \ PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \ } else { \ @@ -725,7 +724,7 @@ PharFileFunction(phar_file_exists, FS_EXISTS, orig_file_exists) PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir) /* }}} */ -PHAR_FUNC(phar_is_file) /* {{{ */ +PHP_FUNCTION(phar_is_file) /* {{{ */ { char *filename; size_t filename_len; @@ -791,7 +790,7 @@ PHAR_FUNC(phar_is_file) /* {{{ */ } /* }}} */ -PHAR_FUNC(phar_is_link) /* {{{ */ +PHP_FUNCTION(phar_is_link) /* {{{ */ { char *filename; size_t filename_len; @@ -886,7 +885,7 @@ void phar_release_functions(void) PHAR_G(orig_##func) = NULL; \ if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \ PHAR_G(orig_##func) = orig->internal_function.handler; \ - orig->internal_function.handler = phar_##func; \ + orig->internal_function.handler = PHP_FN(phar_##func); \ } void phar_intercept_functions_init(void) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index ff103e11686d2..99767468ee71c 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -19,9 +19,14 @@ #define PHAR_MAIN 1 #include "phar_internal.h" +#include "php_phar.h" #include "SAPI.h" #include "func_interceptors.h" +#include "ext/standard/crc32.h" #include "ext/standard/php_var.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ +#include "ext/standard/info.h" +#include "zend_smart_str.h" static void destroy_phar_data(zval *zv); @@ -238,7 +243,7 @@ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ /** * Delete refcount and destruct if needed. On destruct return 1 else 0. */ -int phar_archive_delref(phar_archive_data *phar) /* {{{ */ +bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ { if (phar->is_persistent) { return 0; @@ -481,7 +486,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ /** * Open an already loaded phar */ -int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; #ifdef PHP_WIN32 @@ -559,7 +564,7 @@ int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t ali * Attempt to serialize the data. * Callers are responsible for handling EG(exception) if one occurs. */ -void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker *tracker, int persistent) /* {{{ */ +void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { php_serialize_data_t metadata_hash; smart_str metadata_str = {0}; @@ -585,7 +590,7 @@ void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker * * Precondition: phar_metadata_tracker_has_data is true */ -int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zval *metadata, int persistent, HashTable *unserialize_options, const char* method_name) /* {{{ */ +zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zval *metadata, bool persistent, HashTable *unserialize_options, const char* method_name) /* {{{ */ { const bool has_unserialize_options = unserialize_options != NULL && zend_hash_num_elements(unserialize_options) > 0; /* It should be impossible to create a zval in a persistent phar/entry. */ @@ -626,7 +631,7 @@ int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tracker, zv /** * Check if this has any data, serialized or as a raw value. */ -bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, int persistent) /* {{{ */ +bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { ZEND_ASSERT(!persistent || Z_ISUNDEF(tracker->val)); return !Z_ISUNDEF(tracker->val) || tracker->str != NULL; @@ -636,7 +641,7 @@ bool phar_metadata_tracker_has_data(const phar_metadata_tracker *tracker, int pe /** * Free memory used to track the metadata and set all fields to be null/undef. */ -void phar_metadata_tracker_free(phar_metadata_tracker *tracker, int persistent) /* {{{ */ +void phar_metadata_tracker_free(phar_metadata_tracker *tracker, bool persistent) /* {{{ */ { /* Free the string before the zval in case the zval's destructor modifies the metadata */ if (tracker->str) { @@ -658,7 +663,7 @@ void phar_metadata_tracker_free(phar_metadata_tracker *tracker, int persistent) /** * Free memory used to track the metadata and set all fields to be null/undef. */ -void phar_metadata_tracker_copy(phar_metadata_tracker *dest, const phar_metadata_tracker *source, int persistent) /* {{{ */ +void phar_metadata_tracker_copy(phar_metadata_tracker *dest, const phar_metadata_tracker *source, bool persistent) /* {{{ */ { ZEND_ASSERT(dest != source); phar_metadata_tracker_free(dest, persistent); @@ -694,7 +699,7 @@ void phar_metadata_tracker_clone(phar_metadata_tracker *tracker) /* {{{ */ * * data is the serialized zval */ -void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, int persistent) /* {{{ */ +void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent) /* {{{ */ { phar_metadata_tracker_free(tracker, persistent); if (zip_metadata_len) { @@ -1302,7 +1307,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch /** * Create or open a phar for writing */ -int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { const char *ext_str, *z; char *my_error; @@ -1379,7 +1384,9 @@ int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, siz } /* }}} */ -int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); + +zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *mydata; php_stream *fp; @@ -1402,7 +1409,7 @@ int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, si } if (fp) { - if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, is_data, error) == SUCCESS) { + if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error) == SUCCESS) { if ((*pphar)->is_data || !PHAR_G(readonly)) { (*pphar)->is_writeable = 1; } @@ -1532,18 +1539,18 @@ int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, si * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual; - int ret, is_data = 0; + bool is_data = false; if (error) { *error = NULL; } if (!strstr(fname, ".phar")) { - is_data = 1; + is_data = true; } if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { @@ -1574,7 +1581,7 @@ int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t a fname_len = ZSTR_LEN(actual); } - ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, is_data, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -1618,7 +1625,7 @@ static inline char *phar_strnstr(const char *buf, int buf_len, const char *searc * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, int is_data, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; @@ -1772,7 +1779,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char if (got > 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, is_data, compression, error); + return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); } } } @@ -1956,7 +1963,7 @@ static int phar_check_str(const char *fname, const char *ext_str, size_t ext_len * the last parameter should be set to tell the thing to assume that filename is the full path, and only to check the * extension rules, not to iterate. */ -int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete) /* {{{ */ +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete) /* {{{ */ { const char *pos, *slash; @@ -2023,11 +2030,11 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const zend_string *str_key; ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&PHAR_G(phar_fname_map), str_key, pphar) { - if (ZSTR_LEN(str_key) > (uint32_t) filename_len) { + if (ZSTR_LEN(str_key) > filename_len) { continue; } - if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && ((uint32_t)filename_len == ZSTR_LEN(str_key) + if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && (filename_len == ZSTR_LEN(str_key) || filename[ZSTR_LEN(str_key)] == '/' || filename[ZSTR_LEN(str_key)] == '\0')) { *ext_str = filename + (ZSTR_LEN(str_key) - pphar->ext_len); goto woohoo; @@ -2036,11 +2043,11 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const if (PHAR_G(manifest_cached)) { ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&cached_phars, str_key, pphar) { - if (ZSTR_LEN(str_key) > (uint32_t) filename_len) { + if (ZSTR_LEN(str_key) > filename_len) { continue; } - if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && ((uint32_t)filename_len == ZSTR_LEN(str_key) + if (!memcmp(filename, ZSTR_VAL(str_key), ZSTR_LEN(str_key)) && (filename_len == ZSTR_LEN(str_key) || filename[ZSTR_LEN(str_key)] == '/' || filename[ZSTR_LEN(str_key)] == '\0')) { *ext_str = filename + (ZSTR_LEN(str_key) - pphar->ext_len); goto woohoo; @@ -2101,7 +2108,7 @@ int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const } /* }}} */ -static int php_check_dots(const char *element, size_t n) /* {{{ */ +static bool php_check_dots(const char *element, size_t n) /* {{{ */ { for(n-- ; n != SIZE_MAX; --n) { if (element[n] != '.') { @@ -2237,7 +2244,7 @@ char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ * * This is used by phar_parse_url() */ -int phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ +zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ { const char *ext_str; #ifdef PHP_WIN32 @@ -2314,7 +2321,7 @@ int phar_split_fname(const char *filename, size_t filename_len, char **arch, siz * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ { if (error) { *error = NULL; @@ -2362,7 +2369,7 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* fname = actual; } - int ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, 0, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2375,10 +2382,8 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* /** * Validate the CRC32 of a file opened from within the phar */ -int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ +zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ { - uint32_t crc = php_crc32_bulk_init(); - int len = idata->internal_file->uncompressed_filesize, ret; php_stream *fp = idata->fp; phar_entry_info *entry = idata->internal_file; @@ -2443,7 +2448,8 @@ int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, php_stream_seek(fp, idata->zero, SEEK_SET); - ret = php_crc32_stream_bulk_update(&crc, fp, len); + uint32_t crc = php_crc32_bulk_init(); + zend_result ret = php_crc32_stream_bulk_update(&crc, fp, idata->internal_file->uncompressed_filesize); php_stream_seek(fp, idata->zero, SEEK_SET); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 625b8f1f16f90..eb836ac691adc 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -24,39 +24,9 @@ #include #include "php.h" #include "tar.h" -#include "php_ini.h" -#include "zend_constants.h" -#include "zend_execute.h" -#include "zend_exceptions.h" +#include "pharzip.h" #include "zend_hash.h" -#include "zend_interfaces.h" -#include "zend_operators.h" -#include "zend_sort.h" -#include "zend_vm.h" -#include "zend_smart_str.h" -#include "main/php_streams.h" -#include "main/streams/php_stream_plain_wrapper.h" -#include "main/SAPI.h" -#include "main/php_main.h" -#include "main/php_open_temporary_file.h" -#include "ext/standard/info.h" -#include "ext/standard/basic_functions.h" -#include "ext/standard/file.h" -#include "ext/standard/php_string.h" -#include "ext/standard/url.h" -#include "ext/standard/crc32.h" -#include "ext/standard/md5.h" -#include "ext/standard/sha1.h" -#include "ext/standard/php_var.h" -#include "ext/standard/php_versioning.h" -#include "Zend/zend_virtual_cwd.h" -#include "ext/spl/spl_array.h" #include "ext/spl/spl_directory.h" -#include "ext/spl/spl_exceptions.h" -#include "ext/spl/spl_iterators.h" -#include "php_phar.h" -#include "ext/hash/php_hash.h" -#include "ext/hash/php_hash_sha.h" /* PHP_ because this is public information via MINFO */ #define PHP_PHAR_API_VERSION "1.1.1" @@ -193,8 +163,6 @@ ZEND_EXTERN_MODULE_GLOBALS(phar) ZEND_TSRMLS_CACHE_EXTERN() #endif -#include "pharzip.h" - typedef union _phar_archive_object phar_archive_object; typedef union _phar_entry_object phar_entry_object; @@ -331,7 +299,7 @@ struct _phar_entry_fp { phar_entry_fp_info *manifest; }; -static inline php_stream *phar_get_entrypfp(phar_entry_info *entry) +static inline php_stream *phar_get_entrypfp(const phar_entry_info *entry) { if (!entry->is_persistent) { return entry->phar->fp; @@ -339,35 +307,7 @@ static inline php_stream *phar_get_entrypfp(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].fp; } -static inline php_stream *phar_get_entrypufp(phar_entry_info *entry) -{ - if (!entry->is_persistent) { - return entry->phar->ufp; - } - return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp; -} - -static inline void phar_set_entrypfp(phar_entry_info *entry, php_stream *fp) -{ - if (!entry->phar->is_persistent) { - entry->phar->fp = fp; - return; - } - - PHAR_G(cached_fp)[entry->phar->phar_pos].fp = fp; -} - -static inline void phar_set_entrypufp(phar_entry_info *entry, php_stream *fp) -{ - if (!entry->phar->is_persistent) { - entry->phar->ufp = fp; - return; - } - - PHAR_G(cached_fp)[entry->phar->phar_pos].ufp = fp; -} - -static inline php_stream *phar_get_pharfp(phar_archive_data *phar) +static inline php_stream *phar_get_pharfp(const phar_archive_data *phar) { if (!phar->is_persistent) { return phar->fp; @@ -375,49 +315,7 @@ static inline php_stream *phar_get_pharfp(phar_archive_data *phar) return PHAR_G(cached_fp)[phar->phar_pos].fp; } -static inline php_stream *phar_get_pharufp(phar_archive_data *phar) -{ - if (!phar->is_persistent) { - return phar->ufp; - } - return PHAR_G(cached_fp)[phar->phar_pos].ufp; -} - -static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) -{ - if (!phar->is_persistent) { - phar->fp = fp; - return; - } - - PHAR_G(cached_fp)[phar->phar_pos].fp = fp; -} - -static inline void phar_set_pharufp(phar_archive_data *phar, php_stream *fp) -{ - if (!phar->is_persistent) { - phar->ufp = fp; - return; - } - - PHAR_G(cached_fp)[phar->phar_pos].ufp = fp; -} - -static inline void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zend_off_t offset) -{ - phar_entry_fp_info *data; - - if (!entry->is_persistent) { - entry->fp_type = type; - entry->offset = offset; - return; - } - data = &(PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos]); - data->fp_type = type; - data->offset = offset; -} - -static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) +static inline enum phar_fp_type phar_get_fp_type(const phar_entry_info *entry) { if (!entry->is_persistent) { return entry->fp_type; @@ -425,19 +323,6 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type; } -static inline zend_off_t phar_get_fp_offset(phar_entry_info *entry) -{ - if (!entry->is_persistent) { - return entry->offset; - } - if (PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) { - if (!PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) { - PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset; - } - } - return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset; -} - #define PHAR_MIME_PHP '\0' #define PHAR_MIME_PHPS '\1' #define PHAR_MIME_OTHER '\2' @@ -487,10 +372,8 @@ static inline void phar_unixify_path_separators(char *path, size_t path_len) } } #endif -/** - * validate an alias, returns 1 for success, 0 for failure - */ -static inline int phar_validate_alias(const char *alias, size_t alias_len) /* {{{ */ + +static inline bool phar_validate_alias(const char *alias, size_t alias_len) /* {{{ */ { return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) || memchr(alias, ';', alias_len) || memchr(alias, '\n', alias_len) || memchr(alias, '\r', alias_len)); @@ -522,16 +405,15 @@ void phar_request_initialize(void); void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); -int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -int phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -int phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_open_executed_filename(char *alias, size_t alias_len, char **error); -int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); -int phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); -int phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); -int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); +zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); +zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); +zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); +zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); +zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); /* utility functions */ zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error); @@ -540,33 +422,31 @@ char *phar_compress_filter(phar_entry_info * entry, int return_unknown); /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); -int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); +zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar); char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd); phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error); -void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, int persistent); -bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, int persistent); +void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent); +bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, bool persistent); /* If this has data, free it and set all values to undefined. */ -void phar_metadata_tracker_free(phar_metadata_tracker* val, int persistent); -void phar_metadata_tracker_copy(phar_metadata_tracker* dest, const phar_metadata_tracker *source, int persistent); +void phar_metadata_tracker_free(phar_metadata_tracker* val, bool persistent); +void phar_metadata_tracker_copy(phar_metadata_tracker* dest, const phar_metadata_tracker *source, bool persistent); void phar_metadata_tracker_clone(phar_metadata_tracker* tracker); -void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker* tracker, int persistent); -int phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tracker, zval *value, int persistent, HashTable *unserialize_options, const char* method_name); +void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker* tracker, bool persistent); +zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tracker, zval *value, bool persistent, HashTable *unserialize_options, const char* method_name); void destroy_phar_manifest_entry(zval *zv); int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links); php_stream *phar_get_efp(phar_entry_info *entry, int follow_links); -int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); -int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links); +zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); +zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links); phar_entry_info *phar_get_link_source(phar_entry_info *entry); -int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error); -int phar_separate_entry_fp(phar_entry_info *entry, char **error); -int phar_open_archive_fp(phar_archive_data *phar); -int phar_copy_on_write(phar_archive_data **pphar); +zend_result phar_open_archive_fp(phar_archive_data *phar); +zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ -int phar_is_tar(char *buf, char *fname); -int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error); -int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); +bool phar_is_tar(char *buf, char *fname); +zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); +zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int defaultstub, char **error); /* zip functions in zip.c */ @@ -575,23 +455,22 @@ int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t a int phar_zip_flush(phar_archive_data *archive, char *user_stub, zend_long len, int defaultstub, char **error); #ifdef PHAR_MAIN -static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, int is_data, char **error); extern const php_stream_wrapper php_stream_phar_wrapper; #else extern HashTable cached_phars; extern HashTable cached_alias; #endif -int phar_archive_delref(phar_archive_data *phar); +bool phar_archive_delref(phar_archive_data *phar); void phar_entry_delref(phar_entry_data *idata); phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security); phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security); phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); -int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); +zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); int phar_flush(phar_archive_data *archive, char *user_stub, zend_long len, int convert, char **error); -int phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete); -int phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete); +zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); typedef enum { pcr_use_query, diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 9d16512ec5d13..0d992a6dd7f6a 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -20,6 +20,14 @@ #include "phar_internal.h" #include "func_interceptors.h" #include "phar_object_arginfo.h" +#include "ext/spl/spl_array.h" +#include "ext/spl/spl_exceptions.h" +#include "ext/spl/spl_iterators.h" +#include "ext/standard/php_var.h" +#include "main/SAPI.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" +#include "zend_exceptions.h" static zend_class_entry *phar_ce_archive; static zend_class_entry *phar_ce_data; @@ -1922,7 +1930,7 @@ PHP_METHOD(Phar, isFileFormat) } /* }}} */ -static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp) /* {{{ */ +static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *fp) /* {{{ */ { char *error; zend_off_t offset; @@ -2600,12 +2608,11 @@ PHP_METHOD(Phar, isWritable) /* {{{ Deletes a named file within the archive. */ PHP_METHOD(Phar, delete) { - char *fname; - size_t fname_len; + zend_string *file_name; char *error; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } @@ -2621,7 +2628,7 @@ PHP_METHOD(Phar, delete) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_TRUE; @@ -2631,7 +2638,7 @@ PHP_METHOD(Phar, delete) phar_obj->archive->is_modified = 1; } } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be deleted", fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be deleted", ZSTR_VAL(file_name)); RETURN_THROWS(); } @@ -2679,12 +2686,13 @@ PHP_METHOD(Phar, getPath) */ PHP_METHOD(Phar, setAlias) { - char *alias, *error, *oldalias; + zend_string *new_alias = NULL; + char *error, *oldalias; phar_archive_data *fd_ptr; - size_t alias_len, oldalias_len; + size_t oldalias_len; int old_temp, readd = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_alias) == FAILURE) { RETURN_THROWS(); } @@ -2711,12 +2719,12 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - if (alias_len == phar_obj->archive->alias_len && memcmp(phar_obj->archive->alias, alias, alias_len) == 0) { + if (zend_string_equals_cstr(new_alias, phar_obj->archive->alias, phar_obj->archive->alias_len)) { RETURN_TRUE; } - if (alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, fd_ptr->fname); - if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), new_alias))) { + spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), fd_ptr->fname); + if (SUCCESS == phar_free_alias(fd_ptr, ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { efree(error); goto valid_alias; } @@ -2724,9 +2732,9 @@ PHP_METHOD(Phar, setAlias) efree(error); RETURN_THROWS(); } - if (!phar_validate_alias(alias, alias_len)) { + if (!phar_validate_alias(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->archive->fname); + "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), phar_obj->archive->fname); RETURN_THROWS(); } valid_alias: @@ -2743,13 +2751,8 @@ PHP_METHOD(Phar, setAlias) oldalias_len = phar_obj->archive->alias_len; old_temp = phar_obj->archive->is_temporary_alias; - if (alias_len) { - phar_obj->archive->alias = estrndup(alias, alias_len); - } else { - phar_obj->archive->alias = NULL; - } - - phar_obj->archive->alias_len = alias_len; + phar_obj->archive->alias = estrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias)); + phar_obj->archive->alias_len = ZSTR_LEN(new_alias); phar_obj->archive->is_temporary_alias = 0; phar_flush(phar_obj->archive, NULL, 0, 0, &error); @@ -2765,7 +2768,7 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, phar_obj->archive); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), new_alias, phar_obj->archive); if (oldalias) { efree(oldalias); @@ -3036,7 +3039,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - phar_obj->archive->sig_flags = (php_uint32)algo; + phar_obj->archive->sig_flags = (uint32_t)algo; phar_obj->archive->is_modified = 1; PHAR_G(openssl_privatekey) = key; PHAR_G(openssl_privatekey_len) = key_len; @@ -3408,13 +3411,13 @@ PHP_METHOD(Phar, decompressFiles) /* {{{ copy a file internal to the phar archive to another new file within the phar */ PHP_METHOD(Phar, copy) { - char *oldfile, *newfile, *error; + char *error; const char *pcr_error; - size_t oldfile_len, newfile_len; phar_entry_info *oldentry, newentry = {0}, *temp; - size_t tmp_len = 0; + zend_string *new_file = NULL; + zend_string *old_file = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &oldfile, &oldfile_len, &newfile, &newfile_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "PP", &old_file, &new_file) == FAILURE) { RETURN_THROWS(); } @@ -3422,43 +3425,43 @@ PHP_METHOD(Phar, copy) if (PHAR_G(readonly) && !phar_obj->archive->is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot copy \"%s\" to \"%s\", phar is read-only", oldfile, newfile); + "Cannot copy \"%s\" to \"%s\", phar is read-only", ZSTR_VAL(old_file), ZSTR_VAL(new_file)); RETURN_THROWS(); } - if (oldfile_len >= sizeof(".phar")-1 && !memcmp(oldfile, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(old_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (newfile_len >= sizeof(".phar")-1 && !memcmp(newfile, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(new_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL == (oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, (uint32_t) oldfile_len)) || oldentry->is_deleted) { + if (NULL == (oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file)) || oldentry->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (NULL != (temp = zend_hash_str_find_ptr(&phar_obj->archive->manifest, newfile, (uint32_t) newfile_len)) && !temp->is_deleted) { + if (NULL != (temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file)) && !temp->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", oldfile, newfile, phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - tmp_len = newfile_len; - if (phar_path_check(&newfile, &tmp_len, &pcr_error) > pcr_is_ok) { + size_t tmp_len = ZSTR_LEN(new_file); + char *tmp_new_file = ZSTR_VAL(new_file); + if (phar_path_check(&tmp_new_file, &tmp_len, &pcr_error) > pcr_is_ok) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", newfile, pcr_error, oldfile, phar_obj->archive->fname); + "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), phar_obj->archive->fname); RETURN_THROWS(); } - newfile_len = tmp_len; if (phar_obj->archive->is_persistent) { if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { @@ -3466,15 +3469,15 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } /* re-populate with copied-on-write entry */ - oldentry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, oldfile, (uint32_t) oldfile_len); + oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file); } memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info)); phar_metadata_tracker_clone(&newentry.metadata_tracker); - newentry.filename = estrndup(newfile, newfile_len); - newentry.filename_len = newfile_len; + newentry.filename = estrndup(tmp_new_file, tmp_len); + newentry.filename_len = tmp_len; newentry.fp_refcount = 0; if (oldentry->fp_type != PHAR_FP) { @@ -3487,7 +3490,7 @@ PHP_METHOD(Phar, copy) } } - zend_hash_str_add_mem(&oldentry->phar->manifest, newfile, newfile_len, &newentry, sizeof(phar_entry_info)); + zend_hash_str_add_mem(&oldentry->phar->manifest, ZSTR_VAL(new_file), tmp_len, &newentry, sizeof(phar_entry_info)); phar_obj->archive->is_modified = 1; phar_flush(phar_obj->archive, 0, 0, 0, &error); @@ -3503,34 +3506,34 @@ PHP_METHOD(Phar, copy) /* {{{ determines whether a file exists in the phar */ PHP_METHOD(Phar, offsetExists) { - char *fname; - size_t fname_len; + zend_string *file_name; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint32_t) fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ RETURN_FALSE; } } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { /* none of these are real files, so they don't exist */ RETURN_FALSE; } RETURN_TRUE; } else { - if (zend_hash_str_exists(&phar_obj->archive->virtual_dirs, fname, (uint32_t) fname_len)) { - RETURN_TRUE; + /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ + if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { + RETURN_FALSE; } - RETURN_FALSE; + RETURN_BOOL(zend_hash_exists(&phar_obj->archive->virtual_dirs, file_name)); } } /* }}} */ @@ -3538,31 +3541,31 @@ PHP_METHOD(Phar, offsetExists) /* {{{ get a PharFileInfo object for a specific file */ PHP_METHOD(Phar, offsetGet) { - char *fname, *error; - size_t fname_len; + char *error; phar_entry_info *entry; + zend_string *file_name = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); /* security is 0 here so that we can get a better error message than "entry doesn't exist" */ - if (!(entry = phar_get_entry_info_dir(phar_obj->archive, fname, fname_len, 1, &error, 0))) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", fname, error?", ":"", error?error:""); + if (!(entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, 0))) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", ZSTR_VAL(file_name), error?", ":"", error?error:""); } else { - if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { + if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot directly get any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3572,7 +3575,7 @@ PHP_METHOD(Phar, offsetGet) efree(entry); } - zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, fname); + zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, ZSTR_VAL(file_name)); zval zfname; ZVAL_NEW_STR(&zfname, sfname); @@ -3587,11 +3590,9 @@ PHP_METHOD(Phar, offsetGet) /* }}} */ /* {{{ add a file within the phar archive from a string or resource */ -static void phar_add_file(phar_archive_data **pphar, char *filename, size_t filename_len, char *cont_str, size_t cont_len, zval *zresource) +static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, const zend_string *content, zval *zresource) { - size_t start_pos=0; char *error; - size_t contents_len; phar_entry_data *data; php_stream *contents_file = NULL; php_stream_statbuf ssb; @@ -3600,14 +3601,21 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, size_t file ALLOCA_FLAG(filename_use_heap) #endif - if (filename_len >= sizeof(".phar")-1) { - start_pos = '/' == filename[0]; /* account for any leading slash: multiple-leads handled elsewhere */ - if (!memcmp(&filename[start_pos], ".phar", sizeof(".phar")-1) && (filename[start_pos+5] == '/' || filename[start_pos+5] == '\\' || filename[start_pos+5] == '\0')) { + if ( + zend_string_starts_with_literal(file_name, ".phar") + || zend_string_starts_with_literal(file_name, "/.phar") + ) { + size_t prefix_len = (ZSTR_VAL(file_name)[0] == '/') + sizeof(".phar")-1; + char next_char = ZSTR_VAL(file_name)[prefix_len]; + if (next_char == '/' || next_char == '\\' || next_char == '\0') { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); return; } } + /* TODO How to handle Windows path normalisation with zend_string ? */ + char *filename = ZSTR_VAL(file_name); + size_t filename_len = ZSTR_LEN(file_name); #ifdef PHP_WIN32 save_filename = filename; if (memchr(filename, '\\', filename_len)) { @@ -3631,9 +3639,11 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, size_t file } if (!data->internal_file->is_dir) { - if (cont_str) { - contents_len = php_stream_write(data->fp, cont_str, cont_len); - if (contents_len != cont_len) { + size_t contents_len = 0; + if (content) { + contents_len = ZSTR_LEN(content); + size_t written_len = php_stream_write(data->fp, ZSTR_VAL(content), ZSTR_LEN(content)); + if (written_len != contents_len) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); goto finish; } @@ -3682,17 +3692,17 @@ finish: ; /* }}} */ /* {{{ create a directory within the phar archive */ -static void phar_mkdir(phar_archive_data **pphar, char *dirname, size_t dirname_len) +static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) { char *error; phar_entry_data *data; - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, dirname, dirname_len, "w+b", 2, &error, 1))) { + if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), "w+b", 2, &error, 1))) { if (error) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", dirname, error); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", ZSTR_VAL(dir_name), error); efree(error); } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created", dirname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created", ZSTR_VAL(dir_name)); } return; @@ -3719,12 +3729,12 @@ static void phar_mkdir(phar_archive_data **pphar, char *dirname, size_t dirname_ /* {{{ set the contents of an internal file to those of an external file */ PHP_METHOD(Phar, offsetSet) { - char *fname, *cont_str = NULL; - size_t fname_len, cont_len; zval *zresource = NULL; + zend_string *file_name = NULL; + zend_string *file_content = NULL; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "pr", &fname, &fname_len, &zresource) == FAILURE - && zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &fname, &fname_len, &cont_str, &cont_len) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "Pr", &file_name, &zresource) == FAILURE + && zend_parse_parameters(ZEND_NUM_ARGS(), "PS", &file_name, &file_content) == FAILURE) { RETURN_THROWS(); } @@ -3735,33 +3745,33 @@ PHP_METHOD(Phar, offsetSet) RETURN_THROWS(); } - if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { + if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", phar_obj->archive->fname); RETURN_THROWS(); } - if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(file_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } - phar_add_file(&(phar_obj->archive), fname, fname_len, cont_str, cont_len, zresource); + phar_add_file(&(phar_obj->archive), file_name, file_content, zresource); } /* }}} */ /* {{{ remove a file from a phar */ PHP_METHOD(Phar, offsetUnset) { - char *fname, *error; - size_t fname_len; + char *error; + zend_string *file_name; phar_entry_info *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); } @@ -3772,8 +3782,8 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } - if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint32_t) fname_len)) { - if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len))) { + if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { + if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return; @@ -3785,7 +3795,7 @@ PHP_METHOD(Phar, offsetUnset) RETURN_THROWS(); } /* re-populate entry after copy on write */ - entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint32_t) fname_len); + entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); } entry->is_modified = 0; entry->is_deleted = 1; @@ -3804,55 +3814,53 @@ PHP_METHOD(Phar, offsetUnset) /* {{{ Adds an empty directory to the phar archive */ PHP_METHOD(Phar, addEmptyDir) { - char *dirname; - size_t dirname_len; + zend_string *dir_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &dirname, &dirname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &dir_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (dirname_len >= sizeof(".phar")-1 && !memcmp(dirname, ".phar", sizeof(".phar")-1)) { + if (zend_string_starts_with_literal(dir_name, ".phar")) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); RETURN_THROWS(); } - phar_mkdir(&phar_obj->archive, dirname, dirname_len); + phar_mkdir(&phar_obj->archive, dir_name); } /* }}} */ /* {{{ Adds a file to the archive using the filename, or the second parameter as the name within the archive */ PHP_METHOD(Phar, addFile) { - char *fname, *localname = NULL; - size_t fname_len, localname_len = 0; + zend_string *file_name; + zend_string *local_name = NULL; php_stream *resource; zval zresource; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &localname, &localname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &file_name, &local_name) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - if (!strstr(fname, "://") && php_check_open_basedir(fname)) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive, open_basedir restrictions prevent this", fname); + if (!strstr(ZSTR_VAL(file_name), "://") && php_check_open_basedir(ZSTR_VAL(file_name))) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive, open_basedir restrictions prevent this", ZSTR_VAL(file_name)); RETURN_THROWS(); } - if (!(resource = php_stream_open_wrapper(fname, "rb", 0, NULL))) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", fname); + if (!(resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL))) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", ZSTR_VAL(file_name)); RETURN_THROWS(); } - if (localname) { - fname = localname; - fname_len = localname_len; + if (local_name) { + file_name = local_name; } php_stream_to_zval(resource, &zresource); - phar_add_file(&(phar_obj->archive), fname, fname_len, NULL, 0, &zresource); + phar_add_file(&(phar_obj->archive), file_name, NULL, &zresource); zval_ptr_dtor(&zresource); } /* }}} */ @@ -3860,16 +3868,16 @@ PHP_METHOD(Phar, addFile) /* {{{ Adds a file to the archive using its contents as a string */ PHP_METHOD(Phar, addFromString) { - char *localname, *cont_str; - size_t localname_len, cont_len; + zend_string *local_name = NULL; + zend_string *file_content = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &localname, &localname_len, &cont_str, &cont_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "PS", &local_name, &file_content) == FAILURE) { RETURN_THROWS(); } PHAR_ARCHIVE_OBJECT(); - phar_add_file(&(phar_obj->archive), localname, localname_len, cont_str, cont_len, NULL); + phar_add_file(&(phar_obj->archive), local_name, file_content, NULL); } /* }}} */ @@ -4004,7 +4012,7 @@ PHP_METHOD(Phar, getMetadata) /* }}} */ /* {{{ Modifies the phar metadata or throws */ -static int serialize_metadata_or_throw(phar_metadata_tracker *tracker, int persistent, zval *metadata) +static zend_result serialize_metadata_or_throw(phar_metadata_tracker *tracker, int persistent, zval *metadata) { php_serialize_data_t metadata_hash; smart_str main_metadata_str = {0}; @@ -4105,7 +4113,7 @@ PHP_METHOD(Phar, delMetadata) } /* }}} */ -static int phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */ +static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */ { php_stream_statbuf ssb; size_t len; @@ -4259,7 +4267,7 @@ static int phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, } } - if (FAILURE == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to seek internal file pointer", entry->filename, fullpath); efree(fullpath); php_stream_close(fp); diff --git a/ext/phar/phar_object.stub.php b/ext/phar/phar_object.stub.php index e20b575d87a5c..ae5bd69c32f48 100644 --- a/ext/phar/phar_object.stub.php +++ b/ext/phar/phar_object.stub.php @@ -187,10 +187,10 @@ public function offsetSet($localName, $value): void {} public function offsetUnset($localName): void {} /** @tentative-return-type */ - public function setAlias(string $alias): bool {} + public function setAlias(string $alias): true {} /** @tentative-return-type */ - public function setDefaultStub(?string $index = null, ?string $webIndex = null): bool {} + public function setDefaultStub(?string $index = null, ?string $webIndex = null): true {} /** @tentative-return-type */ public function setMetadata(mixed $metadata): void {} diff --git a/ext/phar/phar_object_arginfo.h b/ext/phar/phar_object_arginfo.h index 16482611560b7..6fe081fe4dbe8 100644 --- a/ext/phar/phar_object_arginfo.h +++ b/ext/phar/phar_object_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4182a1159f6cf8a0d71a7814d0435b5e2be29276 */ + * Stub hash: 031dc8f07d2d9bac4a5f82f4ac2c5b3da5995405 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -133,11 +133,11 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_offsetUnset ZEND_ARG_INFO(0, localName) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setAlias, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setAlias, 0, 1, IS_TRUE, 0) ZEND_ARG_TYPE_INFO(0, alias, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setDefaultStub, 0, 0, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Phar_setDefaultStub, 0, 0, IS_TRUE, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, webIndex, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -302,9 +302,14 @@ ZEND_END_ARG_INFO() #define arginfo_class_PharData_offsetUnset arginfo_class_Phar_offsetUnset -#define arginfo_class_PharData_setAlias arginfo_class_Phar_setAlias +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PharData_setAlias, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, alias, IS_STRING, 0) +ZEND_END_ARG_INFO() -#define arginfo_class_PharData_setDefaultStub arginfo_class_Phar_setDefaultStub +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PharData_setDefaultStub, 0, 0, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, webIndex, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() #define arginfo_class_PharData_setMetadata arginfo_class_Phar_setMetadata @@ -608,7 +613,7 @@ static zend_class_entry *register_class_PharException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharException", class_PharException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -618,7 +623,7 @@ static zend_class_entry *register_class_Phar(zend_class_entry *class_entry_Recur zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Phar", class_Phar_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveDirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveDirectoryIterator, 0); zend_class_implements(class_entry, 2, class_entry_Countable, class_entry_ArrayAccess); zval const_BZ2_value; @@ -725,7 +730,7 @@ static zend_class_entry *register_class_PharData(zend_class_entry *class_entry_R zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharData", class_PharData_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveDirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveDirectoryIterator, 0); zend_class_implements(class_entry, 2, class_entry_Countable, class_entry_ArrayAccess); return class_entry; @@ -736,7 +741,7 @@ static zend_class_entry *register_class_PharFileInfo(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PharFileInfo", class_PharFileInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); return class_entry; } diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index 9825909ee22fc..66db4c06829c0 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -32,6 +32,6 @@ extern zend_module_entry phar_module_entry; #define PHP_PHAR_API PHPAPI #endif -PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len); +PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len); #endif /* PHP_PHAR_H */ diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 79f02ff70db5e..f5e1d9514c724 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -168,7 +168,6 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha php_url *resource = NULL; php_stream *fpf; zval *pzoption, *metadata; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { return NULL; @@ -187,7 +186,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha return NULL; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); /* strip leading "/" */ @@ -565,7 +564,6 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f char *internal_file, *error; phar_archive_data *phar; phar_entry_info *entry; - uint32_t host_len; size_t internal_file_len; if ((resource = phar_parse_url(wrapper, url, "r", flags|PHP_STREAM_URL_STAT_QUIET)) == NULL) { @@ -583,7 +581,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f return FAILURE; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ @@ -674,7 +672,6 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int int internal_file_len; phar_entry_data *idata; phar_archive_data *pphar; - uint32_t host_len; if ((resource = phar_parse_url(wrapper, url, "rb", options)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "phar error: unlink failed"); @@ -694,7 +691,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int return 0; } - host_len = ZSTR_LEN(resource->host); + size_t host_len = ZSTR_LEN(resource->host); phar_request_initialize(); pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); @@ -747,7 +744,6 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from char *error; phar_archive_data *phar, *pfrom, *pto; phar_entry_info *entry; - uint32_t host_len; int is_dir = 0; int is_modified = 0; @@ -823,7 +819,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from return 0; } - host_len = ZSTR_LEN(resource_from->host); + size_t host_len = ZSTR_LEN(resource_from->host); if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), host_len, NULL, 0, &error)) { php_url_free(resource_from); @@ -893,8 +889,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from Bucket *b; zend_string *str_key; zend_string *new_str_key; - uint32_t from_len = ZSTR_LEN(resource_from->path) - 1; - uint32_t to_len = ZSTR_LEN(resource_to->path) - 1; + size_t from_len = ZSTR_LEN(resource_from->path) - 1; + size_t to_len = ZSTR_LEN(resource_to->path) - 1; ZEND_HASH_MAP_FOREACH_BUCKET(&phar->manifest, b) { str_key = b->key; diff --git a/ext/phar/stream.h b/ext/phar/stream.h index 732da3a0b3f2c..ce75b70dcba00 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -18,6 +18,7 @@ */ BEGIN_EXTERN_C() +#include "ext/standard/url.h" php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); void phar_entry_remove(phar_entry_data *idata, char **error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 0b1de03c33f7b..44a8e127e233d 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -18,6 +18,7 @@ */ #include "phar_internal.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ static uint32_t phar_tar_number(const char *buf, size_t len) /* {{{ */ { @@ -62,10 +63,10 @@ static uint32_t phar_tar_number(const char *buf, size_t len) /* {{{ */ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -static int phar_tar_octal(char *buf, uint32_t val, int len) /* {{{ */ +static zend_result phar_tar_octal(char *buf, uint32_t val, size_t len) /* {{{ */ { char *p = buf; - int s = len; + size_t s = len; p += len; /* Start at the end and work backwards. */ while (s-- > 0) { @@ -73,12 +74,14 @@ static int phar_tar_octal(char *buf, uint32_t val, int len) /* {{{ */ val >>= 3; } - if (val == 0) + if (val == 0) { return SUCCESS; + } /* If it overflowed, fill field with max value. */ - while (len-- > 0) + while (len-- > 0) { *p++ = '7'; + } return FAILURE; } @@ -97,37 +100,37 @@ static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ } /* }}} */ -int phar_is_tar(char *buf, char *fname) /* {{{ */ +bool phar_is_tar(char *buf, char *fname) /* {{{ */ { tar_header *header = (tar_header *) buf; uint32_t checksum = phar_tar_number(header->checksum, sizeof(header->checksum)); - uint32_t ret; + bool is_tar; char save[sizeof(header->checksum)], *bname; /* assume that the first filename in a tar won't begin with checksum, sizeof(header->checksum)); memset(header->checksum, ' ', sizeof(header->checksum)); - ret = (checksum == phar_tar_checksum(buf, 512)); + is_tar = (checksum == phar_tar_checksum(buf, 512)); memcpy(header->checksum, save, sizeof(header->checksum)); if ((bname = strrchr(fname, PHP_DIR_SEPARATOR))) { fname = bname; } - if (!ret && (bname = strstr(fname, ".tar")) && (bname[4] == '\0' || bname[4] == '.')) { + if (!is_tar && (bname = strstr(fname, ".tar")) && (bname[4] == '\0' || bname[4] == '.')) { /* probably a corrupted tar - so we will pretend it is one */ - return 1; + return true; } - return ret; + return is_tar; } /* }}} */ -int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; - int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -157,7 +160,7 @@ int phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t a } /* }}} */ -static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ +static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ { char *metadata; size_t save = php_stream_tell(fp), read; @@ -199,7 +202,7 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* } /* }}} */ -int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error) /* {{{ */ +zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char buf[512], *actual_alias = NULL, *p; phar_entry_info entry = {0}; @@ -699,8 +702,8 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia struct _phar_pass_tar_info { php_stream *old; php_stream *new; - int free_fp; - int free_ufp; + bool free_fp; + bool free_ufp; char **error; }; @@ -863,7 +866,7 @@ static int phar_tar_writeheaders(zval *zv, void *argument) /* {{{ */ } /* }}} */ -int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ +static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ { /* Copy the metadata from tracker to the new entry being written out to temporary files */ const zend_string *serialized_str; diff --git a/ext/phar/tests/create_path_error.phpt b/ext/phar/tests/create_path_error.phpt index b0b15612222b1..fea390e477cb8 100644 --- a/ext/phar/tests/create_path_error.phpt +++ b/ext/phar/tests/create_path_error.phpt @@ -65,10 +65,10 @@ foreach($checks as $check) --EXPECTF-- string(5) "query" string(5) "query" -1:Error: file_put_contents(phar://%s//): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -2:Error: file_put_contents(phar://%s/.): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -3:Error: file_put_contents(phar://%s/../): Failed to open stream: phar error: file "" in phar "%s" cannot be empty -4:Error: file_put_contents(phar://%s/a/..): Failed to open stream: phar error: file "" in phar "%s" cannot be empty +1:Error: file_put_contents(phar://%s//): Failed to open stream: phar error: file "" in phar "%s" must not be empty +2:Error: file_put_contents(phar://%s/.): Failed to open stream: phar error: file "" in phar "%s" must not be empty +3:Error: file_put_contents(phar://%s/../): Failed to open stream: phar error: file "" in phar "%s" must not be empty +4:Error: file_put_contents(phar://%s/a/..): Failed to open stream: phar error: file "" in phar "%s" must not be empty 5: 6: 7: diff --git a/ext/phar/tests/phar_oo_011.phpt b/ext/phar/tests/phar_oo_011.phpt index 85c7575bcc085..98b4c34bd1539 100644 --- a/ext/phar/tests/phar_oo_011.phpt +++ b/ext/phar/tests/phar_oo_011.phpt @@ -13,10 +13,22 @@ $pharconfig = 0; require_once 'files/phar_oo_test.inc'; $phar = new Phar($fname); -$phar->setInfoClass('SplFileObject'); $phar['hi/f.php'] = 'hi'; var_dump(isset($phar['hi'])); +var_dump($phar['hi']); +var_dump(isset($phar['hi/f.php'])); +echo $phar['hi/f.php']; +echo "\n"; + +$phar->setInfoClass('SplFileObject'); +$phar['hi/f.php'] = 'hi'; +var_dump(isset($phar['hi'])); +try { + var_dump($phar['hi']); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} var_dump(isset($phar['hi/f.php'])); echo $phar['hi/f.php']; echo "\n"; @@ -27,7 +39,17 @@ echo "\n"; unlink(__DIR__ . '/files/phar_oo_011.phar.php'); __halt_compiler(); ?> ---EXPECT-- +--EXPECTF-- +bool(true) +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%s/phar_oo_011.phar.php/hi" + ["fileName":"SplFileInfo":private]=> + string(2) "hi" +} bool(true) +phar://%s/phar_oo_011.phar.php/hi/f.php +bool(false) +LogicException: Cannot use SplFileObject with directories bool(true) hi diff --git a/ext/phar/util.c b/ext/phar/util.c index aed95e635dd8c..e49e15aee9cc2 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -19,7 +19,10 @@ */ #include "phar_internal.h" +#include "php_phar.h" +#include "ext/hash/php_hash.h" /* Needed for PHP_HASH_API in ext/hash/php_hash_sha.h */ #include "ext/hash/php_hash_sha.h" +#include "ext/standard/md5.h" #ifdef PHAR_HAVE_OPENSSL /* OpenSSL includes */ @@ -34,7 +37,7 @@ #include #include #else -static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type); +static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); #endif /* for links to relative location, prepend cwd of the entry */ @@ -82,6 +85,14 @@ phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */ } /* }}} */ +static php_stream *phar_get_entrypufp(const phar_entry_info *entry) +{ + if (!entry->is_persistent) { + return entry->phar->ufp; + } + return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp; +} + /* retrieve a phar_entry_info's current file pointer for reading contents */ php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */ { @@ -113,6 +124,19 @@ php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */ } /* }}} */ +static zend_off_t phar_get_fp_offset(const phar_entry_info *entry) +{ + if (!entry->is_persistent) { + return entry->offset; + } + if (PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) { + if (!PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) { + PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset; + } + } + return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset; +} + int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */ { php_stream *fp = phar_get_efp(entry, follow_links); @@ -163,7 +187,7 @@ int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_of /* }}} */ /* mount an absolute path or uri to a path internal to the phar archive */ -int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ +zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ { phar_entry_info entry = {0}; php_stream_statbuf ssb; @@ -340,6 +364,105 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data } /* }}} */ +static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ +{ + if (entry->fp_type == PHAR_MOD) { + /* already newly created, truncate */ + php_stream_truncate_set_size(entry->fp, 0); + + entry->old_flags = entry->flags; + entry->is_modified = 1; + phar->is_modified = 1; + /* reset file size */ + entry->uncompressed_filesize = 0; + entry->compressed_filesize = 0; + entry->crc32 = 0; + entry->flags = PHAR_ENT_PERM_DEF_FILE; + entry->fp_type = PHAR_MOD; + entry->offset = 0; + return SUCCESS; + } + + if (error) { + *error = NULL; + } + + /* open a new temp file for writing */ + if (entry->link) { + efree(entry->link); + entry->link = NULL; + entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); + } + + entry->fp = php_stream_fopen_tmpfile(); + + if (!entry->fp) { + if (error) { + spprintf(error, 0, "phar error: unable to create temporary file"); + } + return FAILURE; + } + + entry->old_flags = entry->flags; + entry->is_modified = 1; + phar->is_modified = 1; + /* reset file size */ + entry->uncompressed_filesize = 0; + entry->compressed_filesize = 0; + entry->crc32 = 0; + entry->flags = PHAR_ENT_PERM_DEF_FILE; + entry->fp_type = PHAR_MOD; + entry->offset = 0; + return SUCCESS; +} +/* }}} */ + +static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ +{ + php_stream *fp; + phar_entry_info *link; + + if (FAILURE == phar_open_entry_fp(entry, error, 1)) { + return FAILURE; + } + + if (entry->fp_type == PHAR_MOD) { + return SUCCESS; + } + + fp = php_stream_fopen_tmpfile(); + if (fp == NULL) { + spprintf(error, 0, "phar error: unable to create temporary file"); + return FAILURE; + } + phar_seek_efp(entry, 0, SEEK_SET, 0, 1); + link = phar_get_link_source(entry); + + if (!link) { + link = entry; + } + + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { + if (error) { + spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname); + } + return FAILURE; + } + + if (entry->link) { + efree(entry->link); + entry->link = NULL; + entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); + } + + entry->offset = 0; + entry->fp = fp; + entry->fp_type = PHAR_MOD; + entry->is_modified = 1; + return SUCCESS; +} +/* }}} */ + /** * Retrieve a copy of the file information on a single file within a phar, or null. * This also transfers the open file pointer, if any, to the entry. @@ -348,14 +471,14 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data * appended, truncated, or read. For read, if the entry is marked unmodified, it is * assumed that the file pointer, if present, is opened for reading */ -int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ +zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ { phar_archive_data *phar; phar_entry_info *entry; - int for_write = mode[0] != 'r' || mode[1] == '+'; - int for_append = mode[0] == 'a'; - int for_create = mode[0] != 'r'; - int for_trunc = mode[0] == 'w'; + bool for_write = mode[0] != 'r' || mode[1] == '+'; + bool for_append = mode[0] == 'a'; + bool for_create = mode[0] != 'r'; + bool for_trunc = mode[0] == 'w'; if (!ret) { return FAILURE; @@ -380,7 +503,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, ch if (!path_len) { if (error) { - spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" cannot be empty", fname); + spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", fname); } return FAILURE; } @@ -616,8 +739,18 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch } /* }}} */ +static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) +{ + if (!phar->is_persistent) { + phar->fp = fp; + return; + } + + PHAR_G(cached_fp)[phar->phar_pos].fp = fp; +} + /* initialize a phar_archive_data's read-only fp for existing phar data */ -int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ +zend_result phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ { if (phar_get_pharfp(phar)) { return SUCCESS; @@ -638,7 +771,7 @@ int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ /* }}} */ /* copy file data from an existing to a new phar_entry_info that is not in the manifest */ -int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ +zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ { phar_entry_info *link; @@ -680,9 +813,33 @@ int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **er } /* }}} */ +static void phar_set_entrypufp(const phar_entry_info *entry, php_stream *fp) +{ + if (!entry->phar->is_persistent) { + entry->phar->ufp = fp; + return; + } + + PHAR_G(cached_fp)[entry->phar->phar_pos].ufp = fp; +} + +static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zend_off_t offset) +{ + phar_entry_fp_info *data; + + if (!entry->is_persistent) { + entry->fp_type = type; + entry->offset = offset; + return; + } + data = &(PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos]); + data->fp_type = type; + data->offset = offset; +} + /* open and decompress a compressed phar entry */ -int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ +zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ { php_stream_filter *filter; phar_archive_data *phar = entry->phar; @@ -798,105 +955,6 @@ int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) / } /* }}} */ -int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ -{ - if (entry->fp_type == PHAR_MOD) { - /* already newly created, truncate */ - php_stream_truncate_set_size(entry->fp, 0); - - entry->old_flags = entry->flags; - entry->is_modified = 1; - phar->is_modified = 1; - /* reset file size */ - entry->uncompressed_filesize = 0; - entry->compressed_filesize = 0; - entry->crc32 = 0; - entry->flags = PHAR_ENT_PERM_DEF_FILE; - entry->fp_type = PHAR_MOD; - entry->offset = 0; - return SUCCESS; - } - - if (error) { - *error = NULL; - } - - /* open a new temp file for writing */ - if (entry->link) { - efree(entry->link); - entry->link = NULL; - entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); - } - - entry->fp = php_stream_fopen_tmpfile(); - - if (!entry->fp) { - if (error) { - spprintf(error, 0, "phar error: unable to create temporary file"); - } - return FAILURE; - } - - entry->old_flags = entry->flags; - entry->is_modified = 1; - phar->is_modified = 1; - /* reset file size */ - entry->uncompressed_filesize = 0; - entry->compressed_filesize = 0; - entry->crc32 = 0; - entry->flags = PHAR_ENT_PERM_DEF_FILE; - entry->fp_type = PHAR_MOD; - entry->offset = 0; - return SUCCESS; -} -/* }}} */ - -int phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ -{ - php_stream *fp; - phar_entry_info *link; - - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { - return FAILURE; - } - - if (entry->fp_type == PHAR_MOD) { - return SUCCESS; - } - - fp = php_stream_fopen_tmpfile(); - if (fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return FAILURE; - } - phar_seek_efp(entry, 0, SEEK_SET, 0, 1); - link = phar_get_link_source(entry); - - if (!link) { - link = entry; - } - - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { - if (error) { - spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname); - } - return FAILURE; - } - - if (entry->link) { - efree(entry->link); - entry->link = NULL; - entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); - } - - entry->offset = 0; - entry->fp = fp; - entry->fp_type = PHAR_MOD; - entry->is_modified = 1; - return SUCCESS; -} -/* }}} */ - /** * helper function to open an internal file's fp just-in-time */ @@ -917,7 +975,7 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, } /* }}} */ -PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ { +PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ { phar_archive_data *fd_ptr; if (HT_IS_INITIALIZED(&PHAR_G(phar_alias_map)) && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { @@ -929,7 +987,7 @@ PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filena } /* }}} */ -int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ +zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ { if (phar->refcount || phar->is_persistent) { return FAILURE; @@ -952,7 +1010,7 @@ int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* { * Looks up a phar archive in the filename map, connecting it to the alias * (if any) or returns null */ -int phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ { phar_archive_data *fd, *fd_ptr; char *my_realpath, *save; @@ -1382,7 +1440,7 @@ static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* }}} */ #ifndef PHAR_HAVE_OPENSSL -static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type) /* {{{ */ +static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ { zend_fcall_info fci; zend_fcall_info_cache fcc; @@ -1482,7 +1540,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t /* }}} */ #endif /* #ifndef PHAR_HAVE_OPENSSL */ -int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ { size_t read_size, len; zend_off_t read_len; @@ -1796,7 +1854,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, } /* }}} */ -int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ +zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ { unsigned char buf[1024]; size_t sig_len; @@ -2079,7 +2137,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ } /* }}} */ -int phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ +zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ { zval zv, *pzv; phar_archive_data *newpphar; diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 9faf6054aff06..70cdfc9cc1b50 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -17,6 +17,8 @@ */ #include "phar_internal.h" +#include "ext/standard/crc32.h" +#include "ext/standard/php_string.h" /* For php_stristr() */ #define PHAR_GET_16(var) ((uint16_t)((((uint16_t)var[0]) & 0xff) | \ (((uint16_t)var[1]) & 0xff) << 8)) diff --git a/ext/posix/config.m4 b/ext/posix/config.m4 index ac70068bac8f6..b7a6e4277251e 100644 --- a/ext/posix/config.m4 +++ b/ext/posix/config.m4 @@ -43,7 +43,8 @@ if test "$PHP_POSIX" = "yes"; then dnl Skip pathconf and fpathconf check on musl libc due to limited implementation dnl (first argument is not validated and has different error). - AS_IF([command -v ldd >/dev/null && ldd --version 2>&1 | grep -q "^musl"],[], + AS_IF([command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1], + [], [AC_CHECK_FUNCS([pathconf fpathconf])]) AC_CACHE_CHECK([for working ttyname_r() implementation], diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 6711492e3d2a5..fc4928d5d2cf5 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -746,7 +746,7 @@ PHP_FUNCTION(posix_eaccess) path = expand_filepath(filename, NULL); if (!path) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1285,7 +1285,7 @@ PHP_FUNCTION(posix_pathconf) ZEND_PARSE_PARAMETERS_END(); if (path_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } else if (php_check_open_basedir(path)) { php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path); diff --git a/ext/posix/tests/posix_eaccess.phpt b/ext/posix/tests/posix_eaccess.phpt index ab47a1a0e8e36..4211e6ef13e72 100644 --- a/ext/posix/tests/posix_eaccess.phpt +++ b/ext/posix/tests/posix_eaccess.phpt @@ -17,4 +17,4 @@ try { ?> --EXPECT-- -posix_eaccess(): Argument #1 ($filename) cannot be empty +posix_eaccess(): Argument #1 ($filename) must not be empty diff --git a/ext/posix/tests/posix_pathconf.phpt b/ext/posix/tests/posix_pathconf.phpt index ffbec521f92c0..ba451c62df97b 100644 --- a/ext/posix/tests/posix_pathconf.phpt +++ b/ext/posix/tests/posix_pathconf.phpt @@ -18,7 +18,7 @@ var_dump(posix_errno() != 0); var_dump(posix_pathconf(sys_get_temp_dir(), POSIX_PC_PATH_MAX)); ?> --EXPECTF-- -posix_pathconf(): Argument #1 ($path) cannot be empty +posix_pathconf(): Argument #1 ($path) must not be empty bool(false) bool(true) int(%d) diff --git a/ext/random/config.m4 b/ext/random/config.m4 index 5c4c2b8bda3ae..ff43b856acf00 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -12,6 +12,11 @@ AC_CHECK_HEADERS([CommonCrypto/CommonRandom.h],,, [dnl #include ]) +dnl +dnl Mostly for non Linux systems +dnl +AC_CHECK_FUNCS([getrandom]) + dnl dnl Setup extension dnl diff --git a/ext/random/csprng.c b/ext/random/csprng.c index 05fc912317e6a..8b38985c6ac67 100644 --- a/ext/random/csprng.c +++ b/ext/random/csprng.c @@ -48,7 +48,7 @@ #ifdef HAVE_SYS_PARAM_H # include # if (defined(__FreeBSD__) && __FreeBSD_version > 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ - defined(__sun) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) + (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) # include # endif #endif @@ -100,7 +100,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_ #else size_t read_bytes = 0; # if (defined(__linux__) && defined(SYS_getrandom)) || (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || (defined(__DragonFly__) && __DragonFly_version >= 500700) || \ - defined(__sun) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) + (defined(__sun) && defined(HAVE_GETRANDOM)) || (defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000) || defined(__midipix__) /* Linux getrandom(2) syscall or FreeBSD/DragonFlyBSD/NetBSD getrandom(2) function * Being a syscall, implemented in the kernel, getrandom offers higher quality output * compared to the arc4random api albeit a fallback to /dev/urandom is considered. diff --git a/ext/random/random_arginfo.h b/ext/random/random_arginfo.h index fcb96380c6f0e..7f684271f7bab 100644 --- a/ext/random/random_arginfo.h +++ b/ext/random/random_arginfo.h @@ -267,8 +267,7 @@ static zend_class_entry *register_class_Random_Engine_Mt19937(zend_class_entry * zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Mt19937", class_Random_Engine_Mt19937_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -279,8 +278,7 @@ static zend_class_entry *register_class_Random_Engine_PcgOneseq128XslRr64(zend_c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "PcgOneseq128XslRr64", class_Random_Engine_PcgOneseq128XslRr64_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -291,8 +289,7 @@ static zend_class_entry *register_class_Random_Engine_Xoshiro256StarStar(zend_cl zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Xoshiro256StarStar", class_Random_Engine_Xoshiro256StarStar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zend_class_implements(class_entry, 1, class_entry_Random_Engine); return class_entry; @@ -303,8 +300,7 @@ static zend_class_entry *register_class_Random_Engine_Secure(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random\\Engine", "Secure", class_Random_Engine_Secure_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Random_CryptoSafeEngine); return class_entry; @@ -336,8 +332,7 @@ static zend_class_entry *register_class_Random_Randomizer(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "Randomizer", class_Random_Randomizer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); zval property_engine_default_value; ZVAL_UNDEF(&property_engine_default_value); @@ -369,8 +364,7 @@ static zend_class_entry *register_class_Random_RandomError(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "RandomError", class_Random_RandomError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -380,8 +374,7 @@ static zend_class_entry *register_class_Random_BrokenRandomEngineError(zend_clas zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "BrokenRandomEngineError", class_Random_BrokenRandomEngineError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Random_RandomError); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Random_RandomError, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -391,8 +384,7 @@ static zend_class_entry *register_class_Random_RandomException(zend_class_entry zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Random", "RandomException", class_Random_RandomException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 1109b497c131d..379641d5b8d78 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -434,7 +434,7 @@ PHP_METHOD(Random_Randomizer, getBytesFromString) const size_t max_offset = source_length - 1; if (source_length < 1) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt b/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt index 7280949d647e8..29c845353630c 100644 --- a/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytesFromString_error.phpt @@ -24,5 +24,5 @@ try { ?> --EXPECTF-- -Random\Randomizer::getBytesFromString(): Argument #1 ($string) cannot be empty +Random\Randomizer::getBytesFromString(): Argument #1 ($string) must not be empty Random\Randomizer::getBytesFromString(): Argument #2 ($length) must be greater than 0 diff --git a/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt b/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt index 15526327b095c..cbd0495676c1e 100644 --- a/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt +++ b/ext/random/tests/03_randomizer/methods/pickArrayKeys_error.phpt @@ -43,7 +43,7 @@ try { ?> --EXPECTF-- Random\Randomizer::pickArrayKeys(): Argument #1 ($array) must be of type array, string given -Random\Randomizer::pickArrayKeys(): Argument #1 ($array) cannot be empty +Random\Randomizer::pickArrayKeys(): Argument #1 ($array) must not be empty Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 0956bbc1acf70..531db004b3ba6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -19,7 +19,11 @@ */ #include "zend_compile.h" +#include "zend_execute.h" +#include "zend_lazy_objects.h" +#include "zend_object_handlers.h" #include "zend_type_info.h" +#include "zend_types.h" #ifdef HAVE_CONFIG_H #include #endif @@ -474,7 +478,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char smart_str_append_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(Z_OBJ_P(obj)); + HashTable *properties = zend_get_properties_no_lazy_init(Z_OBJ_P(obj)); zend_string *prop_name; smart_str prop_str = {0}; @@ -940,6 +944,17 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha smart_str_appends(str, "protected "); break; } + switch (prop->flags & ZEND_ACC_PPP_SET_MASK) { + case ZEND_ACC_PRIVATE_SET: + smart_str_appends(str, "private(set) "); + break; + case ZEND_ACC_PROTECTED_SET: + smart_str_appends(str, "protected(set) "); + break; + case ZEND_ACC_PUBLIC_SET: + ZEND_UNREACHABLE(); + break; + } if (prop->flags & ZEND_ACC_STATIC) { smart_str_appends(str, "static "); } @@ -5176,6 +5191,201 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) } /* }}} */ +void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, + int strategy, bool is_reset) +{ + reflection_object *intern; + zend_object *obj; + zend_class_entry *ce; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zend_long options = 0; + + ZEND_ASSERT(strategy == ZEND_LAZY_OBJECT_STRATEGY_GHOST + || strategy == ZEND_LAZY_OBJECT_STRATEGY_PROXY); + + GET_REFLECTION_OBJECT_PTR(ce); + + if (is_reset) { + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJ_OF_CLASS(obj, ce) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(options) + ZEND_PARSE_PARAMETERS_END(); + } else { + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_FUNC(fci, fcc) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(options) + ZEND_PARSE_PARAMETERS_END(); + obj = NULL; + } + + if (options & ~ZEND_LAZY_OBJECT_USER_MASK) { + uint32_t arg_num = 2 + is_reset; + zend_argument_error(reflection_exception_ptr, arg_num, + "contains invalid flags"); + RETURN_THROWS(); + } + + if (!is_reset && (options & ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR)) { + zend_argument_error(reflection_exception_ptr, 2, + "does not accept ReflectionClass::SKIP_DESTRUCTOR"); + RETURN_THROWS(); + } + + if (is_reset) { + if (zend_object_is_lazy(obj) && !zend_lazy_object_initialized(obj)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, "Object is already lazy"); + RETURN_THROWS(); + } + } else { + obj = NULL; + } + + if (!fcc.function_handler) { + /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal + * with it ourselves. It is important that it is not refetched on every call, + * because calls may occur from different scopes. */ + zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); + } + + obj = zend_object_make_lazy(obj, ce, &fci.function_name, &fcc, + strategy | options); + + if (!obj) { + RETURN_THROWS(); + } + + if (!is_reset) { + RETURN_OBJ(obj); + } +} + +/* {{{ Instantiates a lazy instance, using the ghost strategy */ +PHP_METHOD(ReflectionClass, newLazyGhost) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_GHOST, /* is_reset */ false); +} +/* }}} */ + +/* {{{ Instantiates a lazy instance, using the proxy strategy */ +PHP_METHOD(ReflectionClass, newLazyProxy) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /* is_reset */ false); +} +/* }}} */ + +/* {{{ Reset an object and make it lazy, using the ghost strategy */ +PHP_METHOD(ReflectionClass, resetAsLazyGhost) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_GHOST, /* is_reset */ true); +} +/* }}} */ + +/* {{{ Reset an object and make it lazy, using the proxy strategy */ +PHP_METHOD(ReflectionClass, resetAsLazyProxy) +{ + reflection_class_new_lazy(INTERNAL_FUNCTION_PARAM_PASSTHRU, + ZEND_LAZY_OBJECT_STRATEGY_PROXY, /* is_reset */ true); +} +/* }}} */ + +/* {{{ Returns whether object lazy and uninitialized */ +ZEND_METHOD(ReflectionClass, isUninitializedLazyObject) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL(zend_object_is_lazy(object) && !zend_lazy_object_initialized(object)); +} +/* }}} */ + +/* {{{ Trigger object initialization */ +ZEND_METHOD(ReflectionClass, initializeLazyObject) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + zend_lazy_object_init(object); + } + + if (zend_lazy_object_initialized(object)) { + RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); + } else { + RETURN_THROWS(); + } +} +/* }}} */ + +/* {{{ Mark object as initialized without calling the initializer */ +ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + zend_lazy_object_mark_as_initialized(object); + } + + if (zend_lazy_object_initialized(object)) { + RETURN_OBJ_COPY(zend_lazy_object_get_instance(object)); + } else { + RETURN_THROWS(); + } +} +/* }}} */ + +/* {{{ Get lazy object initializer */ +ZEND_METHOD(ReflectionClass, getLazyInitializer) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ce); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(object, ce) + ZEND_PARSE_PARAMETERS_END(); + + if (!zend_object_is_lazy(object) + || zend_lazy_object_initialized(object)) { + RETURN_NULL(); + } + + RETURN_ZVAL(zend_lazy_object_get_initializer_zv(object), 1, 0); +} +/* }}} */ + /* {{{ Returns an array of interfaces this class implements */ ZEND_METHOD(ReflectionClass, getInterfaces) { @@ -5679,6 +5889,16 @@ ZEND_METHOD(ReflectionProperty, isProtected) } /* }}} */ +ZEND_METHOD(ReflectionProperty, isPrivateSet) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE_SET); +} + +ZEND_METHOD(ReflectionProperty, isProtectedSet) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED_SET); +} + /* {{{ Returns whether this property is static */ ZEND_METHOD(ReflectionProperty, isStatic) { @@ -5727,7 +5947,7 @@ ZEND_METHOD(ReflectionProperty, getModifiers) { reflection_object *intern; property_reference *ref; - uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL; + uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL; if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); @@ -5869,6 +6089,16 @@ ZEND_METHOD(ReflectionProperty, getRawValue) } } +static void reflection_property_set_raw_value(property_reference *ref, reflection_object *intern, zend_object *object, zval *value) +{ + if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); + } else { + zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); + zend_call_known_instance_method_with_1_params(func, object, NULL, value); + } +} + ZEND_METHOD(ReflectionProperty, setRawValue) { reflection_object *intern; @@ -5887,11 +6117,133 @@ ZEND_METHOD(ReflectionProperty, setRawValue) RETURN_THROWS(); } - if (!ref->prop || !ref->prop->hooks || !ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_update_property_ex(intern->ce, Z_OBJ_P(object), ref->unmangled_name, value); - } else { - zend_function *func = zend_get_property_hook_trampoline(ref->prop, ZEND_PROPERTY_HOOK_SET, ref->unmangled_name); - zend_call_known_instance_method_with_1_params(func, Z_OBJ_P(object), NULL, value); + reflection_property_set_raw_value(ref, intern, Z_OBJ_P(object), value); +} + +static zend_result reflection_property_check_lazy_compatible(reflection_object *intern, + property_reference *ref, zend_object *object, const char *method) +{ + if (!ref->prop) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use %s on dynamic property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; + } + + if (ref->prop->flags & ZEND_ACC_STATIC) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use %s on static property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; + } + + if (ref->prop->flags & ZEND_ACC_VIRTUAL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use %s on virtual property %s::$%s", + method, ZSTR_VAL(intern->ce->name), + ZSTR_VAL(ref->unmangled_name)); + return FAILURE; + } + + if (UNEXPECTED(object->handlers->write_property != zend_std_write_property)) { + if (!zend_class_can_be_lazy(object->ce)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Can not use %s on internal class %s", + method, ZSTR_VAL(intern->ce->name)); + return FAILURE; + } + } + + ZEND_ASSERT(IS_VALID_PROPERTY_OFFSET(ref->prop->offset)); + + return SUCCESS; +} + +/* {{{ Set property value withtout triggering initializer while skipping hooks if any */ +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) +{ + reflection_object *intern; + property_reference *ref; + zend_object *object; + zval *value; + + GET_REFLECTION_OBJECT_PTR(ref); + + ZEND_PARSE_PARAMETERS_START(2, 2) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + Z_PARAM_ZVAL(value) + } ZEND_PARSE_PARAMETERS_END(); + + if (reflection_property_check_lazy_compatible(intern, ref, object, + "setRawValueWithoutLazyInitialization") == FAILURE) { + RETURN_THROWS(); + } + + zval *var_ptr = OBJ_PROP(object, ref->prop->offset); + bool prop_was_lazy = Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY; + + /* Do not trigger initialization */ + Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_LAZY; + + reflection_property_set_raw_value(ref, intern, object, value); + + /* Mark property as lazy again if an exception prevented update */ + if (EG(exception) && prop_was_lazy && Z_TYPE_P(var_ptr) == IS_UNDEF + && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + Z_PROP_FLAG_P(var_ptr) |= IS_PROP_LAZY; + } + + /* Object becomes non-lazy if this was the last lazy prop */ + if (prop_was_lazy && !(Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY) + && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + if (zend_lazy_object_decr_lazy_props(object)) { + zend_lazy_object_realize(object); + } + } +} + +/* {{{ Mark property as non-lazy, and initialize to default value */ +ZEND_METHOD(ReflectionProperty, skipLazyInitialization) +{ + reflection_object *intern; + property_reference *ref; + zend_object *object; + + GET_REFLECTION_OBJECT_PTR(ref); + + ZEND_PARSE_PARAMETERS_START(1, 1) { + Z_PARAM_OBJ_OF_CLASS(object, intern->ce) + } ZEND_PARSE_PARAMETERS_END(); + + if (reflection_property_check_lazy_compatible(intern, ref, object, + "skipLazyInitialization") == FAILURE) { + RETURN_THROWS(); + } + + bool prop_was_lazy = (Z_PROP_FLAG_P(OBJ_PROP(object, ref->prop->offset)) & IS_PROP_LAZY); + + zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; + zval *dst = OBJ_PROP(object, ref->prop->offset); + + if (!(Z_PROP_FLAG_P(dst) & IS_PROP_LAZY)) { + /* skipLazyInitialization has no effect on non-lazy properties */ + return; + } + + ZEND_ASSERT(Z_TYPE_P(dst) == IS_UNDEF && "Lazy property should be UNDEF"); + + ZVAL_COPY_PROP(dst, src); + + /* Object becomes non-lazy if this was the last lazy prop */ + if (prop_was_lazy && zend_object_is_lazy(object) + && !zend_lazy_object_initialized(object)) { + if (zend_lazy_object_decr_lazy_props(object)) { + zend_lazy_object_realize(object); + } } } @@ -6041,7 +6393,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) } /* Get-only virtual property can never be written to. */ - if ((prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); reflection_type_factory(never_type, return_value, 0); return; diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index 6420b04520aa6..d676597fd0bed 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -47,6 +47,7 @@ extern PHPAPI zend_class_entry *reflection_enum_ptr; extern PHPAPI zend_class_entry *reflection_enum_unit_case_ptr; extern PHPAPI zend_class_entry *reflection_enum_backed_case_ptr; extern PHPAPI zend_class_entry *reflection_fiber_ptr; +extern PHPAPI zend_class_entry *reflection_lazy_object_ptr; PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object); diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index d6d9c9d715f4a..366c13f3a1a1d 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -250,6 +250,12 @@ class ReflectionClass implements Reflector /** @cvalue ZEND_ACC_READONLY_CLASS */ public const int IS_READONLY = UNKNOWN; + /** @cvalue ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE */ + public const int SKIP_INITIALIZATION_ON_SERIALIZE = UNKNOWN; + + /** @cvalue ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR */ + public const int SKIP_DESTRUCTOR = UNKNOWN; + public string $name; private function __clone(): void {} @@ -370,6 +376,22 @@ public function newInstanceWithoutConstructor(): object {} /** @tentative-return-type */ public function newInstanceArgs(array $args = []): ?object {} + public function newLazyGhost(callable $initializer, int $options = 0): object {} + + public function newLazyProxy(callable $factory, int $options = 0): object {} + + public function resetAsLazyGhost(object $object, callable $factory, int $options = 0): void {} + + public function resetAsLazyProxy(object $object, callable $factory, int $options = 0): void {} + + public function initializeLazyObject(object $object): object {} + + public function isUninitializedLazyObject(object $object): bool {} + + public function markLazyObjectAsInitialized(object $object): object {} + + public function getLazyInitializer(object $object): ?callable {} + /** @tentative-return-type */ public function getParentClass(): ReflectionClass|false {} @@ -444,6 +466,10 @@ class ReflectionProperty implements Reflector public const int IS_PRIVATE = UNKNOWN; /** @cvalue ZEND_ACC_ABSTRACT */ public const int IS_ABSTRACT = UNKNOWN; + /** @cvalue ZEND_ACC_PROTECTED_SET */ + public const int IS_PROTECTED_SET = UNKNOWN; + /** @cvalue ZEND_ACC_PRIVATE_SET */ + public const int IS_PRIVATE_SET = UNKNOWN; public string $name; public string $class; @@ -468,6 +494,10 @@ public function getRawValue(object $object): mixed {} public function setRawValue(object $object, mixed $value): void {} + public function setRawValueWithoutLazyInitialization(object $object, mixed $value): void {} + + public function skipLazyInitialization(object $object): void {} + /** @tentative-return-type */ public function isInitialized(?object $object = null): bool {} @@ -480,6 +510,10 @@ public function isPrivate(): bool {} /** @tentative-return-type */ public function isProtected(): bool {} + public function isPrivateSet(): bool {} + + public function isProtectedSet(): bool {} + /** @tentative-return-type */ public function isStatic(): bool {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index a35bdd766ef7b..5d95b25582988 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d2a365f6f398bbcf3f2520c28d508ca63f08b5ff */ + * Stub hash: 09e21577c53d8b53e30aa30e3208d3807ecd8852 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -287,6 +287,38 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_newLazyGhost, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, initializer, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_newLazyProxy, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, factory, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_resetAsLazyGhost, 0, 2, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, factory, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionClass_resetAsLazyProxy arginfo_class_ReflectionClass_resetAsLazyGhost + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_initializeLazyObject, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_isUninitializedLazyObject, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionClass_markLazyObjectAsInitialized arginfo_class_ReflectionClass_initializeLazyObject + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_getLazyInitializer, 0, 1, IS_CALLABLE, 1) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_ReflectionClass_getParentClass, 0, 0, ReflectionClass, MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -361,6 +393,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_setRawV ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionProperty_setRawValueWithoutLazyInitialization arginfo_class_ReflectionProperty_setRawValue + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_skipLazyInitialization, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_isInitialized, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, object, IS_OBJECT, 1, "null") ZEND_END_ARG_INFO() @@ -371,6 +409,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_isProtected arginfo_class_ReflectionFunctionAbstract_inNamespace +#define arginfo_class_ReflectionProperty_isPrivateSet arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionProperty_isProtectedSet arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + #define arginfo_class_ReflectionProperty_isStatic arginfo_class_ReflectionFunctionAbstract_inNamespace #define arginfo_class_ReflectionProperty_isReadOnly arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType @@ -759,6 +801,14 @@ ZEND_METHOD(ReflectionClass, isInstance); ZEND_METHOD(ReflectionClass, newInstance); ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor); ZEND_METHOD(ReflectionClass, newInstanceArgs); +ZEND_METHOD(ReflectionClass, newLazyGhost); +ZEND_METHOD(ReflectionClass, newLazyProxy); +ZEND_METHOD(ReflectionClass, resetAsLazyGhost); +ZEND_METHOD(ReflectionClass, resetAsLazyProxy); +ZEND_METHOD(ReflectionClass, initializeLazyObject); +ZEND_METHOD(ReflectionClass, isUninitializedLazyObject); +ZEND_METHOD(ReflectionClass, markLazyObjectAsInitialized); +ZEND_METHOD(ReflectionClass, getLazyInitializer); ZEND_METHOD(ReflectionClass, getParentClass); ZEND_METHOD(ReflectionClass, isSubclassOf); ZEND_METHOD(ReflectionClass, getStaticProperties); @@ -781,10 +831,14 @@ ZEND_METHOD(ReflectionProperty, getValue); ZEND_METHOD(ReflectionProperty, setValue); ZEND_METHOD(ReflectionProperty, getRawValue); ZEND_METHOD(ReflectionProperty, setRawValue); +ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization); +ZEND_METHOD(ReflectionProperty, skipLazyInitialization); ZEND_METHOD(ReflectionProperty, isInitialized); ZEND_METHOD(ReflectionProperty, isPublic); ZEND_METHOD(ReflectionProperty, isPrivate); ZEND_METHOD(ReflectionProperty, isProtected); +ZEND_METHOD(ReflectionProperty, isPrivateSet); +ZEND_METHOD(ReflectionProperty, isProtectedSet); ZEND_METHOD(ReflectionProperty, isStatic); ZEND_METHOD(ReflectionProperty, isReadOnly); ZEND_METHOD(ReflectionProperty, isDefault); @@ -1038,6 +1092,14 @@ static const zend_function_entry class_ReflectionClass_methods[] = { ZEND_ME(ReflectionClass, newInstance, arginfo_class_ReflectionClass_newInstance, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, newInstanceWithoutConstructor, arginfo_class_ReflectionClass_newInstanceWithoutConstructor, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, newInstanceArgs, arginfo_class_ReflectionClass_newInstanceArgs, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, newLazyGhost, arginfo_class_ReflectionClass_newLazyGhost, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, newLazyProxy, arginfo_class_ReflectionClass_newLazyProxy, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, resetAsLazyGhost, arginfo_class_ReflectionClass_resetAsLazyGhost, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, resetAsLazyProxy, arginfo_class_ReflectionClass_resetAsLazyProxy, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, initializeLazyObject, arginfo_class_ReflectionClass_initializeLazyObject, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isUninitializedLazyObject, arginfo_class_ReflectionClass_isUninitializedLazyObject, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, markLazyObjectAsInitialized, arginfo_class_ReflectionClass_markLazyObjectAsInitialized, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getLazyInitializer, arginfo_class_ReflectionClass_getLazyInitializer, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getParentClass, arginfo_class_ReflectionClass_getParentClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, isSubclassOf, arginfo_class_ReflectionClass_isSubclassOf, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getStaticProperties, arginfo_class_ReflectionClass_getStaticProperties, ZEND_ACC_PUBLIC) @@ -1074,10 +1136,14 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, setValue, arginfo_class_ReflectionProperty_setValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getRawValue, arginfo_class_ReflectionProperty_getRawValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, setRawValue, arginfo_class_ReflectionProperty_setRawValue, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, setRawValueWithoutLazyInitialization, arginfo_class_ReflectionProperty_setRawValueWithoutLazyInitialization, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, skipLazyInitialization, arginfo_class_ReflectionProperty_skipLazyInitialization, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isInitialized, arginfo_class_ReflectionProperty_isInitialized, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isPublic, arginfo_class_ReflectionProperty_isPublic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isPrivate, arginfo_class_ReflectionProperty_isPrivate, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isProtected, arginfo_class_ReflectionProperty_isProtected, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isPrivateSet, arginfo_class_ReflectionProperty_isPrivateSet, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isProtectedSet, arginfo_class_ReflectionProperty_isProtectedSet, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isStatic, arginfo_class_ReflectionProperty_isStatic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isReadOnly, arginfo_class_ReflectionProperty_isReadOnly, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isDefault, arginfo_class_ReflectionProperty_isDefault, ZEND_ACC_PUBLIC) @@ -1269,7 +1335,7 @@ static zend_class_entry *register_class_ReflectionException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionException", class_ReflectionException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -1279,7 +1345,7 @@ static zend_class_entry *register_class_Reflection(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Reflection", class_Reflection_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } @@ -1300,8 +1366,7 @@ static zend_class_entry *register_class_ReflectionFunctionAbstract(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFunctionAbstract", class_ReflectionFunctionAbstract_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1318,7 +1383,7 @@ static zend_class_entry *register_class_ReflectionFunction(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFunction", class_ReflectionFunction_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionFunctionAbstract); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionFunctionAbstract, 0); zval const_IS_DEPRECATED_value; ZVAL_LONG(&const_IS_DEPRECATED_value, ZEND_ACC_DEPRECATED); @@ -1347,8 +1412,7 @@ static zend_class_entry *register_class_ReflectionGenerator(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionGenerator", class_ReflectionGenerator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1358,7 +1422,7 @@ static zend_class_entry *register_class_ReflectionMethod(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionMethod", class_ReflectionMethod_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionFunctionAbstract); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionFunctionAbstract, 0); zval const_IS_STATIC_value; ZVAL_LONG(&const_IS_STATIC_value, ZEND_ACC_STATIC); @@ -1410,8 +1474,7 @@ static zend_class_entry *register_class_ReflectionClass(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionClass", class_ReflectionClass_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_IMPLICIT_ABSTRACT_value; @@ -1438,6 +1501,18 @@ static zend_class_entry *register_class_ReflectionClass(zend_class_entry *class_ zend_declare_typed_class_constant(class_entry, const_IS_READONLY_name, &const_IS_READONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_IS_READONLY_name); + zval const_SKIP_INITIALIZATION_ON_SERIALIZE_value; + ZVAL_LONG(&const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); + zend_string *const_SKIP_INITIALIZATION_ON_SERIALIZE_name = zend_string_init_interned("SKIP_INITIALIZATION_ON_SERIALIZE", sizeof("SKIP_INITIALIZATION_ON_SERIALIZE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_SKIP_INITIALIZATION_ON_SERIALIZE_name, &const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_SKIP_INITIALIZATION_ON_SERIALIZE_name); + + zval const_SKIP_DESTRUCTOR_value; + ZVAL_LONG(&const_SKIP_DESTRUCTOR_value, ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR); + zend_string *const_SKIP_DESTRUCTOR_name = zend_string_init_interned("SKIP_DESTRUCTOR", sizeof("SKIP_DESTRUCTOR") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_SKIP_DESTRUCTOR_name, &const_SKIP_DESTRUCTOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_SKIP_DESTRUCTOR_name); + zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); @@ -1452,7 +1527,7 @@ static zend_class_entry *register_class_ReflectionObject(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionObject", class_ReflectionObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClass); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClass, 0); return class_entry; } @@ -1479,8 +1554,7 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionProperty", class_ReflectionProperty_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_STATIC_value; @@ -1519,6 +1593,18 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla zend_declare_typed_class_constant(class_entry, const_IS_ABSTRACT_name, &const_IS_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_IS_ABSTRACT_name); + zval const_IS_PROTECTED_SET_value; + ZVAL_LONG(&const_IS_PROTECTED_SET_value, ZEND_ACC_PROTECTED_SET); + zend_string *const_IS_PROTECTED_SET_name = zend_string_init_interned("IS_PROTECTED_SET", sizeof("IS_PROTECTED_SET") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_SET_name, &const_IS_PROTECTED_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IS_PROTECTED_SET_name); + + zval const_IS_PRIVATE_SET_value; + ZVAL_LONG(&const_IS_PRIVATE_SET_value, ZEND_ACC_PRIVATE_SET); + zend_string *const_IS_PRIVATE_SET_name = zend_string_init_interned("IS_PRIVATE_SET", sizeof("IS_PRIVATE_SET") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_SET_name, &const_IS_PRIVATE_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IS_PRIVATE_SET_name); + zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); @@ -1539,8 +1625,7 @@ static zend_class_entry *register_class_ReflectionClassConstant(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionClassConstant", class_ReflectionClassConstant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_PUBLIC_value; @@ -1587,8 +1672,7 @@ static zend_class_entry *register_class_ReflectionParameter(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionParameter", class_ReflectionParameter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1642,8 +1726,7 @@ static zend_class_entry *register_class_ReflectionType(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionType", class_ReflectionType_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Stringable); return class_entry; @@ -1654,7 +1737,7 @@ static zend_class_entry *register_class_ReflectionNamedType(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionNamedType", class_ReflectionNamedType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1664,7 +1747,7 @@ static zend_class_entry *register_class_ReflectionUnionType(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionUnionType", class_ReflectionUnionType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1674,7 +1757,7 @@ static zend_class_entry *register_class_ReflectionIntersectionType(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionIntersectionType", class_ReflectionIntersectionType_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionType); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, 0); return class_entry; } @@ -1684,8 +1767,7 @@ static zend_class_entry *register_class_ReflectionExtension(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionExtension", class_ReflectionExtension_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1702,8 +1784,7 @@ static zend_class_entry *register_class_ReflectionZendExtension(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionZendExtension", class_ReflectionZendExtension_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; @@ -1720,8 +1801,7 @@ static zend_class_entry *register_class_ReflectionReference(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionReference", class_ReflectionReference_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1731,8 +1811,7 @@ static zend_class_entry *register_class_ReflectionAttribute(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionAttribute", class_ReflectionAttribute_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval const_IS_INSTANCEOF_value; @@ -1755,7 +1834,7 @@ static zend_class_entry *register_class_ReflectionEnum(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnum", class_ReflectionEnum_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClass); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClass, 0); return class_entry; } @@ -1765,7 +1844,7 @@ static zend_class_entry *register_class_ReflectionEnumUnitCase(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnumUnitCase", class_ReflectionEnumUnitCase_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClassConstant); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionClassConstant, 0); return class_entry; } @@ -1775,7 +1854,7 @@ static zend_class_entry *register_class_ReflectionEnumBackedCase(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionEnumBackedCase", class_ReflectionEnumBackedCase_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionEnumUnitCase); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionEnumUnitCase, 0); return class_entry; } @@ -1785,8 +1864,7 @@ static zend_class_entry *register_class_ReflectionFiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionFiber", class_ReflectionFiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1796,8 +1874,7 @@ static zend_class_entry *register_class_ReflectionConstant(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionConstant", class_ReflectionConstant_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index 15059211ef01d..9b5c7db436b09 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -11,11 +11,13 @@ echo $rc; --EXPECT-- Class [ class ReflectionClass implements Stringable, Reflector ] { - - Constants [4] { + - Constants [6] { Constant [ public int IS_IMPLICIT_ABSTRACT ] { 16 } Constant [ public int IS_EXPLICIT_ABSTRACT ] { 64 } Constant [ public int IS_FINAL ] { 32 } Constant [ public int IS_READONLY ] { 65536 } + Constant [ public int SKIP_INITIALIZATION_ON_SERIALIZE ] { 8 } + Constant [ public int SKIP_DESTRUCTOR ] { 16 } } - Static properties [0] { @@ -28,7 +30,7 @@ Class [ class ReflectionClass implements Stringable, Refle Property [ public string $name ] } - - Methods [56] { + - Methods [64] { Method [ private method __clone ] { - Parameters [0] { @@ -330,6 +332,76 @@ Class [ class ReflectionClass implements Stringable, Refle - Tentative return [ ?object ] } + Method [ public method newLazyGhost ] { + + - Parameters [2] { + Parameter #0 [ callable $initializer ] + Parameter #1 [ int $options = 0 ] + } + - Return [ object ] + } + + Method [ public method newLazyProxy ] { + + - Parameters [2] { + Parameter #0 [ callable $factory ] + Parameter #1 [ int $options = 0 ] + } + - Return [ object ] + } + + Method [ public method resetAsLazyGhost ] { + + - Parameters [3] { + Parameter #0 [ object $object ] + Parameter #1 [ callable $factory ] + Parameter #2 [ int $options = 0 ] + } + - Return [ void ] + } + + Method [ public method resetAsLazyProxy ] { + + - Parameters [3] { + Parameter #0 [ object $object ] + Parameter #1 [ callable $factory ] + Parameter #2 [ int $options = 0 ] + } + - Return [ void ] + } + + Method [ public method initializeLazyObject ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ object ] + } + + Method [ public method isUninitializedLazyObject ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ bool ] + } + + Method [ public method markLazyObjectAsInitialized ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ object ] + } + + Method [ public method getLazyInitializer ] { + + - Parameters [1] { + Parameter #0 [ object $object ] + } + - Return [ ?callable ] + } + Method [ public method getParentClass ] { - Parameters [0] { diff --git a/ext/reflection/tests/ReflectionClass_toString_005.phpt b/ext/reflection/tests/ReflectionClass_toString_005.phpt index 4d4178828cc8e..a43cd96d8b7c8 100644 --- a/ext/reflection/tests/ReflectionClass_toString_005.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_005.phpt @@ -25,8 +25,8 @@ Class [ readonly class Foo ] { } - Properties [2] { - Property [ public readonly int $bar ] - Property [ public readonly int $baz ] + Property [ public protected(set) readonly int $bar ] + Property [ public protected(set) readonly int $baz ] } - Methods [0] { diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt index 21a2bc82d7697..f9c05d2f6e596 100644 --- a/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt +++ b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt @@ -31,7 +31,7 @@ Class [ final class Foo implements UnitEnum ] { } - Properties [1] { - Property [ public readonly string $name ] + Property [ public protected(set) readonly string $name ] } - Methods [0] { diff --git a/ext/reflection/tests/ReflectionEnum_toString.phpt b/ext/reflection/tests/ReflectionEnum_toString.phpt index 00965e7b783c0..91ef587a9a3a4 100644 --- a/ext/reflection/tests/ReflectionEnum_toString.phpt +++ b/ext/reflection/tests/ReflectionEnum_toString.phpt @@ -31,7 +31,7 @@ Class [ final class Foo implements UnitEnum ] { } - Properties [1] { - Property [ public readonly string $name ] + Property [ public protected(set) readonly string $name ] } - Methods [0] { diff --git a/ext/reflection/tests/asymmetric_visibility_flags.phpt b/ext/reflection/tests/asymmetric_visibility_flags.phpt new file mode 100644 index 0000000000000..e6b171d3e765a --- /dev/null +++ b/ext/reflection/tests/asymmetric_visibility_flags.phpt @@ -0,0 +1,34 @@ +--TEST-- +ReflectionProperty::is{Private,Protected}Set +--FILE-- +isPrivateSet()); + var_dump($reflectionProperty->isProtectedSet()); + var_dump(($reflectionProperty->getModifiers() & ReflectionProperty::IS_PRIVATE_SET) !== 0); + var_dump(($reflectionProperty->getModifiers() & ReflectionProperty::IS_PROTECTED_SET) !== 0); + echo $reflectionProperty; +} + +test('bar'); +test('baz'); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +Property [ public private(set) int $bar ] +bool(false) +bool(true) +bool(false) +bool(true) +Property [ public protected(set) int $baz ] diff --git a/ext/reflection/tests/asymmetric_visibility_write.phpt b/ext/reflection/tests/asymmetric_visibility_write.phpt new file mode 100644 index 0000000000000..6a582392fedb6 --- /dev/null +++ b/ext/reflection/tests/asymmetric_visibility_write.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionProperty::is{Private,Protected}Set +--FILE-- +setValue($foo, $i++); + var_dump($reflectionProperty->getValue($foo)); +} + +test('bar'); +test('baz'); + +?> +--EXPECT-- +int(0) +int(1) diff --git a/ext/reflection/tests/readonly_properties.phpt b/ext/reflection/tests/readonly_properties.phpt index 25b3adcca3637..dd1a1a06f2be7 100644 --- a/ext/reflection/tests/readonly_properties.phpt +++ b/ext/reflection/tests/readonly_properties.phpt @@ -25,4 +25,4 @@ bool(false) bool(false) bool(true) bool(true) -Property [ public readonly int $ro ] +Property [ public protected(set) readonly int $ro ] diff --git a/ext/session/config.m4 b/ext/session/config.m4 index 1171f912832a2..36cfdf10972ab 100644 --- a/ext/session/config.m4 +++ b/ext/session/config.m4 @@ -19,6 +19,7 @@ if test "$PHP_SESSION" != "no"; then [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + PHP_ADD_EXTENSION_DEP(session, date) dnl https://bugs.php.net/53141 PHP_ADD_EXTENSION_DEP(session, spl, true) diff --git a/ext/session/config.w32 b/ext/session/config.w32 index bd5065b599db0..825bc8b61d291 100644 --- a/ext/session/config.w32 +++ b/ext/session/config.w32 @@ -4,6 +4,7 @@ ARG_ENABLE("session", "session support", "yes"); if (PHP_SESSION == "yes") { EXTENSION("session", "mod_user_class.c session.c mod_files.c mod_mm.c mod_user.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_EXTENSION_DEP('session', 'date'); // https://bugs.php.net/53141 ADD_EXTENSION_DEP('session', 'spl', true); AC_DEFINE("HAVE_PHP_SESSION", 1, "Define to 1 if the PHP extension 'session' is available."); diff --git a/ext/session/session.c b/ext/session/session.c index aa9883ab1df33..3d762886dbb6d 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -789,6 +789,44 @@ static PHP_INI_MH(OnUpdateSidBits) /* {{{ */ } /* }}} */ +static PHP_INI_MH(OnUpdateSessionGcProbability) /* {{{ */ +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + + if (tmp < 0) { + php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); + return FAILURE; + } + + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = tmp; + + return SUCCESS; +} +/* }}} */ + +static PHP_INI_MH(OnUpdateSessionDivisor) /* {{{ */ +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + + if (tmp <= 0) { + php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); + return FAILURE; + } + + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = tmp; + + return SUCCESS; +} +/* }}} */ + static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */ { int tmp = ZEND_ATOL(ZSTR_VAL(new_value)); @@ -808,14 +846,48 @@ static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */ return SUCCESS; } /* }}} */ +static PHP_INI_MH(OnUpdateUseOnlyCookies) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + bool *p = (bool *) ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_bool(new_value); + if (!*p) { + php_error_docref("session.configuration", E_DEPRECATED, "Disabling session.use_only_cookies INI setting is deprecated"); + } + return SUCCESS; +} + +static PHP_INI_MH(OnUpdateUseTransSid) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + bool *p = (bool *) ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_bool(new_value); + if (*p) { + php_error_docref("session.configuration", E_DEPRECATED, "Enabling session.use_trans_sid INI setting is deprecated"); + } + return SUCCESS; +} + +static PHP_INI_MH(OnUpdateRefererCheck) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + if (ZSTR_LEN(new_value) != 0) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.referer_check INI setting is deprecated"); + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + /* {{{ PHP_INI */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionLong, gc_probability, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionLong, gc_divisor, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor,gc_divisor, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime,cookie_lifetime, php_ps_globals, ps_globals) @@ -825,12 +897,12 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionString, cookie_samesite, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_only_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateSessionString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionString, cache_limiter, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateSessionBool, use_trans_sid, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) @@ -1478,7 +1550,7 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */ zval_ptr_dtor_str(sid); ZVAL_STR(sid, smart_str_extract(&var)); } else { - REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), 0); + REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), CONST_DEPRECATED); smart_str_free(&var); } } else { @@ -1486,7 +1558,7 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */ zval_ptr_dtor_str(sid); ZVAL_EMPTY_STRING(sid); } else { - REGISTER_STRINGL_CONSTANT("SID", "", 0, 0); + REGISTER_STRINGL_CONSTANT("SID", "", 0, CONST_DEPRECATED); } } @@ -2383,6 +2455,10 @@ PHP_FUNCTION(session_create_id) } if (prefix && ZSTR_LEN(prefix)) { + if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { + zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); + RETURN_THROWS(); + } if (php_session_valid_key(ZSTR_VAL(prefix)) == FAILURE) { /* E_ERROR raised for security reason. */ php_error_docref(NULL, E_WARNING, "Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, \"-\", and \",\" characters are allowed"); diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h index a1fe34cfde3e8..3e0c889ae3c55 100644 --- a/ext/session/session_arginfo.h +++ b/ext/session/session_arginfo.h @@ -266,7 +266,7 @@ static zend_class_entry *register_class_SessionHandler(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SessionHandler", class_SessionHandler_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_SessionHandlerInterface, class_entry_SessionIdInterface); return class_entry; diff --git a/ext/session/tests/015.phpt b/ext/session/tests/015.phpt index 1d6e9d65fe67e..3154022fae861 100644 --- a/ext/session/tests/015.phpt +++ b/ext/session/tests/015.phpt @@ -20,10 +20,16 @@ error_reporting(E_ALL); session_id("test015"); session_start(); +$sid = SID; ?> - + ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: Constant SID is deprecated in %s on line 6 diff --git a/ext/session/tests/018.phpt b/ext/session/tests/018.phpt index f504f120d6b10..5d9c6eb6261b1 100644 --- a/ext/session/tests/018.phpt +++ b/ext/session/tests/018.phpt @@ -26,4 +26,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0
diff --git a/ext/session/tests/020.phpt b/ext/session/tests/020.phpt index 873973f04bfc5..3fb64dbc076ae 100644 --- a/ext/session/tests/020.phpt +++ b/ext/session/tests/020.phpt @@ -27,4 +27,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/021.phpt b/ext/session/tests/021.phpt index 02f712a9d871e..00d5779adf421 100644 --- a/ext/session/tests/021.phpt +++ b/ext/session/tests/021.phpt @@ -59,7 +59,12 @@ ini_set("url_rewriter.tags", "a=href,fieldset=,area=href,frame=src,input=src"); session_destroy(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 4
diff --git a/ext/session/tests/bug36459.phpt b/ext/session/tests/bug36459.phpt index 201aed60e056e..21a5f62c64312 100644 --- a/ext/session/tests/bug36459.phpt +++ b/ext/session/tests/bug36459.phpt @@ -30,6 +30,9 @@ session_start(); --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 Bug #36459 Incorrect adding PHPSESSID to links, which contains \r\n diff --git a/ext/session/tests/bug41600.phpt b/ext/session/tests/bug41600.phpt index 4181becfef395..09e89e67ea1a8 100644 --- a/ext/session/tests/bug41600.phpt +++ b/ext/session/tests/bug41600.phpt @@ -27,4 +27,7 @@ session_start(); session_destroy(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/bug42596.phpt b/ext/session/tests/bug42596.phpt index dca5fc0c99068..c1217384ce850 100644 --- a/ext/session/tests/bug42596.phpt +++ b/ext/session/tests/bug42596.phpt @@ -34,5 +34,6 @@ foreach (glob($sessdir. "*") as $sessfile) { rmdir($sessdir); ?> --EXPECT-- +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 hello world string(6) "100777" diff --git a/ext/session/tests/bug50308.phpt b/ext/session/tests/bug50308.phpt index 414a8354d35fd..920f967d42f9b 100644 --- a/ext/session/tests/bug50308.phpt +++ b/ext/session/tests/bug50308.phpt @@ -25,6 +25,9 @@ session.use_only_cookies=0 --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/bug51338.phpt b/ext/session/tests/bug51338.phpt index d6a2ddb652746..44d6cface0538 100644 --- a/ext/session/tests/bug51338.phpt +++ b/ext/session/tests/bug51338.phpt @@ -13,6 +13,7 @@ session_start(); print_r(ob_list_handlers()); ?> --EXPECT-- +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 Array ( ) diff --git a/ext/session/tests/bug71683.phpt b/ext/session/tests/bug71683.phpt index 9541121daa3b3..ad4783ee50cc3 100644 --- a/ext/session/tests/bug71683.phpt +++ b/ext/session/tests/bug71683.phpt @@ -14,4 +14,5 @@ ob_start(); echo "ok\n"; ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 ok diff --git a/ext/session/tests/bug71974.phpt b/ext/session/tests/bug71974.phpt index 1c16ab1c24e46..225a465f4c572 100644 --- a/ext/session/tests/bug71974.phpt +++ b/ext/session/tests/bug71974.phpt @@ -5,6 +5,7 @@ session --SKIPIF-- --INI-- +display_startup_errors=0 session.save_handler=files session.auto_start=0 session.use_cookies=1 diff --git a/ext/session/tests/bug72940.phpt b/ext/session/tests/bug72940.phpt index 740c5410743f5..9a927a5419e4a 100644 --- a/ext/session/tests/bug72940.phpt +++ b/ext/session/tests/bug72940.phpt @@ -31,8 +31,15 @@ session_start(); var_dump(session_id(), SID); session_destroy(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 + +Deprecated: Constant SID is deprecated in %s on line 8 string(12) "bug72940test" string(0) "" + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 13 + +Deprecated: Constant SID is deprecated in %s on line 15 string(11) "bug72940get" string(21) "PHPSESSID=bug72940get" diff --git a/ext/session/tests/bug74892.phpt b/ext/session/tests/bug74892.phpt index 793e67cfadd44..916120cb4d447 100644 --- a/ext/session/tests/bug74892.phpt +++ b/ext/session/tests/bug74892.phpt @@ -1,15 +1,17 @@ --TEST-- Bug #74892 Url Rewriting (trans_sid) not working on urls that start with # +--INI-- +session.use_cookies=0 +session.use_only_cookies=0 +session.use_trans_sid=1 --EXTENSIONS-- session --SKIPIF-- --FILE-- External link with anchor

External link with anchor 2

Internal link

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

Click This Anchor Tag!

External link with anchor

External link with anchor 2

diff --git a/ext/session/tests/deprecations.phpt b/ext/session/tests/deprecations.phpt new file mode 100644 index 0000000000000..4a2337fb99dad --- /dev/null +++ b/ext/session/tests/deprecations.phpt @@ -0,0 +1,64 @@ +--TEST-- +Deprecated GET/POST sessions +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.use_cookies=0 +session.use_only_cookies=1 +session.use_trans_sid=0 +--FILE-- + '0', 'use_only_cookies' => '0', 'use_trans_sid' => '1']); + +echo SID; + +?> +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 11 + +Deprecated: ini_set(): Usage of session.trans_sid_tags INI setting is deprecated in %s on line 16 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 21 + +Deprecated: ini_set(): Usage of session.referer_check INI setting is deprecated in %s on line 26 + +Deprecated: session_start(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 32 + +Deprecated: session_start(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 32 + +Deprecated: Constant SID is deprecated in %s on line 34 +PHPSESSID=%s diff --git a/ext/session/tests/gh13891.phpt b/ext/session/tests/gh13891.phpt index 7df9bffa770bc..97c0bfd617b70 100644 --- a/ext/session/tests/gh13891.phpt +++ b/ext/session/tests/gh13891.phpt @@ -14,4 +14,13 @@ session // We *must* set it here because the bug only triggers on a runtime edit ini_set('session.trans_sid_hosts','php.net'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Usage of session.trans_sid_hosts INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 3 + +Deprecated: PHP Request Shutdown: Usage of session.trans_sid_hosts INI setting is deprecated in Unknown on line 0 diff --git a/ext/session/tests/rfc1867.phpt b/ext/session/tests/rfc1867.phpt index 0962a91bc4fe7..6e2cf22752947 100644 --- a/ext/session/tests/rfc1867.phpt +++ b/ext/session/tests/rfc1867.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_cleanup.phpt b/ext/session/tests/rfc1867_cleanup.phpt index cdfd3c833104b..2cb25e8d6929a 100644 --- a/ext/session/tests/rfc1867_cleanup.phpt +++ b/ext/session/tests/rfc1867_cleanup.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_disabled.phpt b/ext/session/tests/rfc1867_disabled.phpt index a928a6171c33c..4ca2048f0446e 100644 --- a/ext/session/tests/rfc1867_disabled.phpt +++ b/ext/session/tests/rfc1867_disabled.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 disabled --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_disabled_2.phpt b/ext/session/tests/rfc1867_disabled_2.phpt index dcfbe075cbf5b..eb45d7f4bbcd3 100644 --- a/ext/session/tests/rfc1867_disabled_2.phpt +++ b/ext/session/tests/rfc1867_disabled_2.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 disabled 2 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_inter.phpt b/ext/session/tests/rfc1867_inter.phpt index a7ddff14f5e72..5ab9983ea14b1 100644 --- a/ext/session/tests/rfc1867_inter.phpt +++ b/ext/session/tests/rfc1867_inter.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_no_name.phpt b/ext/session/tests/rfc1867_no_name.phpt index d6a771baf2164..693c3814ec0d2 100644 --- a/ext/session/tests/rfc1867_no_name.phpt +++ b/ext/session/tests/rfc1867_no_name.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 no name --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_cookie.phpt b/ext/session/tests/rfc1867_sid_cookie.phpt index e090ebec5d6e6..5dc6492050f4f 100644 --- a/ext/session/tests/rfc1867_sid_cookie.phpt +++ b/ext/session/tests/rfc1867_sid_cookie.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid cookie --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_get.phpt b/ext/session/tests/rfc1867_sid_get.phpt index f227dd7d34300..8929556cdb0b3 100644 --- a/ext/session/tests/rfc1867_sid_get.phpt +++ b/ext/session/tests/rfc1867_sid_get.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid get --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_get_2.phpt b/ext/session/tests/rfc1867_sid_get_2.phpt index 8362f3b58d480..1a771935c4af0 100644 --- a/ext/session/tests/rfc1867_sid_get_2.phpt +++ b/ext/session/tests/rfc1867_sid_get_2.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid get 2 --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/rfc1867_sid_invalid.phpt b/ext/session/tests/rfc1867_sid_invalid.phpt index fe01b5a8ba2aa..2a61ab98d9206 100644 --- a/ext/session/tests/rfc1867_sid_invalid.phpt +++ b/ext/session/tests/rfc1867_sid_invalid.phpt @@ -6,7 +6,6 @@ upload_max_filesize=1024 session.save_path= session.name=PHPSESSID session.use_cookies=1 -session.use_only_cookies=0 session.use_strict_mode=0 session.auto_start=0 session.upload_progress.enabled=1 diff --git a/ext/session/tests/rfc1867_sid_post.phpt b/ext/session/tests/rfc1867_sid_post.phpt index e1f2123b56a58..62bc17bd83831 100644 --- a/ext/session/tests/rfc1867_sid_post.phpt +++ b/ext/session/tests/rfc1867_sid_post.phpt @@ -1,6 +1,7 @@ --TEST-- session rfc1867 sid post --INI-- +display_startup_errors=0 file_uploads=1 upload_max_filesize=1024 session.save_path= diff --git a/ext/session/tests/session_basic3.phpt b/ext/session/tests/session_basic3.phpt index 661f48546d123..7ddeffaa48d37 100644 --- a/ext/session/tests/session_basic3.phpt +++ b/ext/session/tests/session_basic3.phpt @@ -222,6 +222,9 @@ var_dump(session_destroy()); ob_end_flush(); ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 *** Testing basic session functionality : variation3 use_trans_sid *** *** Test trans sid *** diff --git a/ext/session/tests/session_basic4.phpt b/ext/session/tests/session_basic4.phpt index 93b04604d24d4..d1c8cdcd95928 100644 --- a/ext/session/tests/session_basic4.phpt +++ b/ext/session/tests/session_basic4.phpt @@ -48,6 +48,9 @@ echo ' '; ?> --EXPECT-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 *** Testing basic session functionality : variation4 use_trans_sid *** *** Test trans sid *** diff --git a/ext/session/tests/session_basic5.phpt b/ext/session/tests/session_basic5.phpt index 4f1d39ee02701..dd029b8aeeb7b 100644 --- a/ext/session/tests/session_basic5.phpt +++ b/ext/session/tests/session_basic5.phpt @@ -234,7 +234,12 @@ var_dump(session_destroy()); ob_end_flush(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 + +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 *** Testing basic session functionality : variation5 use_trans_sid *** *** Test trans sid *** diff --git a/ext/session/tests/session_create_id_invalid_prefix.phpt b/ext/session/tests/session_create_id_invalid_prefix.phpt index 0a4e2c2d40013..7de7e8061f689 100644 --- a/ext/session/tests/session_create_id_invalid_prefix.phpt +++ b/ext/session/tests/session_create_id_invalid_prefix.phpt @@ -12,8 +12,18 @@ session var_dump(session_create_id('_')); var_dump(session_create_id('%')); -var_dump(session_create_id("AB\0CD")); +try { + var_dump(session_create_id('ABTgdPs68S3M4HMaqKwj33TzqLMv5PHpWQxJbfpeogEhrJRY7o9f33pKLCmhf0tXCtoBkIu0yxXYCSHfJhPd2miPUW4MIpd91dnEiOwWDfaBnfdJZOwgvgmYLSfDGaebqmnCAoyuzlcq2j59nNRhccgJIkr9ytY3RwFTTXszpcjpx6mlJuG9GksKAhPsnnaEwSEb0eFyqvn80gYI2roKSjaFSmJxg0xgXuCF4csMo8DxiSvovho5QTKx5u7h8VyQL')); +} catch (Throwable $e) { + echo $e::class . ': ' . $e->getMessage() . "\n"; +} + +try { + var_dump(session_create_id("AB\0CD")); +} catch (Throwable $e) { + echo $e::class . ': ' . $e->getMessage() . "\n"; +} ?> Done @@ -23,9 +33,6 @@ bool(false) Warning: session_create_id(): Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in %s on line %d bool(false) - -Fatal error: Uncaught ValueError: session_create_id(): Argument #1 ($prefix) must not contain any null bytes in %s:%d -Stack trace: -#0 %s(5): session_create_id('AB\x00CD') -#1 {main} - thrown in %s +ValueError: session_create_id(): Argument #1 ($prefix) cannot be longer than 256 characters +ValueError: session_create_id(): Argument #1 ($prefix) must not contain any null bytes +Done diff --git a/ext/session/tests/session_gc_probability_ini.phpt b/ext/session/tests/session_gc_probability_ini.phpt new file mode 100644 index 0000000000000..6d6f7519ba41a --- /dev/null +++ b/ext/session/tests/session_gc_probability_ini.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test session.gc_probability and session.gc_divisor settings for invalid values +--INI-- +session.gc_maxlifetime=1 +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + -1, + 'gc_divisor' => -1 + ], + [ + 'gc_probability' => -1, + 'gc_divisor' => 1 + ], + [ + 'gc_probability' => 1, + 'gc_divisor' => -1 + ], + [ + 'gc_probability' => 1, + 'gc_divisor' => 0 + ], +]; + +ob_start(); +foreach($gc_settings as $gc_setting) { +try { + session_start($gc_setting); + session_write_close(); + } catch (Throwable $e) { + echo $e::class, ': '. $e->getMessage(), "\n"; + } +} +ob_end_flush(); +?> +Done +--EXPECTF-- +Warning: session_start(): session.gc_probability must be greater than or equal to 0 in %s on line %d + +Warning: session_start(): Setting option "gc_probability" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d + +Warning: session_start(): session.gc_probability must be greater than or equal to 0 in %s on line %d + +Warning: session_start(): Setting option "gc_probability" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d + +Warning: session_start(): session.gc_divisor must be greater than 0 in %s on line %d + +Warning: session_start(): Setting option "gc_divisor" failed in %s on line %d +Done diff --git a/ext/session/tests/user_session_module/bug71162.phpt b/ext/session/tests/user_session_module/bug71162.phpt index 12199d58d39c7..673e6ac2ecb19 100644 --- a/ext/session/tests/user_session_module/bug71162.phpt +++ b/ext/session/tests/user_session_module/bug71162.phpt @@ -5,7 +5,7 @@ session --INI-- session.use_strict_mode=0 --XFAIL-- -Current session module is designed to write empty session always. In addition, current session module only supports SessionHandlerInterface only from PHP 7.0. +Current session module is designed to write empty session always. --FILE-- ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 8a12d430d476f..e22a625bf9603 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -42,7 +42,7 @@ PHP_SXE_API zend_class_entry *sxe_get_element_class_entry(void) /* {{{ */ /* }}} */ static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, zend_function *fptr_count); -static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data); +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe); static xmlNodePtr php_sxe_reset_iterator_no_clear_iter_data(php_sxe_object *sxe, int use_data); static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data); static void php_sxe_iterator_dtor(zend_object_iterator *iter); @@ -96,7 +96,7 @@ static xmlNodePtr php_sxe_get_first_node_non_destructive(php_sxe_object *sxe, xm } } -static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, const zend_string *name, int prefix) /* {{{ */ +static inline int match_ns(xmlNodePtr node, const zend_string *name, int prefix) /* {{{ */ { if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) { return 1; @@ -125,7 +125,7 @@ static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, zend_long offse } } while (node && nodendx <= offset) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (sxe->iter.type == SXE_ITER_CHILD || ( sxe->iter.type == SXE_ITER_ELEMENT && xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)))) { if (nodendx == offset) { @@ -149,7 +149,7 @@ static xmlNodePtr sxe_find_element_by_name(php_sxe_object *sxe, xmlNodePtr node, { const xmlChar *raw_name = BAD_CAST ZSTR_VAL(name); while (node) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (xmlStrEqual(node->name, raw_name)) { return node; } @@ -183,7 +183,7 @@ static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node, } while (node) { - if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (node->type == XML_ELEMENT_NODE && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (xmlStrEqual(node->name, (xmlChar *)name)) { *type = SXE_ITER_ELEMENT; return orgnode; @@ -265,7 +265,7 @@ static zval *sxe_prop_dim_read(zend_object *object, zval *member, bool elements, if (Z_TYPE_P(member) != IS_LONG || sxe->iter.type == SXE_ITER_ATTRLIST) { if (Z_TYPE_P(member) == IS_LONG) { while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix); break; @@ -276,7 +276,7 @@ static zval *sxe_prop_dim_read(zend_object *object, zval *member, bool elements, } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(name)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { node_as_zval(sxe, (xmlNodePtr) attr, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix); break; } @@ -467,10 +467,9 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, case IS_OBJECT: if (Z_OBJCE_P(value) == ce_SimpleXMLElement) { zval zval_copy; - if (sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING) == FAILURE) { - zend_throw_error(NULL, "Unable to cast node to string"); - return &EG(error_zval); - } + zend_result rv = sxe_object_cast_ex(Z_OBJ_P(value), &zval_copy, IS_STRING); + ZEND_IGNORE_VALUE(rv); + ZEND_ASSERT(rv == SUCCESS); value_str = Z_STR(zval_copy); break; @@ -491,7 +490,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, if (attribs) { if (Z_TYPE_P(member) == IS_LONG) { while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { is_attr = 1; ++counter; @@ -503,7 +502,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { is_attr = 1; ++counter; break; @@ -542,7 +541,7 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value, while (node) { SKIP_TEXT(node); - if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { newnode = node; ++counter; } @@ -707,7 +706,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt int nodendx = 0; while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { exists = 1; break; @@ -718,7 +717,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt } } else { while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { exists = 1; break; } @@ -831,7 +830,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements int nodendx = 0; while (attr && nodendx <= Z_LVAL_P(member)) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { if (nodendx == Z_LVAL_P(member)) { xmlUnlinkNode((xmlNodePtr) attr); php_libxml_node_free_resource((xmlNodePtr) attr); @@ -844,7 +843,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements } else { while (attr) { anext = attr->next; - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && xmlStrEqual(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns((xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { xmlUnlinkNode((xmlNodePtr) attr); php_libxml_node_free_resource((xmlNodePtr) attr); break; @@ -871,7 +870,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements SKIP_TEXT(node); - if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if (xmlStrEqual(node->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix)) { xmlUnlinkNode(node); php_libxml_node_free_resource(node); } @@ -995,7 +994,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */ attr = node->properties; test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { return 0; } attr = attr->next; @@ -1031,7 +1030,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */ } } - if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) { + if (node->type == XML_ELEMENT_NODE && (! match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix))) { goto next_iter; } @@ -1092,7 +1091,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */ ZVAL_UNDEF(&zattr); test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; while (attr) { - if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { + if ((!test || xmlStrEqual(attr->name, BAD_CAST ZSTR_VAL(sxe->iter.name))) && match_ns((xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { ZVAL_STR(&value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1)); namelen = xmlStrlen(attr->name); if (Z_ISUNDEF(zattr)) { @@ -1138,7 +1137,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */ } } - if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) { + if (node->type == XML_ELEMENT_NODE && (! match_ns(node, sxe->iter.nsprefix, sxe->iter.isprefix))) { goto next_iter; } @@ -1667,7 +1666,7 @@ PHP_METHOD(SimpleXMLElement, addChild) } if (qname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1734,7 +1733,7 @@ PHP_METHOD(SimpleXMLElement, addAttribute) } if (qname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1753,7 +1752,8 @@ PHP_METHOD(SimpleXMLElement, addAttribute) } localname = xmlSplitQName2((xmlChar *)qname, &prefix); - if (localname == NULL) { + bool free_localname = localname != NULL; + if (!free_localname) { if (nsuri_len > 0) { if (prefix != NULL) { xmlFree(prefix); @@ -1761,17 +1761,13 @@ PHP_METHOD(SimpleXMLElement, addAttribute) php_error_docref(NULL, E_WARNING, "Attribute requires prefix for namespace"); return; } - localname = xmlStrdup((xmlChar *)qname); + localname = (xmlChar *) qname; } attrp = xmlHasNsProp(node, localname, (xmlChar *)nsuri); if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) { - xmlFree(localname); - if (prefix != NULL) { - xmlFree(prefix); - } php_error_docref(NULL, E_WARNING, "Attribute already exists"); - return; + goto out; } if (nsuri != NULL) { @@ -1783,7 +1779,10 @@ PHP_METHOD(SimpleXMLElement, addAttribute) attrp = xmlNewNsProp(node, nsptr, localname, (xmlChar *)value); - xmlFree(localname); +out: + if (free_localname) { + xmlFree(localname); + } if (prefix != NULL) { xmlFree(prefix); } @@ -1892,26 +1891,24 @@ PHP_METHOD(SimpleXMLElement, __toString) RETURN_THROWS(); } - if (sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING) != SUCCESS) { - zval_ptr_dtor(return_value); - RETURN_EMPTY_STRING(); - } + zend_result rv = sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING); + ZEND_IGNORE_VALUE(rv); + ZEND_ASSERT(rv == SUCCESS); } /* }}} */ -static zend_result php_sxe_count_elements_helper(php_sxe_object *sxe, zend_long *count) /* {{{ */ +static zend_long php_sxe_count_elements_helper(php_sxe_object *sxe) /* {{{ */ { - *count = 0; - + zend_long count = 0; xmlNodePtr node = php_sxe_reset_iterator_no_clear_iter_data(sxe, 0); while (node) { - (*count)++; + count++; node = php_sxe_iterator_fetch(sxe, node->next, 0); } - return SUCCESS; + return count; } /* }}} */ @@ -1929,23 +1926,21 @@ static zend_result sxe_count_elements(zend_object *object, zend_long *count) /* } return FAILURE; } - return php_sxe_count_elements_helper(intern, count); + *count = php_sxe_count_elements_helper(intern); + return SUCCESS; } /* }}} */ /* {{{ Get number of child elements */ PHP_METHOD(SimpleXMLElement, count) { - zend_long count = 0; php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } - php_sxe_count_elements_helper(sxe, &count); - - RETURN_LONG(count); + RETURN_LONG(php_sxe_count_elements_helper(sxe)); } /* }}} */ @@ -2364,7 +2359,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i if (sxe->iter.name) { while (node) { if (node->type == XML_ATTRIBUTE_NODE) { - if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(node, prefix, isprefix)) { break; } } @@ -2373,7 +2368,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else { while (node) { if (node->type == XML_ATTRIBUTE_NODE) { - if (match_ns(sxe, node, prefix, isprefix)) { + if (match_ns(node, prefix, isprefix)) { break; } } @@ -2383,7 +2378,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else if (sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name) { while (node) { if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) { + if (xmlStrEqual(node->name, BAD_CAST ZSTR_VAL(sxe->iter.name)) && match_ns(node, prefix, isprefix)) { break; } } @@ -2392,7 +2387,7 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i } else { while (node) { if (node->type == XML_ELEMENT_NODE) { - if (match_ns(sxe, node, prefix, isprefix)) { + if (match_ns(node, prefix, isprefix)) { break; } } @@ -2431,14 +2426,14 @@ static xmlNodePtr php_sxe_reset_iterator_no_clear_iter_data(php_sxe_object *sxe, return NULL; } -static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data) /* {{{ */ +static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe) /* {{{ */ { if (!Z_ISUNDEF(sxe->iter.data)) { zval_ptr_dtor(&sxe->iter.data); ZVAL_UNDEF(&sxe->iter.data); } - return php_sxe_reset_iterator_no_clear_iter_data(sxe, use_data); + return php_sxe_reset_iterator_no_clear_iter_data(sxe, 1); } /* }}} */ @@ -2534,7 +2529,7 @@ static void php_sxe_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ PHP_SXE_API void php_sxe_rewind_iterator(php_sxe_object *sxe) /* {{{ */ { - php_sxe_reset_iterator(sxe, 1); + php_sxe_reset_iterator(sxe); } /* }}} */ @@ -2545,7 +2540,7 @@ static void php_sxe_iterator_rewind(zend_object_iterator *iter) /* {{{ */ php_sxe_iterator *iterator = (php_sxe_iterator *)iter; sxe = iterator->sxe; - php_sxe_reset_iterator(sxe, 1); + php_sxe_reset_iterator(sxe); } /* }}} */ diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 285df20813f07..1048fe443017a 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -165,8 +165,7 @@ static zend_class_entry *register_class_SimpleXMLElement(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SimpleXMLElement", class_SimpleXMLElement_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 3, class_entry_Stringable, class_entry_Countable, class_entry_RecursiveIterator); return class_entry; @@ -177,7 +176,7 @@ static zend_class_entry *register_class_SimpleXMLIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SimpleXMLIterator", class_SimpleXMLIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SimpleXMLElement); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SimpleXMLElement, 0); return class_entry; } diff --git a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt index 8969cf0751de7..65f8f7baa8b7f 100644 --- a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt +++ b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt @@ -18,6 +18,6 @@ try { echo $a->asXML(); ?> --EXPECT-- -SimpleXMLElement::addAttribute(): Argument #1 ($qualifiedName) cannot be empty +SimpleXMLElement::addAttribute(): Argument #1 ($qualifiedName) must not be empty testfest diff --git a/ext/skeleton/.gitignore.in b/ext/skeleton/.gitignore.in index ae434fef9765c..52fc9c864cf0c 100644 --- a/ext/skeleton/.gitignore.in +++ b/ext/skeleton/.gitignore.in @@ -1,3 +1,4 @@ +*.dep *.lo *.la .libs @@ -39,3 +40,4 @@ tests/**/*.sh tests/**/*.db tests/**/*.mem tmp-php.ini +*~ diff --git a/ext/snmp/config.m4 b/ext/snmp/config.m4 index 79abace8de888..22cab40adf3be 100644 --- a/ext/snmp/config.m4 +++ b/ext/snmp/config.m4 @@ -87,5 +87,6 @@ if test "$PHP_SNMP" != "no"; then LIBS=$LIBS_SAVE PHP_NEW_EXTENSION([snmp], [snmp.c], [$ext_shared]) + PHP_ADD_EXTENSION_DEP(snmp, spl) PHP_SUBST([SNMP_SHARED_LIBADD]) fi diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index 07b9872883eab..a2facb6946d67 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -7,6 +7,7 @@ if (PHP_SNMP != "no") { SETUP_OPENSSL("snmp", PHP_SNMP) >= 2) { if (CHECK_LIB("netsnmp.lib", "snmp", PHP_SNMP)) { EXTENSION('snmp', 'snmp.c'); + ADD_EXTENSION_DEP('snmp', 'spl'); AC_DEFINE('HAVE_SNMP', 1, "Define to 1 if the PHP extension 'snmp' is available."); } else { WARNING("snmp not enabled; libraries and headers not found"); diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 62e77979a3a0c..7e8d4d0bc2fc1 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -668,7 +668,7 @@ static bool php_snmp_parse_oid( objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - zend_value_error("Array of object IDs cannot be empty"); + zend_value_error("Array of object IDs must not be empty"); return false; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); diff --git a/ext/snmp/snmp_arginfo.h b/ext/snmp/snmp_arginfo.h index 307c22ecb8d8e..97046c88b61c2 100644 --- a/ext/snmp/snmp_arginfo.h +++ b/ext/snmp/snmp_arginfo.h @@ -270,7 +270,7 @@ static zend_class_entry *register_class_SNMP(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SNMP", class_SNMP_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_VERSION_1_value; ZVAL_LONG(&const_VERSION_1_value, SNMP_VERSION_1); @@ -400,7 +400,7 @@ static zend_class_entry *register_class_SNMPException(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SNMPException", class_SNMPException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } diff --git a/ext/snmp/tests/snmp2_get.phpt b/ext/snmp/tests/snmp2_get.phpt index 174fbc91462e7..30500eb5ca9b3 100644 --- a/ext/snmp/tests/snmp2_get.phpt +++ b/ext/snmp/tests/snmp2_get.phpt @@ -54,7 +54,7 @@ var_dump(snmp2_get($hostname, $community, array('.1.3.6.1.2.1.1.1.0', '.1.3.6.1. --EXPECTF-- Checking error handling Empty OID array -Array of object IDs cannot be empty +Array of object IDs must not be empty Checking working Single OID string(%d) "%s" diff --git a/ext/soap/config.m4 b/ext/soap/config.m4 index 1f4370fdf8022..1b25e5101edec 100644 --- a/ext/soap/config.m4 +++ b/ext/soap/config.m4 @@ -20,6 +20,8 @@ if test "$PHP_SOAP" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_SUBST([SOAP_SHARED_LIBADD]) ]) + PHP_ADD_EXTENSION_DEP(soap, date) + PHP_ADD_EXTENSION_DEP(soap, hash) PHP_ADD_EXTENSION_DEP(soap, libxml) PHP_ADD_EXTENSION_DEP(soap, session, true) fi diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index f30d108465fdc..583f6a2b2e0d1 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -10,6 +10,8 @@ if (PHP_SOAP != "no") { ) { EXTENSION('soap', 'soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c', null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_SOAP', 1, "Define to 1 if the PHP extension 'soap' is available."); + ADD_EXTENSION_DEP('soap', 'date'); + ADD_EXTENSION_DEP('soap', 'hash'); ADD_EXTENSION_DEP('soap', 'session', true); if (!PHP_SOAP_SHARED) { diff --git a/ext/soap/soap.c b/ext/soap/soap.c index b152a1a187af0..401fbde9d82a9 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -571,7 +571,7 @@ PHP_METHOD(SoapParam, __construct) } if (ZSTR_LEN(name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -602,11 +602,11 @@ PHP_METHOD(SoapHeader, __construct) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(ns) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ZSTR_LEN(name) == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index 63e5a01910c48..23af99aa3946c 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -323,8 +323,7 @@ static zend_class_entry *register_class_Soap_Url(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Soap", "Url", class_Soap_Url_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -334,8 +333,7 @@ static zend_class_entry *register_class_Soap_Sdl(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "Soap", "Sdl", class_Soap_Sdl_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -345,7 +343,7 @@ static zend_class_entry *register_class_SoapParam(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapParam", class_SoapParam_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_param_name_default_value; ZVAL_UNDEF(&property_param_name_default_value); @@ -367,7 +365,7 @@ static zend_class_entry *register_class_SoapHeader(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapHeader", class_SoapHeader_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_namespace_default_value; ZVAL_UNDEF(&property_namespace_default_value); @@ -407,7 +405,7 @@ static zend_class_entry *register_class_SoapFault(zend_class_entry *class_entry_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapFault", class_SoapFault_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); zval property_faultstring_default_value; ZVAL_UNDEF(&property_faultstring_default_value); @@ -459,7 +457,7 @@ static zend_class_entry *register_class_SoapVar(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapVar", class_SoapVar_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_enc_type_default_value; ZVAL_UNDEF(&property_enc_type_default_value); @@ -505,7 +503,7 @@ static zend_class_entry *register_class_SoapServer(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapServer", class_SoapServer_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property___soap_fault_default_value; ZVAL_NULL(&property___soap_fault_default_value); @@ -522,7 +520,7 @@ static zend_class_entry *register_class_SoapClient(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SoapClient", class_SoapClient_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_uri_default_value; ZVAL_NULL(&property_uri_default_value); diff --git a/ext/soap/tests/bugs/bug31755.phpt b/ext/soap/tests/bugs/bug31755.phpt index 9284ba145e073..cf8987db3ee13 100644 --- a/ext/soap/tests/bugs/bug31755.phpt +++ b/ext/soap/tests/bugs/bug31755.phpt @@ -26,6 +26,6 @@ $response= $client->__soapCall('function', array(), null, $header); print $client->__getLastRequest(); ?> --EXPECT-- -SoapHeader::__construct(): Argument #1 ($namespace) cannot be empty +SoapHeader::__construct(): Argument #1 ($namespace) must not be empty bar diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 198ec02583edc..04dad88ac5915 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -662,7 +662,7 @@ static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_ * this is not required, at least on linux for abstract paths. It also * assumes that the path is not empty */ if (ZSTR_LEN(path_str) == 0) { - do_from_zval_err(ctx, "%s", "the path is cannot be empty"); + do_from_zval_err(ctx, "%s", "the path is must not be empty"); zend_tmp_string_release(tmp_path_str); return; } diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index a6258bc1f7388..f19672ecd5339 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -295,6 +295,13 @@ */ const SO_BINDTODEVICE = UNKNOWN; #endif +#ifdef SO_BINDTOIFINDEX +/** + * @var int + * @cvalue SO_BINDTOIFINDEX + */ +const SO_BINDTOIFINDEX = UNKNOWN; +#endif #ifdef SO_USER_COOKIE /** * @var int diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index a8dc7adaa8574..3faa4d1f43063 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: dcdacf23e3445748178066972e101cbe0ebd6ad5 */ + * Stub hash: 08677a3dd11366b55a1c539475adead74109595e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -425,6 +425,9 @@ static void register_sockets_symbols(int module_number) #if defined(SO_BINDTODEVICE) REGISTER_LONG_CONSTANT("SO_BINDTODEVICE", SO_BINDTODEVICE, CONST_PERSISTENT); #endif +#if defined(SO_BINDTOIFINDEX) + REGISTER_LONG_CONSTANT("SO_BINDTOIFINDEX", SO_BINDTOIFINDEX, CONST_PERSISTENT); +#endif #if defined(SO_USER_COOKIE) REGISTER_LONG_CONSTANT("SO_LABEL", SO_LABEL, CONST_PERSISTENT); #endif @@ -1087,8 +1090,7 @@ static zend_class_entry *register_class_Socket(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Socket", class_Socket_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -1098,8 +1100,7 @@ static zend_class_entry *register_class_AddressInfo(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AddressInfo", class_AddressInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index ebc5fadae6452..f1f0ce58ef81c 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1383,7 +1383,7 @@ static zend_class_entry *register_class_SodiumException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SodiumException", class_SodiumException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } diff --git a/ext/spl/spl_array_arginfo.h b/ext/spl/spl_array_arginfo.h index e846943c3cbfe..24dcadac661c8 100644 --- a/ext/spl/spl_array_arginfo.h +++ b/ext/spl/spl_array_arginfo.h @@ -259,7 +259,7 @@ static zend_class_entry *register_class_ArrayObject(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArrayObject", class_ArrayObject_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_IteratorAggregate, class_entry_ArrayAccess, class_entry_Serializable, class_entry_Countable); zval const_STD_PROP_LIST_value; @@ -282,7 +282,7 @@ static zend_class_entry *register_class_ArrayIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ArrayIterator", class_ArrayIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_SeekableIterator, class_entry_ArrayAccess, class_entry_Serializable, class_entry_Countable); zval const_STD_PROP_LIST_value; @@ -305,7 +305,7 @@ static zend_class_entry *register_class_RecursiveArrayIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveArrayIterator", class_RecursiveArrayIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_ArrayIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ArrayIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); zval const_CHILD_ARRAYS_ONLY_value; diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 15273cb6c46a4..1f75c4e3ae8f8 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -23,7 +23,7 @@ #include "ext/standard/php_filestat.h" #include "ext/standard/flock_compat.h" #include "ext/standard/scanf.h" -#include "ext/standard/php_string.h" +#include "ext/standard/php_string.h" /* For php_basename() */ #include "zend_attributes.h" #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -696,7 +696,7 @@ static void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_l } if (ZSTR_LEN(path) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1227,7 +1227,7 @@ PHP_METHOD(SplFileInfo, getLinkTarget) } #if defined(PHP_WIN32) || defined(HAVE_SYMLINK) if (intern->file_name == NULL) { - zend_value_error("Filename cannot be empty"); + zend_value_error("Filename must not be empty"); RETURN_THROWS(); } if (!IS_ABSOLUTE_PATH(ZSTR_VAL(intern->file_name), ZSTR_LEN(intern->file_name))) { @@ -1362,7 +1362,7 @@ PHP_METHOD(SplFileInfo, getPathInfo) path = spl_filesystem_object_get_pathname(intern); if (path && ZSTR_LEN(path)) { zend_string *dpath = zend_string_init(ZSTR_VAL(path), ZSTR_LEN(path), 0); - ZSTR_LEN(dpath) = php_dirname(ZSTR_VAL(dpath), ZSTR_LEN(path)); + ZSTR_LEN(dpath) = zend_dirname(ZSTR_VAL(dpath), ZSTR_LEN(path)); spl_filesystem_object_create_info(dpath, ce, return_value); zend_string_release(dpath); } diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 4534970dc492c..b8d197aa941b8 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -487,8 +487,7 @@ static zend_class_entry *register_class_SplFileInfo(zend_class_entry *class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFileInfo", class_SplFileInfo_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Stringable); @@ -507,7 +506,7 @@ static zend_class_entry *register_class_DirectoryIterator(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DirectoryIterator", class_DirectoryIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); zend_class_implements(class_entry, 1, class_entry_SeekableIterator); return class_entry; @@ -518,7 +517,7 @@ static zend_class_entry *register_class_FilesystemIterator(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FilesystemIterator", class_FilesystemIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_DirectoryIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DirectoryIterator, 0); zval const_CURRENT_MODE_MASK_value; ZVAL_LONG(&const_CURRENT_MODE_MASK_value, SPL_FILE_DIR_CURRENT_MODE_MASK); @@ -600,7 +599,7 @@ static zend_class_entry *register_class_RecursiveDirectoryIterator(zend_class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveDirectoryIterator", class_RecursiveDirectoryIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilesystemIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilesystemIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -612,7 +611,7 @@ static zend_class_entry *register_class_GlobIterator(zend_class_entry *class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "GlobIterator", class_GlobIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilesystemIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilesystemIterator, 0); zend_class_implements(class_entry, 1, class_entry_Countable); return class_entry; @@ -624,7 +623,7 @@ static zend_class_entry *register_class_SplFileObject(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFileObject", class_SplFileObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileInfo); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileInfo, 0); zend_class_implements(class_entry, 2, class_entry_RecursiveIterator, class_entry_SeekableIterator); zval const_DROP_NEW_LINE_value; @@ -659,7 +658,7 @@ static zend_class_entry *register_class_SplTempFileObject(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplTempFileObject", class_SplTempFileObject_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplFileObject); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplFileObject, 0); return class_entry; } diff --git a/ext/spl/spl_dllist_arginfo.h b/ext/spl/spl_dllist_arginfo.h index aa87f686bb70d..024fa6dc6e836 100644 --- a/ext/spl/spl_dllist_arginfo.h +++ b/ext/spl/spl_dllist_arginfo.h @@ -155,7 +155,7 @@ static zend_class_entry *register_class_SplDoublyLinkedList(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplDoublyLinkedList", class_SplDoublyLinkedList_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Iterator, class_entry_Countable, class_entry_ArrayAccess, class_entry_Serializable); zval const_IT_MODE_LIFO_value; @@ -190,7 +190,7 @@ static zend_class_entry *register_class_SplQueue(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplQueue", class_SplQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplDoublyLinkedList); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplDoublyLinkedList, 0); return class_entry; } @@ -200,7 +200,7 @@ static zend_class_entry *register_class_SplStack(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplStack", class_SplStack_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplDoublyLinkedList); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplDoublyLinkedList, 0); return class_entry; } diff --git a/ext/spl/spl_exceptions_arginfo.h b/ext/spl/spl_exceptions_arginfo.h index f2594f1238d72..7165074b4aece 100644 --- a/ext/spl/spl_exceptions_arginfo.h +++ b/ext/spl/spl_exceptions_arginfo.h @@ -58,7 +58,7 @@ static zend_class_entry *register_class_LogicException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LogicException", class_LogicException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -68,7 +68,7 @@ static zend_class_entry *register_class_BadFunctionCallException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "BadFunctionCallException", class_BadFunctionCallException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -78,7 +78,7 @@ static zend_class_entry *register_class_BadMethodCallException(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "BadMethodCallException", class_BadMethodCallException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_BadFunctionCallException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_BadFunctionCallException, 0); return class_entry; } @@ -88,7 +88,7 @@ static zend_class_entry *register_class_DomainException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DomainException", class_DomainException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -98,7 +98,7 @@ static zend_class_entry *register_class_InvalidArgumentException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InvalidArgumentException", class_InvalidArgumentException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -108,7 +108,7 @@ static zend_class_entry *register_class_LengthException(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LengthException", class_LengthException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -118,7 +118,7 @@ static zend_class_entry *register_class_OutOfRangeException(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OutOfRangeException", class_OutOfRangeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_LogicException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_LogicException, 0); return class_entry; } @@ -128,7 +128,7 @@ static zend_class_entry *register_class_RuntimeException(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RuntimeException", class_RuntimeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); return class_entry; } @@ -138,7 +138,7 @@ static zend_class_entry *register_class_OutOfBoundsException(zend_class_entry *c zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OutOfBoundsException", class_OutOfBoundsException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -148,7 +148,7 @@ static zend_class_entry *register_class_OverflowException(zend_class_entry *clas zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "OverflowException", class_OverflowException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -158,7 +158,7 @@ static zend_class_entry *register_class_RangeException(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RangeException", class_RangeException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -168,7 +168,7 @@ static zend_class_entry *register_class_UnderflowException(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnderflowException", class_UnderflowException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } @@ -178,7 +178,7 @@ static zend_class_entry *register_class_UnexpectedValueException(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "UnexpectedValueException", class_UnexpectedValueException_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RuntimeException, 0); return class_entry; } diff --git a/ext/spl/spl_fixedarray_arginfo.h b/ext/spl/spl_fixedarray_arginfo.h index 2e66e7060d50b..e517833a02b89 100644 --- a/ext/spl/spl_fixedarray_arginfo.h +++ b/ext/spl/spl_fixedarray_arginfo.h @@ -94,7 +94,7 @@ static zend_class_entry *register_class_SplFixedArray(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplFixedArray", class_SplFixedArray_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_IteratorAggregate, class_entry_ArrayAccess, class_entry_Countable, class_entry_JsonSerializable); diff --git a/ext/spl/spl_heap_arginfo.h b/ext/spl/spl_heap_arginfo.h index 9910ae15cd988..31a3f79fe2c75 100644 --- a/ext/spl/spl_heap_arginfo.h +++ b/ext/spl/spl_heap_arginfo.h @@ -161,7 +161,7 @@ static zend_class_entry *register_class_SplPriorityQueue(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplPriorityQueue", class_SplPriorityQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 2, class_entry_Iterator, class_entry_Countable); zval const_EXTR_BOTH_value; @@ -190,8 +190,7 @@ static zend_class_entry *register_class_SplHeap(zend_class_entry *class_entry_It zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplHeap", class_SplHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 2, class_entry_Iterator, class_entry_Countable); return class_entry; @@ -202,7 +201,7 @@ static zend_class_entry *register_class_SplMinHeap(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplMinHeap", class_SplMinHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplHeap); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplHeap, 0); return class_entry; } @@ -212,7 +211,7 @@ static zend_class_entry *register_class_SplMaxHeap(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplMaxHeap", class_SplMaxHeap_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_SplHeap); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_SplHeap, 0); return class_entry; } diff --git a/ext/spl/spl_iterators_arginfo.h b/ext/spl/spl_iterators_arginfo.h index 1d6566f6c6908..d0b0d5ddbcc87 100644 --- a/ext/spl/spl_iterators_arginfo.h +++ b/ext/spl/spl_iterators_arginfo.h @@ -605,7 +605,7 @@ static zend_class_entry *register_class_EmptyIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "EmptyIterator", class_EmptyIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; @@ -616,7 +616,7 @@ static zend_class_entry *register_class_CallbackFilterIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CallbackFilterIterator", class_CallbackFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, 0); return class_entry; } @@ -626,7 +626,7 @@ static zend_class_entry *register_class_RecursiveCallbackFilterIterator(zend_cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveCallbackFilterIterator", class_RecursiveCallbackFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CallbackFilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CallbackFilterIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -648,7 +648,7 @@ static zend_class_entry *register_class_RecursiveIteratorIterator(zend_class_ent zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveIteratorIterator", class_RecursiveIteratorIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_OuterIterator); zval const_LEAVES_ONLY_value; @@ -694,7 +694,7 @@ static zend_class_entry *register_class_IteratorIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "IteratorIterator", class_IteratorIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_OuterIterator); return class_entry; @@ -705,8 +705,7 @@ static zend_class_entry *register_class_FilterIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FilterIterator", class_FilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, ZEND_ACC_ABSTRACT); return class_entry; } @@ -716,8 +715,7 @@ static zend_class_entry *register_class_RecursiveFilterIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveFilterIterator", class_RecursiveFilterIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); - class_entry->ce_flags |= ZEND_ACC_ABSTRACT; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, ZEND_ACC_ABSTRACT); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -728,7 +726,7 @@ static zend_class_entry *register_class_ParentIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ParentIterator", class_ParentIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveFilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveFilterIterator, 0); return class_entry; } @@ -749,7 +747,7 @@ static zend_class_entry *register_class_LimitIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LimitIterator", class_LimitIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -759,7 +757,7 @@ static zend_class_entry *register_class_CachingIterator(zend_class_entry *class_ zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "CachingIterator", class_CachingIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); zend_class_implements(class_entry, 3, class_entry_ArrayAccess, class_entry_Countable, class_entry_Stringable); zval const_CALL_TOSTRING_value; @@ -806,7 +804,7 @@ static zend_class_entry *register_class_RecursiveCachingIterator(zend_class_entr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveCachingIterator", class_RecursiveCachingIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_CachingIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_CachingIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -817,7 +815,7 @@ static zend_class_entry *register_class_NoRewindIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NoRewindIterator", class_NoRewindIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -827,7 +825,7 @@ static zend_class_entry *register_class_AppendIterator(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AppendIterator", class_AppendIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -837,7 +835,7 @@ static zend_class_entry *register_class_InfiniteIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InfiniteIterator", class_InfiniteIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_IteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_IteratorIterator, 0); return class_entry; } @@ -847,7 +845,7 @@ static zend_class_entry *register_class_RegexIterator(zend_class_entry *class_en zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RegexIterator", class_RegexIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_FilterIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_FilterIterator, 0); zval const_USE_KEY_value; ZVAL_LONG(&const_USE_KEY_value, REGIT_USE_KEY); @@ -905,7 +903,7 @@ static zend_class_entry *register_class_RecursiveRegexIterator(zend_class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveRegexIterator", class_RecursiveRegexIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RegexIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RegexIterator, 0); zend_class_implements(class_entry, 1, class_entry_RecursiveIterator); return class_entry; @@ -916,7 +914,7 @@ static zend_class_entry *register_class_RecursiveTreeIterator(zend_class_entry * zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "RecursiveTreeIterator", class_RecursiveTreeIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_RecursiveIteratorIterator); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_RecursiveIteratorIterator, 0); zval const_BYPASS_CURRENT_value; ZVAL_LONG(&const_BYPASS_CURRENT_value, RTIT_BYPASS_CURRENT); diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 730f4c279c254..be12c594e0146 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -255,7 +255,7 @@ static zend_class_entry *register_class_SplObjectStorage(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SplObjectStorage", class_SplObjectStorage_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Countable, class_entry_SeekableIterator, class_entry_Serializable, class_entry_ArrayAccess); return class_entry; @@ -266,7 +266,7 @@ static zend_class_entry *register_class_MultipleIterator(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "MultipleIterator", class_MultipleIterator_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Iterator); zval const_MIT_NEED_ANY_value; diff --git a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt index 01b7c7d72cf19..3db6700d2e94c 100644 --- a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt +++ b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt @@ -12,4 +12,4 @@ try { } ?> --EXPECT-- -DirectoryIterator::__construct(): Argument #1 ($directory) cannot be empty +DirectoryIterator::__construct(): Argument #1 ($directory) must not be empty diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 4ef8cb3101ae4..01b8af435b633 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -421,7 +421,7 @@ PHP_METHOD(SQLite3, loadExtension) } if (extension_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/sqlite3/sqlite3_arginfo.h b/ext/sqlite3/sqlite3_arginfo.h index 9c813bace265c..31588ffd57345 100644 --- a/ext/sqlite3/sqlite3_arginfo.h +++ b/ext/sqlite3/sqlite3_arginfo.h @@ -294,8 +294,7 @@ static zend_class_entry *register_class_SQLite3Exception(zend_class_entry *class zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Exception", class_SQLite3Exception_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); - class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, ZEND_ACC_NO_DYNAMIC_PROPERTIES); return class_entry; } @@ -305,8 +304,7 @@ static zend_class_entry *register_class_SQLite3(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3", class_SQLite3_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); zval const_OK_value; ZVAL_LONG(&const_OK_value, SQLITE_OK); @@ -540,8 +538,7 @@ static zend_class_entry *register_class_SQLite3Stmt(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Stmt", class_SQLite3Stmt_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -551,8 +548,7 @@ static zend_class_entry *register_class_SQLite3Result(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SQLite3Result", class_SQLite3Result_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt index 8ab22520267f0..0be7469c8944b 100644 --- a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt +++ b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt @@ -26,4 +26,4 @@ try { ?> --EXPECTF-- -string(61) "SQLite3::loadExtension(): Argument #1 ($name) cannot be empty" +string(63) "SQLite3::loadExtension(): Argument #1 ($name) must not be empty" diff --git a/ext/standard/array.c b/ext/standard/array.c index 068057e70a9ec..a2fef8b145283 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6211,7 +6211,7 @@ PHPAPI bool php_array_pick_keys(php_random_algo_with_state engine, zval *input, if (num_avail == 0) { if (!silent) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); } return false; } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 7b3494303ca41..67276adb1627e 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2500,7 +2500,7 @@ PHP_FUNCTION(parse_ini_file) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index 45ea1f0a887ba..1985040f70ad2 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -51,10 +51,6 @@ PHPAPI int _php_error_log(int opt_err, const char *message, const char *opt, con PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_len, const char *opt, const char *headers); PHPAPI int php_prefix_varname(zval *result, zend_string *prefix, const char *var_name, size_t var_name_len, bool add_underscore); -/* Deprecated type aliases -- use the standard types instead */ -typedef uint32_t php_uint32; -typedef int32_t php_int32; - typedef struct _php_basic_globals { HashTable *user_shutdown_function_names; HashTable putenv_ht; diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 00bc7c5509d06..6834c3094dd73 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -4178,8 +4178,7 @@ static zend_class_entry *register_class___PHP_Incomplete_Class(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "__PHP_Incomplete_Class", class___PHP_Incomplete_Class_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); zend_string *attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0, 0); @@ -4193,7 +4192,7 @@ static zend_class_entry *register_class_AssertionError(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "AssertionError", class_AssertionError_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, 0); return class_entry; } diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 5975cc2936c11..90a3cbd3166ab 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -104,8 +104,8 @@ AC_SEARCH_LIBS([crypt_r], [crypt], PHP_CRYPT_R_STYLE AC_CHECK_HEADERS([crypt.h]) - AC_CACHE_CHECK(for standard DES crypt, ac_cv_crypt_des,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +AC_CACHE_CHECK([for standard DES crypt], [ac_cv_crypt_des], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifdef HAVE_UNISTD_H #include #endif @@ -120,16 +120,13 @@ AC_CHECK_HEADERS([crypt.h]) int main(void) { char *encrypted = crypt("rasmuslerdorf","rl"); return !encrypted || strcmp(encrypted,"rl.3StKT.4T8M"); -}]])],[ - ac_cv_crypt_des=yes -],[ - ac_cv_crypt_des=no -],[ - ac_cv_crypt_des=yes -])]) - - AC_CACHE_CHECK(for extended DES crypt, ac_cv_crypt_ext_des,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}])], + [ac_cv_crypt_des=yes], + [ac_cv_crypt_des=no], + [ac_cv_crypt_des=yes])]) + +AC_CACHE_CHECK([for extended DES crypt], [ac_cv_crypt_ext_des], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifdef HAVE_UNISTD_H #include #endif @@ -144,16 +141,13 @@ int main(void) { int main(void) { char *encrypted = crypt("rasmuslerdorf","_J9..rasm"); return !encrypted || strcmp(encrypted,"_J9..rasmBYk8r9AiWNc"); -}]])],[ - ac_cv_crypt_ext_des=yes - ],[ - ac_cv_crypt_ext_des=no - ],[ - ac_cv_crypt_ext_des=no - ])]) - - AC_CACHE_CHECK(for MD5 crypt, ac_cv_crypt_md5,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}])], + [ac_cv_crypt_ext_des=yes], + [ac_cv_crypt_ext_des=no], + [ac_cv_crypt_ext_des=no])]) + +AC_CACHE_CHECK([for MD5 crypt], [ac_cv_crypt_md5], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -178,16 +172,13 @@ int main(void) { strcat(answer,"rISCgZzpwk3UhDidwXvin0"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_md5=yes - ],[ - ac_cv_crypt_md5=no - ],[ - ac_cv_crypt_md5=no - ])]) - - AC_CACHE_CHECK(for Blowfish crypt, ac_cv_crypt_blowfish,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_md5=yes], + [ac_cv_crypt_md5=no], + [ac_cv_crypt_md5=no])]) + +AC_CACHE_CHECK([for Blowfish crypt], [ac_cv_crypt_blowfish], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -203,22 +194,20 @@ int main(void) { char salt[30], answer[70]; char *encrypted; - salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0'; + salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; + salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0'; strcat(salt,"rasmuslerd............"); strcpy(answer,salt); strcpy(&answer[29],"nIdrcHdxcUxWomQX9j6kvERCFjTg7Ra"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_blowfish=yes - ],[ - ac_cv_crypt_blowfish=no - ],[ - ac_cv_crypt_blowfish=no - ])]) - - AC_CACHE_CHECK(for SHA512 crypt, ac_cv_crypt_sha512,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_blowfish=yes], + [ac_cv_crypt_blowfish=no], + [ac_cv_crypt_blowfish=no])]) + +AC_CACHE_CHECK([for SHA512 crypt], [ac_cv_crypt_sha512], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -239,16 +228,13 @@ int main(void) { strcat(answer, "EeHCRjm0bljalWuALHSTs1NB9ipEiLEXLhYeXdOpx22gmlmVejnVXFhd84cEKbYxCo.XuUTrW.RLraeEnsvWs/"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); - }]])],[ - ac_cv_crypt_sha512=yes - ],[ - ac_cv_crypt_sha512=no - ],[ - ac_cv_crypt_sha512=no - ])]) - - AC_CACHE_CHECK(for SHA256 crypt, ac_cv_crypt_sha256,[ - AC_RUN_IFELSE([AC_LANG_SOURCE([[ +}]])], + [ac_cv_crypt_sha512=yes], + [ac_cv_crypt_sha512=no], + [ac_cv_crypt_sha512=no])]) + +AC_CACHE_CHECK([for SHA256 crypt], [ac_cv_crypt_sha256], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_UNISTD_H #include #endif @@ -269,13 +255,10 @@ int main(void) { strcat(answer, "cFAm2puLCujQ9t.0CxiFIIvFi4JyQx5UncCt/xRIX23"); encrypted = crypt("rasmuslerdorf",salt); return !encrypted || strcmp(encrypted,answer); -}]])],[ - ac_cv_crypt_sha256=yes - ],[ - ac_cv_crypt_sha256=no - ],[ - ac_cv_crypt_sha256=no - ])]) +}]])], + [ac_cv_crypt_sha256=yes], + [ac_cv_crypt_sha256=no], + [ac_cv_crypt_sha256=no])]) if test "$ac_cv_crypt_blowfish" = "no" || test "$ac_cv_crypt_des" = "no" || test "$ac_cv_crypt_ext_des" = "no" || test "$ac_cv_crypt_md5" = "no" || test "$ac_cv_crypt_sha512" = "no" || test "$ac_cv_crypt_sha256" = "no"; then AC_MSG_FAILURE([Cannot use external libcrypt as some algo are missing.]) diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index d9ccd78feb53b..e99c3ca9f5a02 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -15,7 +15,6 @@ */ #include "php.h" -#include "basic_functions.h" #include "crc32.h" #include "crc32_x86.h" @@ -129,7 +128,7 @@ PHPAPI uint32_t php_crc32_bulk_update(uint32_t crc, const char *p, size_t nr) return crc; } -PHPAPI int php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr) +PHPAPI zend_result php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr) { size_t handled = 0, n; char buf[1024]; diff --git a/ext/standard/crc32.h b/ext/standard/crc32.h index bdf45a4bef511..261acdeb1feca 100644 --- a/ext/standard/crc32.h +++ b/ext/standard/crc32.h @@ -29,7 +29,7 @@ PHPAPI uint32_t php_crc32_bulk_update(uint32_t crc, const char *p, size_t nr); /* Return FAILURE if stream reading fail */ -PHPAPI int php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr); +PHPAPI zend_result php_crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr); /* generated using the AUTODIN II polynomial * x^32 + x^26 + x^23 + x^22 + x^16 + diff --git a/ext/standard/dir.c b/ext/standard/dir.c index edb62c368fcfa..1af6efe211a7e 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -467,7 +467,7 @@ PHP_FUNCTION(scandir) ZEND_PARSE_PARAMETERS_END(); if (dirn_len < 1) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dir_arginfo.h b/ext/standard/dir_arginfo.h index cdf21396bb0ab..47ab180ed7b17 100644 --- a/ext/standard/dir_arginfo.h +++ b/ext/standard/dir_arginfo.h @@ -58,7 +58,7 @@ static zend_class_entry *register_class_Directory(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "Directory", class_Directory_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_path_default_value; ZVAL_UNDEF(&property_path_default_value); diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 41e90e3e924bd..04477129e3599 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -388,7 +388,7 @@ PHP_FUNCTION(dns_check_record) ZEND_PARSE_PARAMETERS_END(); if (hostname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 2aeedb133e018..a41d6f44d03a0 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -108,7 +108,7 @@ PHP_FUNCTION(dns_check_record) } if (hostname_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 5b3ba60e5fdea..8ebca90bce396 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -218,7 +218,7 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ ZEND_PARSE_PARAMETERS_END(); if (!cmd_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (strlen(cmd) != cmd_len) { @@ -514,15 +514,11 @@ PHP_FUNCTION(shell_exec) php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(command, command_len) + Z_PARAM_PATH(command, command_len) ZEND_PARSE_PARAMETERS_END(); if (!command_len) { - zend_argument_value_error(1, "cannot be empty"); - RETURN_THROWS(); - } - if (strlen(command) != command_len) { - zend_argument_value_error(1, "must not contain any null bytes"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/file.c b/ext/standard/file.c index 677fd74d225cf..6b6b43b1fb672 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1499,35 +1499,31 @@ PHP_FUNCTION(copy) context = php_stream_context_from_zval(zcontext, 0); - if (php_copy_file_ctx(source, target, 0, context) == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(php_copy_file_ctx(source, target, 0, context) == SUCCESS); } /* }}} */ /* {{{ php_copy_file */ -PHPAPI int php_copy_file(const char *src, const char *dest) +PHPAPI zend_result php_copy_file(const char *src, const char *dest) { return php_copy_file_ctx(src, dest, 0, NULL); } /* }}} */ /* {{{ php_copy_file_ex */ -PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_flg) +PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags) { - return php_copy_file_ctx(src, dest, src_flg, NULL); + return php_copy_file_ctx(src, dest, src_flags, NULL); } /* }}} */ /* {{{ php_copy_file_ctx */ -PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php_stream_context *ctx) +PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx) { php_stream *srcstream = NULL, *deststream = NULL; - int ret = FAILURE; + zend_result ret = FAILURE; php_stream_statbuf src_s, dest_s; - int src_stat_flags = (src_flg & STREAM_DISABLE_OPEN_BASEDIR) ? PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR : 0; + int src_stat_flags = (src_flags & STREAM_DISABLE_OPEN_BASEDIR) ? PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR : 0; switch (php_stream_stat_path_ex(src, src_stat_flags, &src_s, ctx)) { case -1: @@ -1594,7 +1590,7 @@ PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php } safe_to_copy: - srcstream = php_stream_open_wrapper_ex(src, "rb", src_flg | REPORT_ERRORS, NULL, ctx); + srcstream = php_stream_open_wrapper_ex(src, "rb", src_flags | REPORT_ERRORS, NULL, ctx); if (!srcstream) { return ret; diff --git a/ext/standard/file.h b/ext/standard/file.h index 0f3ccd7c27ab3..eead935848877 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -37,10 +37,9 @@ PHPAPI PHP_FUNCTION(fpassthru); PHP_MINIT_FUNCTION(user_streams); PHPAPI int php_le_stream_context(void); -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block); -PHPAPI int php_copy_file(const char *src, const char *dest); -PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_chk); -PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_chk, php_stream_context *ctx); +PHPAPI zend_result php_copy_file(const char *src, const char *dest); +PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags); +PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx); PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options); PHPAPI int php_mkdir(const char *dir, zend_long mode); PHPAPI void php_fstat(php_stream *stream, zval *return_value); diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 1a046b3de6979..98715b2ee8a08 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -40,7 +40,7 @@ PHP_FUNCTION(ftok) ZEND_PARSE_PARAMETERS_END(); if (pathname_len == 0){ - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/standard/head.c b/ext/standard/head.c index 0acd34c83c4e9..ccef4be16bdfd 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -87,7 +87,7 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e smart_str buf = {0}; if (!ZSTR_LEN(name)) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); return FAILURE; } if (strpbrk(ZSTR_VAL(name), "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ diff --git a/ext/standard/http.c b/ext/standard/http.c index 7a4a58755d894..5f796a4a4026b 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -19,7 +19,6 @@ #include "url.h" #include "SAPI.h" #include "zend_exceptions.h" -#include "ext/spl/spl_exceptions.h" #include "basic_functions.h" static void php_url_encode_scalar(zval *scalar, smart_str *form_str, @@ -338,7 +337,7 @@ PHP_FUNCTION(request_parse_body) sapi_read_post_data(); if (!SG(request_info).post_entry) { - zend_throw_error(spl_ce_InvalidArgumentException, "Content-Type \"%s\" is not supported", SG(request_info).content_type); + zend_throw_error(zend_ce_request_parse_body_exception, "Content-Type \"%s\" is not supported", SG(request_info).content_type); goto exit; } diff --git a/ext/standard/info.c b/ext/standard/info.c index 864199d66de10..8a706ef62eb57 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -296,19 +296,8 @@ static char* php_get_windows_name() } } else if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 6) { if (osvi.dwMajorVersion == 6) { - if (osvi.dwMinorVersion == 0) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - major = "Windows Vista"; - } else { - major = "Windows Server 2008"; - } - } else if (osvi.dwMinorVersion == 1) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - major = "Windows 7"; - } else { - major = "Windows Server 2008 R2"; - } - } else if (osvi.dwMinorVersion == 2) { + ZEND_ASSERT(osvi.dwMinorVersion >= 2); + if (osvi.dwMinorVersion == 2) { /* could be Windows 8/Windows Server 2012, could be Windows 8.1/Windows Server 2012 R2 */ /* XXX and one more X - the above comment is true if no manifest is used for two cases: - if the PHP build doesn't use the correct manifest @@ -656,10 +645,16 @@ static void php_get_windows_cpu(char *buf, size_t bufsize) /* }}} */ #endif +static inline bool php_is_valid_uname_mode(char mode) { + return mode == 'a' || mode == 'm' || mode == 'n' || mode == 'r' || mode == 's' || mode == 'v'; +} + /* {{{ php_get_uname */ PHPAPI zend_string *php_get_uname(char mode) { char *php_uname; + + ZEND_ASSERT(php_is_valid_uname_mode(mode)); #ifdef PHP_WIN32 char tmp_uname[256]; DWORD dwBuild=0; @@ -680,13 +675,12 @@ PHPAPI zend_string *php_get_uname(char mode) } else if (mode == 'v') { char *winver = php_get_windows_name(); dwBuild = (DWORD)(HIWORD(dwVersion)); - if (winver == NULL) { - return strpprintf(0, "build %d", dwBuild); - } else { - zend_string *build_with_version = strpprintf(0, "build %d (%s)", dwBuild, winver); - efree(winver); - return build_with_version; - } + + ZEND_ASSERT(winver != NULL); + + zend_string *build_with_version = strpprintf(0, "build %d (%s)", dwBuild, winver); + efree(winver); + return build_with_version; } else if (mode == 'm') { php_get_windows_cpu(tmp_uname, sizeof(tmp_uname)); php_uname = tmp_uname; @@ -1314,15 +1308,26 @@ PHP_FUNCTION(php_sapi_name) /* {{{ Return information about the system PHP was built on */ PHP_FUNCTION(php_uname) { - char *mode = "a"; + char *mode_str = "a"; size_t modelen = sizeof("a")-1; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STRING(mode, modelen) + Z_PARAM_STRING(mode_str, modelen) ZEND_PARSE_PARAMETERS_END(); - RETURN_STR(php_get_uname(*mode)); + if (modelen != 1) { + zend_argument_value_error(1, "must be a single character"); + RETURN_THROWS(); + } + + char mode = *mode_str; + if (!php_is_valid_uname_mode(mode)) { + zend_argument_value_error(1, "must be one of \"a\", \"m\", \"n\", \"r\", \"s\", or \"v\""); + RETURN_THROWS(); + } + + RETURN_STR(php_get_uname(mode)); } /* }}} */ diff --git a/ext/standard/link.c b/ext/standard/link.c index 0529006d4667c..df2831b878462 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -99,8 +99,9 @@ PHP_FUNCTION(linkinfo) Z_PARAM_PATH(link, link_len) ZEND_PARSE_PARAMETERS_END(); + // TODO Check for empty string dirname = estrndup(link, link_len); - php_dirname(dirname, link_len); + zend_dirname(dirname, link_len); if (php_check_open_basedir(dirname)) { efree(dirname); @@ -141,7 +142,7 @@ PHP_FUNCTION(symlink) } memcpy(dirname, source_p, sizeof(source_p)); - len = php_dirname(dirname, strlen(dirname)); + len = zend_dirname(dirname, strlen(dirname)); if (!expand_filepath_ex(topath, dest_p, dirname, len)) { php_error_docref(NULL, E_WARNING, "No such file or directory"); diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 1fddded70153b..35c23a0be76c0 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -56,6 +56,14 @@ extern zend_long php_getuid(void); +typedef enum { + NO_HEADER_ERROR, + CONTAINS_LF_ONLY, + CONTAINS_CR_ONLY, + CONTAINS_CRLF, + CONTAINS_NULL +} php_mail_header_value_error_type; + static php_mail_header_value_error_type php_mail_build_headers_check_field_value(zval *val) { size_t len = 0; @@ -181,6 +189,20 @@ static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *v } ZEND_HASH_FOREACH_END(); } +#define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ +do { \ + if (Z_TYPE_P(val) == IS_STRING) { \ + php_mail_build_headers_elem(&s, key, val); \ + } else if (Z_TYPE_P(val) == IS_ARRAY) { \ + if (zend_string_equals_literal_ci(key, target)) { \ + zend_type_error("Header \"%s\" must be of type string, array given", target); \ + break; \ + } \ + php_mail_build_headers_elems(&s, key, val); \ + } else { \ + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ + } \ +} while(0) PHPAPI zend_string *php_mail_build_headers(HashTable *headers) { @@ -219,7 +241,13 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) } else if (zend_string_equals_literal_ci(key, "subject")) { zend_value_error("The additional headers cannot contain the \"Subject\" header"); } else { - PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + if (Z_TYPE_P(val) == IS_STRING) { + php_mail_build_headers_elem(&s, key, val); + } else if (Z_TYPE_P(val) == IS_ARRAY) { + php_mail_build_headers_elems(&s, key, val); + } else { + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); + } } if (EG(exception)) { @@ -408,14 +436,9 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { /* {{{ php_mail */ -PHPAPI int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) +PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) { -#ifdef PHP_WIN32 - int tsm_err; - char *tsm_errmsg = NULL; -#endif FILE *sendmail; - int ret; char *sendmail_path = INI_STR("sendmail_path"); char *sendmail_cmd = NULL; char *mail_log = INI_STR("mail.log"); @@ -464,7 +487,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } if (EG(exception)) { - MAIL_RET(0); + MAIL_RET(false); } char *line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : "\r\n"; @@ -486,11 +509,14 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co if (hdr && php_mail_detect_multiple_crlf(hdr)) { php_error_docref(NULL, E_WARNING, "Multiple or malformed newlines found in additional_header"); - MAIL_RET(0); + MAIL_RET(false); } if (!sendmail_path) { #ifdef PHP_WIN32 + int tsm_err; + char *tsm_errmsg = NULL; + /* handle old style win smtp sending */ if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL) == FAILURE) { if (tsm_errmsg) { @@ -499,11 +525,11 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co } else { php_error_docref(NULL, E_WARNING, "%s", GetSMErrorText(tsm_err)); } - MAIL_RET(0); + MAIL_RET(false); } - MAIL_RET(1); + MAIL_RET(true); #else - MAIL_RET(0); + MAIL_RET(false); #endif } if (extra_cmd != NULL) { @@ -547,7 +573,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co signal(SIGCHLD, sig_handler); } #endif - MAIL_RET(0); + MAIL_RET(false); } #endif fprintf(sendmail, "To: %s%s", to, line_sep); @@ -556,7 +582,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co fprintf(sendmail, "%s%s", hdr, line_sep); } fprintf(sendmail, "%s%s%s", line_sep, message, line_sep); - ret = pclose(sendmail); + int ret = pclose(sendmail); #if PHP_SIGCHILD if (sig_handler) { @@ -576,9 +602,9 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co #endif #endif { - MAIL_RET(0); + MAIL_RET(false); } else { - MAIL_RET(1); + MAIL_RET(true); } } else { php_error_docref(NULL, E_WARNING, "Could not execute mail delivery program '%s'", sendmail_path); @@ -587,10 +613,10 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co signal(SIGCHLD, sig_handler); } #endif - MAIL_RET(0); + MAIL_RET(false); } - MAIL_RET(1); /* never reached */ + MAIL_RET(true); /* never reached */ } /* }}} */ diff --git a/ext/standard/md5.h b/ext/standard/md5.h index 0003a934be62d..c488b5c534e36 100644 --- a/ext/standard/md5.h +++ b/ext/standard/md5.h @@ -21,8 +21,6 @@ PHPAPI void make_digest(char *md5str, const unsigned char *digest); PHPAPI void make_digest_ex(char *md5str, const unsigned char *digest, int len); -#include "ext/standard/basic_functions.h" - /* * This is an OpenSSL-compatible implementation of the RSA Data Security, * Inc. MD5 Message-Digest Algorithm (RFC 1321). diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 338f7831c6b87..c2e22240c48e9 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -20,41 +20,6 @@ PHP_MINFO_FUNCTION(mail); PHPAPI zend_string *php_mail_build_headers(HashTable *headers); -PHPAPI extern int php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); - -#define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ -do { \ - if (Z_TYPE_P(val) == IS_STRING) { \ - php_mail_build_headers_elem(&s, key, val); \ - } else if (Z_TYPE_P(val) == IS_ARRAY) { \ - if (zend_string_equals_literal_ci(key, target)) { \ - zend_type_error("Header \"%s\" must be of type string, array given", target); \ - break; \ - } \ - php_mail_build_headers_elems(&s, key, val); \ - } else { \ - zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ - } \ -} while(0) - - -#define PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val) \ -do { \ - if (Z_TYPE_P(val) == IS_STRING) { \ - php_mail_build_headers_elem(&s, key, val); \ - } else if (Z_TYPE_P(val) == IS_ARRAY) { \ - php_mail_build_headers_elems(&s, key, val); \ - } else { \ - zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \ - } \ -} while(0) - -typedef enum { - NO_HEADER_ERROR, - CONTAINS_LF_ONLY, - CONTAINS_CR_ONLY, - CONTAINS_CRLF, - CONTAINS_NULL -} php_mail_header_value_error_type; +PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); #endif /* PHP_MAIL_H */ diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 654ce5d0eddff..1be7d9b283772 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -58,10 +58,6 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); -PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive); -PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2); -PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2); - PHPAPI bool php_binary_string_shuffle(php_random_algo_with_state engine, char *str, zend_long len); #ifdef _REENTRANT diff --git a/ext/standard/sha1.h b/ext/standard/sha1.h index afec81272ca40..046d6db2cc475 100644 --- a/ext/standard/sha1.h +++ b/ext/standard/sha1.h @@ -17,8 +17,6 @@ #ifndef SHA1_H #define SHA1_H -#include "ext/standard/basic_functions.h" - /* SHA1 context. */ typedef struct { uint32_t state[5]; /* state (ABCD) */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 23c34df958b51..1082066dcec55 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -724,7 +724,7 @@ PHP_FUNCTION(wordwrap) } if (breakchar_len == 0) { - zend_argument_value_error(3, "cannot be empty"); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } @@ -930,7 +930,7 @@ PHP_FUNCTION(explode) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(delim) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1277,7 +1277,7 @@ PHP_FUNCTION(str_increment) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -1333,7 +1333,7 @@ PHP_FUNCTION(str_decrement) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(str) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (!zend_string_only_has_ascii_alphanumeric(str)) { @@ -5727,7 +5727,7 @@ PHP_FUNCTION(substr_count) ZEND_PARSE_PARAMETERS_END(); if (needle_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -5802,7 +5802,7 @@ PHP_FUNCTION(str_pad) } if (pad_str_len == 0) { - zend_argument_value_error(3, "must be a non-empty string"); + zend_argument_must_not_be_empty_error(3); RETURN_THROWS(); } diff --git a/ext/standard/tests/array/array_filter_variation9.phpt b/ext/standard/tests/array/array_filter_variation9.phpt index d9c1f9258f3a9..ff0dc7711718b 100644 --- a/ext/standard/tests/array/array_filter_variation9.phpt +++ b/ext/standard/tests/array/array_filter_variation9.phpt @@ -23,9 +23,9 @@ try { echo $e->getMessage(), "\n"; } -// using language construct 'exit' as 'callback' +// using language construct 'isset' as 'callback' try { - var_dump( array_filter($input, 'exit') ); + var_dump( array_filter($input, 'isset') ); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -63,5 +63,5 @@ array(6) { int(1000) } array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name -array_filter(): Argument #2 ($callback) must be a valid callback or null, function "exit" not found or invalid function name +array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name Done diff --git a/ext/standard/tests/array/array_map_variation16.phpt b/ext/standard/tests/array/array_map_variation16.phpt index b7c6690040162..7ee1f04967c5c 100644 --- a/ext/standard/tests/array/array_map_variation16.phpt +++ b/ext/standard/tests/array/array_map_variation16.phpt @@ -2,32 +2,24 @@ Test array_map() function : usage variations - failing built-in functions & language constructs --FILE-- getMessage(), "\n"; } @@ -36,21 +28,11 @@ for($count = 0; $count < count($callback_names); $count++) echo "Done"; ?> --EXPECT-- -*** Testing array_map() : non-permmited built-in functions *** --- Iteration 1 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "echo" not found or invalid function name --- Iteration 2 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "array" not found or invalid function name --- Iteration 3 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "empty" not found or invalid function name --- Iteration 4 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "eval" not found or invalid function name --- Iteration 5 -- -array_map(): Argument #1 ($callback) must be a valid callback or null, function "exit" not found or invalid function name --- Iteration 6 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "isset" not found or invalid function name --- Iteration 7 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "list" not found or invalid function name --- Iteration 8 -- array_map(): Argument #1 ($callback) must be a valid callback or null, function "print" not found or invalid function name Done diff --git a/ext/standard/tests/array/array_rand.phpt b/ext/standard/tests/array/array_rand.phpt index 03fb91eb53062..24f6966bb085e 100644 --- a/ext/standard/tests/array/array_rand.phpt +++ b/ext/standard/tests/array/array_rand.phpt @@ -38,8 +38,8 @@ var_dump(array_rand(array(1,2,3), 2)); ?> --EXPECTF-- -array_rand(): Argument #1 ($array) cannot be empty -array_rand(): Argument #1 ($array) cannot be empty +array_rand(): Argument #1 ($array) must not be empty +array_rand(): Argument #1 ($array) must not be empty array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) diff --git a/ext/standard/tests/dir/bug41693.phpt b/ext/standard/tests/dir/bug41693.phpt index 2c779bedcd41f..05722b9558d2d 100644 --- a/ext/standard/tests/dir/bug41693.phpt +++ b/ext/standard/tests/dir/bug41693.phpt @@ -11,4 +11,4 @@ try { ?> --EXPECT-- -scandir(): Argument #1 ($directory) cannot be empty +scandir(): Argument #1 ($directory) must not be empty diff --git a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt index d02eeb96477a9..c345ea30b84b4 100644 --- a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt +++ b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt @@ -36,8 +36,8 @@ Class [ class Directory ] { } - Properties [2] { - Property [ public readonly string $path ] - Property [ public readonly mixed $handle ] + Property [ public protected(set) readonly string $path ] + Property [ public protected(set) readonly mixed $handle ] } - Methods [3] { diff --git a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt index b6d801e9e701b..ee408b2c97582 100644 --- a/ext/standard/tests/file/file_get_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8-win32.phpt @@ -55,10 +55,10 @@ Warning: file_get_contents(1): Failed to open stream: No such file or directory bool(false) -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/file_get_contents_variation8.phpt b/ext/standard/tests/file/file_get_contents_variation8.phpt index ad23a13bb6b79..d6edef55db612 100644 --- a/ext/standard/tests/file/file_get_contents_variation8.phpt +++ b/ext/standard/tests/file/file_get_contents_variation8.phpt @@ -52,9 +52,9 @@ bool(false) Warning: file_get_contents(1): Failed to open stream: No such file or directory in %s on line %d bool(false) -- Iteration 2 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 3 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 4 -- Warning: file_get_contents( ): Failed to open stream: No such file or directory in %s on line %d diff --git a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt index dac2ba6d37ad3..b1625f030b06c 100644 --- a/ext/standard/tests/file/file_put_contents_variation8-win32.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8-win32.phpt @@ -55,10 +55,10 @@ foreach($names_arr as $key =>$value) { 9 bytes written to: '1' -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/file_put_contents_variation8.phpt b/ext/standard/tests/file/file_put_contents_variation8.phpt index 705efcade7bf3..81bbd25168801 100644 --- a/ext/standard/tests/file/file_put_contents_variation8.phpt +++ b/ext/standard/tests/file/file_put_contents_variation8.phpt @@ -64,9 +64,9 @@ rmdir($dir); -- Iteration 1 -- 9 bytes written to: '1' -- Iteration 2 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 3 -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Iteration 4 -- 9 bytes written to: ' ' -- Iteration 5 -- diff --git a/ext/standard/tests/file/readfile_error.phpt b/ext/standard/tests/file/readfile_error.phpt index 9e47e68fac3c9..ec2cf53946a6d 100644 --- a/ext/standard/tests/file/readfile_error.phpt +++ b/ext/standard/tests/file/readfile_error.phpt @@ -29,8 +29,8 @@ echo "Done\n"; *** Test readfile(): error conditions *** -- Testing readfile() with invalid arguments -- -Path cannot be empty -Path cannot be empty +Path must not be empty +Path must not be empty -- Testing readfile() with non-existent file -- diff --git a/ext/standard/tests/file/readfile_variation10-win32.phpt b/ext/standard/tests/file/readfile_variation10-win32.phpt index 325e47224dccb..2ec770b4101c7 100644 --- a/ext/standard/tests/file/readfile_variation10-win32.phpt +++ b/ext/standard/tests/file/readfile_variation10-win32.phpt @@ -51,10 +51,10 @@ Warning: readfile(-1): Failed to open stream: No such file or directory in %s on Warning: readfile(1): Failed to open stream: No such file or directory in %s on line %d -- Filename: FALSE -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: "" -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- Filename: " " -- diff --git a/ext/standard/tests/file/readfile_variation10.phpt b/ext/standard/tests/file/readfile_variation10.phpt index 5afc5622ed166..d2875215e5f7b 100644 --- a/ext/standard/tests/file/readfile_variation10.phpt +++ b/ext/standard/tests/file/readfile_variation10.phpt @@ -49,9 +49,9 @@ Warning: readfile(-1): Failed to open stream: %s in %s on line %d Warning: readfile(1): Failed to open stream: %s in %s on line %d -- testing '' -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- testing '' -- -ValueError: Path cannot be empty +ValueError: Path must not be empty -- testing ' ' -- Warning: readfile( ): Failed to open stream: %s in %s on line %d diff --git a/ext/standard/tests/file/rename_variation12-win32.phpt b/ext/standard/tests/file/rename_variation12-win32.phpt index 7ecaed35d7dc7..527a8865c331e 100644 --- a/ext/standard/tests/file/rename_variation12-win32.phpt +++ b/ext/standard/tests/file/rename_variation12-win32.phpt @@ -11,8 +11,8 @@ if (substr(PHP_OS, 0, 3) != 'WIN') die('skip.. for Windows'); /* Creating unique files in various dirs by passing relative paths to $dir arg */ echo "*** Testing rename() with absolute and relative paths ***\n"; -$mainDir = "renameVar11"; -$subDir = "renameVar11Sub"; +$mainDir = "renameVar12"; +$subDir = "renameVar12Sub"; $absMainDir = __DIR__."/".$mainDir; mkdir($absMainDir); $absSubDir = $absMainDir."/".$subDir; @@ -83,12 +83,12 @@ bool(true) -- Iteration 5 -- -Warning: rename(%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/renameMe.tmp,%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/renameMe.tmp,%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d bool(false) -- Iteration 6 -- -Warning: rename(%s/renameVar11/renameVar11Sub/BADDIR/renameMe.tmp,%s/renameVar11/renameVar11Sub/BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/BADDIR/renameMe.tmp,%s/renameVar12/renameVar12Sub/BADDIR/IwasRenamed.tmp): The system cannot find the path specified (code: 3) in %s on line %d bool(false) -- Iteration 7 -- diff --git a/ext/standard/tests/file/rename_variation12.phpt b/ext/standard/tests/file/rename_variation12.phpt index b38aab7ed1d0b..8675b17aab5c0 100644 --- a/ext/standard/tests/file/rename_variation12.phpt +++ b/ext/standard/tests/file/rename_variation12.phpt @@ -11,8 +11,8 @@ if (substr(PHP_OS, 0, 3) == 'WIN') die('skip.. not for Windows'); /* Creating unique files in various dirs by passing relative paths to $dir arg */ echo "*** Testing rename() with absolute and relative paths ***\n"; -$mainDir = "renameVar11"; -$subDir = "renameVar11Sub"; +$mainDir = "renameVar12"; +$subDir = "renameVar12Sub"; $absMainDir = __DIR__."/".$mainDir; mkdir($absMainDir); $absSubDir = $absMainDir."/".$subDir; @@ -83,12 +83,12 @@ bool(true) -- Iteration 5 -- -Warning: rename(%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/renameMe.tmp,%s/renameVar11/renameVar11Sub/..///renameVar11Sub//..//../renameVar11Sub/IwasRenamed.tmp): %s in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/renameMe.tmp,%s/renameVar12/renameVar12Sub/..///renameVar12Sub//..//../renameVar12Sub/IwasRenamed.tmp): %s in %s on line %d bool(false) -- Iteration 6 -- -Warning: rename(%s/renameVar11/renameVar11Sub/BADDIR/renameMe.tmp,%s/renameVar11/renameVar11Sub/BADDIR/IwasRenamed.tmp): %s in %s on line %d +Warning: rename(%s/renameVar12/renameVar12Sub/BADDIR/renameMe.tmp,%s/renameVar12/renameVar12Sub/BADDIR/IwasRenamed.tmp): %s in %s on line %d bool(false) -- Iteration 7 -- diff --git a/ext/standard/tests/general_functions/bug44394_2.phpt b/ext/standard/tests/general_functions/bug44394_2.phpt index 356291318c8ba..c6107def029da 100644 --- a/ext/standard/tests/general_functions/bug44394_2.phpt +++ b/ext/standard/tests/general_functions/bug44394_2.phpt @@ -5,12 +5,12 @@ session --INI-- session.name=PHPSESSID session.use_only_cookies=0 +session.use_trans_sid=1 session.trans_sid_tags="a=href,area=href,frame=src,form=" url_rewriter.tags="a=href,area=href,frame=src,form=" --FILE-- --EXPECTF-- +Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is deprecated in Unknown on line 0 + +Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 asd diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt index 007772f408a3f..62ef24429b211 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic1.phpt @@ -74,7 +74,10 @@ Test use_trans_sid=1
---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 Without session @@ -105,6 +108,8 @@ Test use_trans_sid=0
+ +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt index 3aba659c34387..3f133669ad57a 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic2.phpt @@ -74,7 +74,8 @@ Test use_trans_sid=1
---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 5 Without session @@ -105,6 +106,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt index 92cd59e4f458e..7a407f9e1caa6 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic3.phpt @@ -73,7 +73,8 @@ Test use_trans_sid=1 ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 5 Without session @@ -104,6 +105,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 49 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt b/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt index 7dc1ecaa4b7d4..ae7f7a979e672 100644 --- a/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt +++ b/ext/standard/tests/general_functions/output_add_rewrite_var_basic4.phpt @@ -73,7 +73,7 @@ Test use_trans_sid=1 ---EXPECT-- +--EXPECTF-- Without session @@ -104,6 +104,8 @@ Test use_trans_sid=0 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 49 Test use_trans_sid=1 diff --git a/ext/standard/tests/general_functions/php_uname_error.phpt b/ext/standard/tests/general_functions/php_uname_error.phpt index 2f65ed587d36c..694ec19fb6b39 100644 --- a/ext/standard/tests/general_functions/php_uname_error.phpt +++ b/ext/standard/tests/general_functions/php_uname_error.phpt @@ -1,17 +1,26 @@ --TEST-- -Test php_uname() function - error conditions - pass function incorrect arguments +php_uname(): Invalid arguments --FILE-- getMessage(), PHP_EOL; +} +try { + var_dump(php_uname('test')); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + var_dump(php_uname('z')); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- -*** Testing php_uname() - error test - --- Testing php_uname() function with invalid mode -- -bool(true) +ValueError: php_uname(): Argument #1 ($mode) must be a single character +ValueError: php_uname(): Argument #1 ($mode) must be a single character +ValueError: php_uname(): Argument #1 ($mode) must be one of "a", "m", "n", "r", "s", or "v" diff --git a/ext/standard/tests/general_functions/url_rewriting_basic1.phpt b/ext/standard/tests/general_functions/url_rewriting_basic1.phpt index 4c1f6784dcb2c..0bc3a64573ce2 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic1.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic1.phpt @@ -76,7 +76,8 @@ session_start(); echo "\nURL-Rewriting with transparent session id support without output_add_rewrite_var()\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 URL-Rewriting with output_add_rewrite_var() without transparent session id support @@ -115,6 +116,10 @@ URL-Rewriting with output_add_rewrite_var() without transparent session id suppo
+Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 60 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 63 + URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/tests/general_functions/url_rewriting_basic2.phpt b/ext/standard/tests/general_functions/url_rewriting_basic2.phpt index 635383a33c913..bed24209eee7c 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic2.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic2.phpt @@ -87,7 +87,8 @@ output_add_rewrite_var('', ''); echo "\nURL-Rewriting with output_add_rewrite_var() without transparent session id support\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 URL-Rewriting with output_add_rewrite_var() without transparent session id support @@ -126,6 +127,10 @@ URL-Rewriting with output_add_rewrite_var() without transparent session id suppo
+Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 61 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 64 + URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/tests/general_functions/url_rewriting_basic3.phpt b/ext/standard/tests/general_functions/url_rewriting_basic3.phpt index edf41ba4fe200..7a2eed0823d9f 100644 --- a/ext/standard/tests/general_functions/url_rewriting_basic3.phpt +++ b/ext/standard/tests/general_functions/url_rewriting_basic3.phpt @@ -80,7 +80,12 @@ output_add_rewrite_var('', ''); echo "\nURL-Rewriting with transparent session id support without output_add_rewrite_var()\n"; echo $testTags; ---EXPECT-- +--EXPECTF-- +Deprecated: ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated in %s on line 44 + +Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 47 + +Deprecated: ini_set(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 50 URL-Rewriting with transparent session id support without output_add_rewrite_var() diff --git a/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt b/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt index bd4e3f4ff2afa..087b11841cabc 100644 --- a/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt +++ b/ext/standard/tests/http/request_parse_body/unsupported_content_type.phpt @@ -20,7 +20,7 @@ var_dump($_POST, $_FILES); ?> --EXPECT-- -InvalidArgumentException: Content-Type "application/json" is not supported +RequestParseBodyException: Content-Type "application/json" is not supported array(0) { } array(0) { diff --git a/ext/standard/tests/network/bug69523.phpt b/ext/standard/tests/network/bug69523.phpt index 60f3643044c60..5552ca2afdf82 100644 --- a/ext/standard/tests/network/bug69523.phpt +++ b/ext/standard/tests/network/bug69523.phpt @@ -9,4 +9,4 @@ try { } ?> --EXPECT-- -setcookie(): Argument #1 ($name) cannot be empty +setcookie(): Argument #1 ($name) must not be empty diff --git a/ext/standard/tests/network/dns_check_record_error_conditions.phpt b/ext/standard/tests/network/dns_check_record_error_conditions.phpt index dae0bfb3750c6..de33d74bce63d 100644 --- a/ext/standard/tests/network/dns_check_record_error_conditions.phpt +++ b/ext/standard/tests/network/dns_check_record_error_conditions.phpt @@ -15,5 +15,5 @@ try { } ?> --EXPECT-- -dns_check_record(): Argument #1 ($hostname) cannot be empty +dns_check_record(): Argument #1 ($hostname) must not be empty dns_check_record(): Argument #2 ($type) must be a valid DNS record type diff --git a/ext/standard/tests/network/setcookie_error.phpt b/ext/standard/tests/network/setcookie_error.phpt index 8c071199f8625..90177c714e583 100644 --- a/ext/standard/tests/network/setcookie_error.phpt +++ b/ext/standard/tests/network/setcookie_error.phpt @@ -50,7 +50,7 @@ var_dump(headers_list()); --EXPECTHEADERS-- --EXPECTF-- -setcookie(): Argument #1 ($name) cannot be empty +setcookie(): Argument #1 ($name) must not be empty setcookie(): Argument #1 ($name) cannot contain "=", ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "domain" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" diff --git a/ext/standard/tests/network/setrawcookie_error.phpt b/ext/standard/tests/network/setrawcookie_error.phpt index eba7b04bb03a5..9aae95673df09 100644 --- a/ext/standard/tests/network/setrawcookie_error.phpt +++ b/ext/standard/tests/network/setrawcookie_error.phpt @@ -50,7 +50,7 @@ var_dump(headers_list()); --EXPECTHEADERS-- --EXPECTF-- -setrawcookie(): Argument #1 ($name) cannot be empty +setrawcookie(): Argument #1 ($name) must not be empty setrawcookie(): Argument #1 ($name) cannot contain "=", ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setrawcookie(): Argument #2 ($value) cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setrawcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt new file mode 100644 index 0000000000000..a13334baacaa1 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_array.phpt @@ -0,0 +1,61 @@ +--TEST-- +Test unserialize() with array allowed_classes and nonsensical values +--FILE-- + [null]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [false]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [true]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [42]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [15.2]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [[]]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [STDERR]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [new stdClass]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, null given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, false given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, true given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, int given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, float given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, array given +TypeError: unserialize(): Option "allowed_classes" must be an array of class names, resource given +Error: Object of class stdClass could not be converted to string diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt new file mode 100644 index 0000000000000..74997939817d8 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_class_names.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test unserialize() with array allowed_classes and nonsensical class names +--FILE-- + [""]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["245blerg"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => [" whitespace "]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["name\nwith whitespace"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ['$dollars']]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +try { + unserialize($s, ["allowed_classes" => ["have\0nul_byte"]]); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, " whitespace " given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "name +with whitespace" given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "$dollars" given +ValueError: unserialize(): Option "allowed_classes" must be an array of class names, "have" given diff --git a/ext/standard/tests/serialize/unserialize_error_001.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_value.phpt similarity index 100% rename from ext/standard/tests/serialize/unserialize_error_001.phpt rename to ext/standard/tests/serialize/unserialize_allowed_classes_option_invalid_value.phpt diff --git a/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt b/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt new file mode 100644 index 0000000000000..5868cf9e923f0 --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_allowed_classes_option_stringable_value.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test unserialize() with Stringable object in allowed_classes +--FILE-- + [$o]])); +?> +--EXPECT-- +array(3) { + [0]=> + object(foo)#3 (1) { + ["x"]=> + string(3) "bar" + } + [1]=> + int(2) + [2]=> + string(1) "3" +} diff --git a/ext/standard/tests/strings/explode.phpt b/ext/standard/tests/strings/explode.phpt index 07ab4488da5f7..ea467a2d55043 100644 --- a/ext/standard/tests/strings/explode.phpt +++ b/ext/standard/tests/strings/explode.phpt @@ -62,9 +62,9 @@ array ( 4 => 'd', ) d6bee42a771449205344c0938ad4f035 -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty array(1) { [0]=> string(0) "" @@ -79,7 +79,7 @@ array(1) { [0]=> string(0) "" } -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty array(1) { [0]=> string(3) "acb" diff --git a/ext/standard/tests/strings/explode1.phpt b/ext/standard/tests/strings/explode1.phpt index a15290f29fce5..876b159821cdc 100644 --- a/ext/standard/tests/strings/explode1.phpt +++ b/ext/standard/tests/strings/explode1.phpt @@ -91,15 +91,15 @@ var_dump( explode("b", $obj) ); --EXPECT-- *** Testing explode() for basic operations *** -- Iteration 1 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 2 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 3 -- array(1) { [0]=> @@ -201,10 +201,10 @@ array(2) { string(56) "234NULL23abcd00000TRUEFALSE-11.234444true-11.24%PHP%ZEND" } -- Iteration 7 -- -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty -explode(): Argument #1 ($separator) cannot be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty +explode(): Argument #1 ($separator) must not be empty -- Iteration 8 -- array(2) { [0]=> diff --git a/ext/standard/tests/strings/md5_file.phpt b/ext/standard/tests/strings/md5_file.phpt index 7acb81c3a412b..1eb9b2654ada1 100644 --- a/ext/standard/tests/strings/md5_file.phpt +++ b/ext/standard/tests/strings/md5_file.phpt @@ -64,7 +64,7 @@ echo "\nDone"; ?> --EXPECTF-- *** Testing for error conditions *** -Path cannot be empty +Path must not be empty Warning: md5_file(aZrq16u): Failed to open stream: No such file or directory in %s on line %d bool(false) diff --git a/ext/standard/tests/strings/sha1_file.phpt b/ext/standard/tests/strings/sha1_file.phpt index 62419d708f220..60d6ad808f8ca 100644 --- a/ext/standard/tests/strings/sha1_file.phpt +++ b/ext/standard/tests/strings/sha1_file.phpt @@ -74,7 +74,7 @@ unlink("EmptyFileSHA1.txt"); *** Testing for error conditions *** -- No filename -- -Path cannot be empty +Path must not be empty -- invalid filename -- @@ -89,7 +89,7 @@ bool(false) -- NULL as filename -- Deprecated: sha1_file(): Passing null to parameter #1 ($filename) of type string is deprecated in %s on line %d -Path cannot be empty +Path must not be empty -- Hexadecimal Output for Empty file as Argument -- string(40) "da39a3ee5e6b4b0d3255bfef95601890afd80709" diff --git a/ext/standard/tests/strings/str_decrement_errors.phpt b/ext/standard/tests/strings/str_decrement_errors.phpt index 6f7f61e6b7b9a..3186d24b81ed0 100644 --- a/ext/standard/tests/strings/str_decrement_errors.phpt +++ b/ext/standard/tests/strings/str_decrement_errors.phpt @@ -37,7 +37,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_decrement(): Argument #1 ($string) cannot be empty +str_decrement(): Argument #1 ($string) must not be empty str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters diff --git a/ext/standard/tests/strings/str_decrement_underflow.phpt b/ext/standard/tests/strings/str_decrement_underflow.phpt index ea60f0069342c..0521497713a17 100644 --- a/ext/standard/tests/strings/str_decrement_underflow.phpt +++ b/ext/standard/tests/strings/str_decrement_underflow.phpt @@ -23,7 +23,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_decrement(): Argument #1 ($string) cannot be empty +str_decrement(): Argument #1 ($string) must not be empty str_decrement(): Argument #1 ($string) "0" is out of decrement range str_decrement(): Argument #1 ($string) "a" is out of decrement range str_decrement(): Argument #1 ($string) "A" is out of decrement range diff --git a/ext/standard/tests/strings/str_increment_errors.phpt b/ext/standard/tests/strings/str_increment_errors.phpt index 41e4ac10e1078..e06d7e4bba861 100644 --- a/ext/standard/tests/strings/str_increment_errors.phpt +++ b/ext/standard/tests/strings/str_increment_errors.phpt @@ -37,7 +37,7 @@ foreach ($strings as $s) { ?> --EXPECT-- -str_increment(): Argument #1 ($string) cannot be empty +str_increment(): Argument #1 ($string) must not be empty str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters diff --git a/ext/standard/tests/strings/str_pad.phpt b/ext/standard/tests/strings/str_pad.phpt index 278db455f8d55..c7b11e4ac0ce5 100644 --- a/ext/standard/tests/strings/str_pad.phpt +++ b/ext/standard/tests/strings/str_pad.phpt @@ -302,5 +302,5 @@ string(16) "\t\variation\t\t" #### error conditions #### --- empty padding string --- -str_pad(): Argument #3 ($pad_string) must be a non-empty string +str_pad(): Argument #3 ($pad_string) must not be empty str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH diff --git a/ext/standard/tests/strings/substr_count_basic.phpt b/ext/standard/tests/strings/substr_count_basic.phpt index 3b871ac0da3d8..efb5806d1621b 100644 --- a/ext/standard/tests/strings/substr_count_basic.phpt +++ b/ext/standard/tests/strings/substr_count_basic.phpt @@ -34,8 +34,8 @@ var_dump(substr_count($a, "bca", -200, -50)); ?> --EXPECT-- ***Testing basic operations *** -substr_count(): Argument #2 ($needle) cannot be empty -substr_count(): Argument #2 ($needle) cannot be empty +substr_count(): Argument #2 ($needle) must not be empty +substr_count(): Argument #2 ($needle) must not be empty int(0) int(0) int(0) diff --git a/ext/standard/tests/strings/wordwrap.phpt b/ext/standard/tests/strings/wordwrap.phpt index ff1d1fcbba593..efa12bef18dd6 100644 --- a/ext/standard/tests/strings/wordwrap.phpt +++ b/ext/standard/tests/strings/wordwrap.phpt @@ -53,4 +53,4 @@ bool(true) bool(true) bool(true) bool(true) -wordwrap(): Argument #3 ($break) cannot be empty +wordwrap(): Argument #3 ($break) must not be empty diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 305be39d8780f..1ce7521d7fab1 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -102,6 +102,9 @@ static zend_result php_ini_on_update_tags(zend_ini_entry *entry, zend_string *ne static PHP_INI_MH(OnUpdateSessionTags) { + if (!zend_string_starts_with_literal(new_value, "a=href,area=href,frame=src,form=")) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.trans_sid_tags INI setting is deprecated"); + } return php_ini_on_update_tags(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, /* is_session */ true); } @@ -152,6 +155,9 @@ static zend_result php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *n static PHP_INI_MH(OnUpdateSessionHosts) { + if (ZSTR_LEN(new_value) != 0) { + php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.trans_sid_hosts INI setting is deprecated"); + } return php_ini_on_update_hosts(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage, /* is_session */ true); } diff --git a/ext/standard/user_filters_arginfo.h b/ext/standard/user_filters_arginfo.h index a40a00f7ee476..f960a3a904e85 100644 --- a/ext/standard/user_filters_arginfo.h +++ b/ext/standard/user_filters_arginfo.h @@ -44,7 +44,7 @@ static zend_class_entry *register_class_php_user_filter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "php_user_filter", class_php_user_filter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_filtername_default_value; ZVAL_EMPTY_STRING(&property_filtername_default_value); @@ -72,8 +72,7 @@ static zend_class_entry *register_class_StreamBucket(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "StreamBucket", class_StreamBucket_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_bucket_default_value; ZVAL_NULL(&property_bucket_default_value); diff --git a/ext/standard/var.c b/ext/standard/var.c index dd2bd86d91ee8..0d08a0a338309 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -23,11 +23,13 @@ #include "php.h" #include "php_string.h" #include "php_var.h" +#include "zend_lazy_objects.h" #include "zend_smart_str.h" #include "basic_functions.h" #include "php_incomplete_class.h" #include "zend_enum.h" #include "zend_exceptions.h" +#include "zend_types.h" /* }}} */ struct php_serialize_data { @@ -86,6 +88,18 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze } /* }}} */ +static const char *php_var_dump_object_prefix(zend_object *obj) { + if (EXPECTED(!zend_object_is_lazy(obj))) { + return ""; + } + + if (zend_object_is_lazy_proxy(obj)) { + return "lazy proxy "; + } + + return "lazy ghost "; +} + PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ { HashTable *myht; @@ -163,7 +177,9 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("%sobject(%s)#%d (%d) {\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); + + php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); zend_string_release_ex(class_name, 0); if (myht) { @@ -360,7 +376,9 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */ myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - php_printf("object(%s)#%d (%d) refcount(%u){\n", ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc)); + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); + + php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc)); zend_string_release_ex(class_name, 0); if (myht) { ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) { @@ -1206,7 +1224,8 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ if (Z_OBJ_P(struc)->properties == NULL && Z_OBJ_HT_P(struc)->get_properties_for == NULL - && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties) { + && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties + && !zend_object_is_lazy(Z_OBJ_P(struc))) { /* Optimized version without rebulding properties HashTable */ zend_object *obj = Z_OBJ_P(struc); zend_class_entry *ce = obj->ce; @@ -1370,25 +1389,34 @@ PHPAPI void php_unserialize_with_options(zval *return_value, const char *buf, co goto cleanup; } - if(classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) { + if (classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) { ALLOC_HASHTABLE(class_hash); zend_hash_init(class_hash, (Z_TYPE_P(classes) == IS_ARRAY)?zend_hash_num_elements(Z_ARRVAL_P(classes)):0, NULL, NULL, 0); } - if(class_hash && Z_TYPE_P(classes) == IS_ARRAY) { + if (class_hash && Z_TYPE_P(classes) == IS_ARRAY) { zval *entry; - zend_string *lcname; ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(classes), entry) { - convert_to_string(entry); - lcname = zend_string_tolower(Z_STR_P(entry)); + ZVAL_DEREF(entry); + if (UNEXPECTED(Z_TYPE_P(entry) != IS_STRING && Z_TYPE_P(entry) != IS_OBJECT)) { + zend_type_error("%s(): Option \"allowed_classes\" must be an array of class names, %s given", + function_name, zend_zval_value_name(entry)); + goto cleanup; + } + zend_string *name = zval_try_get_string(entry); + if (UNEXPECTED(name == NULL)) { + goto cleanup; + } + if (UNEXPECTED(!zend_is_valid_class_name(name))) { + zend_value_error("%s(): Option \"allowed_classes\" must be an array of class names, \"%s\" given", function_name, ZSTR_VAL(name)); + zend_string_release_ex(name, false); + goto cleanup; + } + zend_string *lcname = zend_string_tolower(name); zend_hash_add_empty_element(class_hash, lcname); - zend_string_release_ex(lcname, 0); + zend_string_release_ex(name, false); + zend_string_release_ex(lcname, false); } ZEND_HASH_FOREACH_END(); - - /* Exception during string conversion. */ - if (EG(exception)) { - goto cleanup; - } } php_var_unserialize_set_allowed_classes(var_hash, class_hash); diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 78d102eefda6c..cbd457e16fdb1 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -561,7 +561,7 @@ static int is_property_visibility_changed(zend_class_entry *ce, zval *key) return 1; } else { php_error_docref(NULL, E_WARNING, - "Cannot unserialize value for hooked property %s::$%s", + "Cannot unserialize value for virtual property %s::$%s", ZSTR_VAL(existing_propinfo->ce->name), Z_STRVAL_P(key)); zval_ptr_dtor_str(key); return -1; diff --git a/ext/sysvmsg/sysvmsg_arginfo.h b/ext/sysvmsg/sysvmsg_arginfo.h index 34eca90d6feb8..a5e84383e16ca 100644 --- a/ext/sysvmsg/sysvmsg_arginfo.h +++ b/ext/sysvmsg/sysvmsg_arginfo.h @@ -80,8 +80,7 @@ static zend_class_entry *register_class_SysvMessageQueue(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvMessageQueue", class_SysvMessageQueue_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sysvsem/sysvsem_arginfo.h b/ext/sysvsem/sysvsem_arginfo.h index 4411a7319caab..d35ab67de2c74 100644 --- a/ext/sysvsem/sysvsem_arginfo.h +++ b/ext/sysvsem/sysvsem_arginfo.h @@ -41,8 +41,7 @@ static zend_class_entry *register_class_SysvSemaphore(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvSemaphore", class_SysvSemaphore_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sysvshm/sysvshm_arginfo.h b/ext/sysvshm/sysvshm_arginfo.h index 05715b2e79ffb..2c4b401a439c6 100644 --- a/ext/sysvshm/sysvshm_arginfo.h +++ b/ext/sysvshm/sysvshm_arginfo.h @@ -59,8 +59,7 @@ static zend_class_entry *register_class_SysvSharedMemory(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "SysvSharedMemory", class_SysvSharedMemory_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/sysvshm/tests/001.phpt b/ext/sysvshm/tests/001.phpt index 00483c2a3cb04..10b258da2d0be 100644 --- a/ext/sysvshm/tests/001.phpt +++ b/ext/sysvshm/tests/001.phpt @@ -35,7 +35,7 @@ var_dump(ftok(__FILE__,"q")); echo "Done\n"; ?> --EXPECTF-- -ftok(): Argument #1 ($filename) cannot be empty +ftok(): Argument #1 ($filename) must not be empty ftok(): Argument #2 ($project_id) must be a single character ftok(): Argument #2 ($project_id) must be a single character diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4 index 9c0fd05ff36fd..8c3ceb38dafd7 100644 --- a/ext/tidy/config.m4 +++ b/ext/tidy/config.m4 @@ -4,40 +4,35 @@ PHP_ARG_WITH([tidy], [Include TIDY support])]) if test "$PHP_TIDY" != "no"; then - - if test "$PHP_TIDY" != "yes"; then - TIDY_SEARCH_DIRS=$PHP_TIDY - else - TIDY_SEARCH_DIRS="/usr/local /usr" - fi + AS_VAR_IF([PHP_TIDY], [yes], + [TIDY_SEARCH_DIRS="/usr/local /usr"], + [TIDY_SEARCH_DIRS=$PHP_TIDY]) for i in $TIDY_SEARCH_DIRS; do for j in tidy tidyp; do - if test -f $i/include/$j/$j.h; then - TIDY_DIR=$i - TIDY_INCDIR=$i/include/$j - TIDY_LIB_NAME=$j - break - elif test -f $i/include/$j.h; then - TIDY_DIR=$i - TIDY_INCDIR=$i/include - TIDY_LIB_NAME=$j - break - fi + AS_IF([test -f $i/include/$j/$j.h], [ + TIDY_DIR=$i + TIDY_INCDIR=$i/include/$j + TIDY_LIB_NAME=$j + break 2 + ], + [test -f $i/include/$j.h], [ + TIDY_DIR=$i + TIDY_INCDIR=$i/include + TIDY_LIB_NAME=$j + break 2 + ]) done done - if test -z "$TIDY_DIR"; then - AC_MSG_ERROR([Cannot find libtidy]) - else - dnl Check for tidybuffio.h (as opposed to simply buffio.h) which indicates - dnl that we are building against tidy-html5 and not the legacy htmltidy. The - dnl two are compatible, except for with regard to this header file. - if test -f "$TIDY_INCDIR/tidybuffio.h"; then - AC_DEFINE([HAVE_TIDYBUFFIO_H], [1], - [Define to 1 if you have the header file.]) - fi - fi + AS_VAR_IF([TIDY_DIR],, [AC_MSG_ERROR([Cannot find libtidy])]) + + dnl Check for tidybuffio.h (as opposed to simply buffio.h) which indicates + dnl that we are building against tidy-html5 and not the legacy htmltidy. The + dnl two are compatible, except for with regard to this header file. + AS_IF([test -f "$TIDY_INCDIR/tidybuffio.h"], + [AC_DEFINE([HAVE_TIDYBUFFIO_H], [1], + [Define to 1 if you have the header file.])]) TIDY_LIBDIR=$TIDY_DIR/$PHP_LIBDIR AS_VAR_IF([TIDY_LIB_NAME], [tidyp], @@ -51,20 +46,28 @@ if test "$PHP_TIDY" != "no"; then [Define to 1 if Tidy library has the 'tidyOptGetDoc' function.])], [PHP_CHECK_LIBRARY([tidy5], [tidyOptGetDoc], [TIDY_LIB_NAME=tidy5 - AC_DEFINE([HAVE_TIDYOPTGETDOC], [1])])]) + AC_DEFINE([HAVE_TIDYOPTGETDOC], [1])], + [], + [-L$TIDY_LIBDIR])], + [-L$TIDY_LIBDIR]) PHP_CHECK_LIBRARY([$TIDY_LIB_NAME], [tidyReleaseDate], [AC_DEFINE([HAVE_TIDYRELEASEDATE], [1], - [Define to 1 if Tidy library has the 'tidyReleaseDate' function.])]) + [Define to 1 if Tidy library has the 'tidyReleaseDate' function.])], + [], + [-L$TIDY_LIBDIR]) PHP_ADD_LIBRARY_WITH_PATH([$TIDY_LIB_NAME], [$TIDY_LIBDIR], [TIDY_SHARED_LIBADD]) PHP_ADD_INCLUDE([$TIDY_INCDIR]) - dnl Add -Wno-ignored-qualifiers as this is an issue upstream - TIDY_COMPILER_FLAGS="$TIDY_CFLAGS -Wno-ignored-qualifiers -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" - PHP_NEW_EXTENSION([tidy], [tidy.c], [$ext_shared],, [$TIDY_COMPILER_FLAGS]) + dnl Add -Wno-ignored-qualifiers as this is an issue upstream. Fixed in + dnl tidy-html5 5.7.20: https://github.com/htacg/tidy-html5/issues/866 + PHP_NEW_EXTENSION([tidy], + [tidy.c], + [$ext_shared],, + [-Wno-ignored-qualifiers -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_SUBST([TIDY_SHARED_LIBADD]) AC_DEFINE([HAVE_TIDY], [1], [Define to 1 if the PHP extension 'tidy' is available.]) diff --git a/ext/tidy/tests/019.phpt b/ext/tidy/tests/019.phpt index 444ecc155a45c..9bf6cf6349a3f 100644 --- a/ext/tidy/tests/019.phpt +++ b/ext/tidy/tests/019.phpt @@ -37,6 +37,6 @@ Warning: tidy_repair_string(): Could not load the Tidy configuration file "" in Warning: tidy_repair_string(): Could not load the Tidy configuration file "1" in %s on line %d Warning: tidy_repair_string(): Could not set encoding "1" in %s on line %d -Path cannot be empty -Path cannot be empty +Path must not be empty +Path must not be empty Done diff --git a/ext/tidy/tidy_arginfo.h b/ext/tidy/tidy_arginfo.h index 99cc28b68099d..56c0b78c32e47 100644 --- a/ext/tidy/tidy_arginfo.h +++ b/ext/tidy/tidy_arginfo.h @@ -526,7 +526,7 @@ static zend_class_entry *register_class_tidy(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "tidy", class_tidy_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_errorBuffer_default_value; ZVAL_NULL(&property_errorBuffer_default_value); @@ -548,8 +548,7 @@ static zend_class_entry *register_class_tidyNode(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "tidyNode", class_tidyNode_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); diff --git a/ext/tokenizer/tokenizer_arginfo.h b/ext/tokenizer/tokenizer_arginfo.h index e7ab3e31cf39c..04b7406596130 100644 --- a/ext/tokenizer/tokenizer_arginfo.h +++ b/ext/tokenizer/tokenizer_arginfo.h @@ -67,7 +67,7 @@ static zend_class_entry *register_class_PhpToken(zend_class_entry *class_entry_S zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "PhpToken", class_PhpToken_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Stringable); zval property_id_default_value; diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index cdaaddecd7bfa..a046ab50e1498 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -92,6 +92,9 @@ char *get_token_type_name(int token_type) case T_PRIVATE: return "T_PRIVATE"; case T_PROTECTED: return "T_PROTECTED"; case T_PUBLIC: return "T_PUBLIC"; + case T_PRIVATE_SET: return "T_PRIVATE_SET"; + case T_PROTECTED_SET: return "T_PROTECTED_SET"; + case T_PUBLIC_SET: return "T_PUBLIC_SET"; case T_READONLY: return "T_READONLY"; case T_VAR: return "T_VAR"; case T_UNSET: return "T_UNSET"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index 81e4e92626f37..45f3c89f2de3a 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -337,6 +337,21 @@ * @cvalue T_PUBLIC */ const T_PUBLIC = UNKNOWN; +/** + * @var int + * @cvalue T_PRIVATE_SET + */ +const T_PRIVATE_SET = UNKNOWN; +/** + * @var int + * @cvalue T_PROTECTED_SET + */ +const T_PROTECTED_SET = UNKNOWN; +/** + * @var int + * @cvalue T_PUBLIC_SET + */ +const T_PUBLIC_SET = UNKNOWN; /** * @var int * @cvalue T_READONLY diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 0fc1f219619dd..61f6ac1ec3659 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b7a13b3b242bd535f62a7d819eb0df751efb54ed */ + * Stub hash: d917cab61a2b436a16d2227cdb438add45e42d69 */ static void register_tokenizer_data_symbols(int module_number) { @@ -70,6 +70,9 @@ static void register_tokenizer_data_symbols(int module_number) REGISTER_LONG_CONSTANT("T_PRIVATE", T_PRIVATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PROTECTED", T_PROTECTED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PUBLIC", T_PUBLIC, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PRIVATE_SET", T_PRIVATE_SET, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PROTECTED_SET", T_PROTECTED_SET, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_PUBLIC_SET", T_PUBLIC_SET, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_READONLY", T_READONLY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_VAR", T_VAR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_UNSET", T_UNSET, CONST_PERSISTENT); diff --git a/ext/xml/xml_arginfo.h b/ext/xml/xml_arginfo.h index 7b31981ed60da..824ae0bfedfe3 100644 --- a/ext/xml/xml_arginfo.h +++ b/ext/xml/xml_arginfo.h @@ -185,8 +185,7 @@ static zend_class_entry *register_class_XMLParser(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLParser", class_XMLParser_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index b5a4badd1381a..528fd8b351c61 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -382,7 +382,7 @@ static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_rea } if (!name_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -467,7 +467,7 @@ static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int t } if (source != NULL && !source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -574,12 +574,12 @@ PHP_METHOD(XMLReader, getAttributeNs) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -655,7 +655,7 @@ PHP_METHOD(XMLReader, moveToAttribute) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -715,12 +715,12 @@ PHP_METHOD(XMLReader, moveToAttributeNs) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (ns_uri_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -860,7 +860,7 @@ static void xml_reader_from_uri(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry * } if (!source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1027,7 +1027,7 @@ PHP_METHOD(XMLReader, setSchema) } if (source != NULL && !source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1132,7 +1132,7 @@ static void xml_reader_from_string(INTERNAL_FUNCTION_PARAMETERS, zend_class_entr } if (!source_len) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/xmlreader/php_xmlreader.stub.php b/ext/xmlreader/php_xmlreader.stub.php index c58ee2460ff02..d319037066046 100644 --- a/ext/xmlreader/php_xmlreader.stub.php +++ b/ext/xmlreader/php_xmlreader.stub.php @@ -99,32 +99,46 @@ class XMLReader public const int SUBST_ENTITIES = UNKNOWN; + /** @virtual */ public int $attributeCount; + /** @virtual */ public string $baseURI; + /** @virtual */ public int $depth; + /** @virtual */ public bool $hasAttributes; + /** @virtual */ public bool $hasValue; + /** @virtual */ public bool $isDefault; + /** @virtual */ public bool $isEmptyElement; + /** @virtual */ public string $localName; + /** @virtual */ public string $name; + /** @virtual */ public string $namespaceURI; + /** @virtual */ public int $nodeType; + /** @virtual */ public string $prefix; + /** @virtual */ public string $value; + /** @virtual */ public string $xmlLang; /** @tentative-return-type */ diff --git a/ext/xmlreader/php_xmlreader_arginfo.h b/ext/xmlreader/php_xmlreader_arginfo.h index a5a0c12cd2593..78e7c2dda44c2 100644 --- a/ext/xmlreader/php_xmlreader_arginfo.h +++ b/ext/xmlreader/php_xmlreader_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 551324d130f9755c4c61cebb5084953fb6f539c4 */ + * Stub hash: 80288a0f40eabc7802a928963386616ea31e448d */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_XMLReader_close, 0, 0, IS_TRUE, 0) ZEND_END_ARG_INFO() @@ -176,7 +176,7 @@ static zend_class_entry *register_class_XMLReader(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLReader", class_XMLReader_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval const_NONE_value; ZVAL_LONG(&const_NONE_value, XML_READER_TYPE_NONE); @@ -313,85 +313,85 @@ static zend_class_entry *register_class_XMLReader(void) zval property_attributeCount_default_value; ZVAL_UNDEF(&property_attributeCount_default_value); zend_string *property_attributeCount_name = zend_string_init("attributeCount", sizeof("attributeCount") - 1, 1); - zend_declare_typed_property(class_entry, property_attributeCount_name, &property_attributeCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_attributeCount_name, &property_attributeCount_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_attributeCount_name); zval property_baseURI_default_value; ZVAL_UNDEF(&property_baseURI_default_value); zend_string *property_baseURI_name = zend_string_init("baseURI", sizeof("baseURI") - 1, 1); - zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_baseURI_name, &property_baseURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_baseURI_name); zval property_depth_default_value; ZVAL_UNDEF(&property_depth_default_value); zend_string *property_depth_name = zend_string_init("depth", sizeof("depth") - 1, 1); - zend_declare_typed_property(class_entry, property_depth_name, &property_depth_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_depth_name, &property_depth_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_depth_name); zval property_hasAttributes_default_value; ZVAL_UNDEF(&property_hasAttributes_default_value); zend_string *property_hasAttributes_name = zend_string_init("hasAttributes", sizeof("hasAttributes") - 1, 1); - zend_declare_typed_property(class_entry, property_hasAttributes_name, &property_hasAttributes_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_hasAttributes_name, &property_hasAttributes_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_hasAttributes_name); zval property_hasValue_default_value; ZVAL_UNDEF(&property_hasValue_default_value); zend_string *property_hasValue_name = zend_string_init("hasValue", sizeof("hasValue") - 1, 1); - zend_declare_typed_property(class_entry, property_hasValue_name, &property_hasValue_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_hasValue_name, &property_hasValue_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_hasValue_name); zval property_isDefault_default_value; ZVAL_UNDEF(&property_isDefault_default_value); zend_string *property_isDefault_name = zend_string_init("isDefault", sizeof("isDefault") - 1, 1); - zend_declare_typed_property(class_entry, property_isDefault_name, &property_isDefault_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isDefault_name, &property_isDefault_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isDefault_name); zval property_isEmptyElement_default_value; ZVAL_UNDEF(&property_isEmptyElement_default_value); zend_string *property_isEmptyElement_name = zend_string_init("isEmptyElement", sizeof("isEmptyElement") - 1, 1); - zend_declare_typed_property(class_entry, property_isEmptyElement_name, &property_isEmptyElement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_declare_typed_property(class_entry, property_isEmptyElement_name, &property_isEmptyElement_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_isEmptyElement_name); zval property_localName_default_value; ZVAL_UNDEF(&property_localName_default_value); zend_string *property_localName_name = zend_string_init("localName", sizeof("localName") - 1, 1); - zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_localName_name, &property_localName_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_localName_name); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1); - zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_name_name, &property_name_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_name_name); zval property_namespaceURI_default_value; ZVAL_UNDEF(&property_namespaceURI_default_value); zend_string *property_namespaceURI_name = zend_string_init("namespaceURI", sizeof("namespaceURI") - 1, 1); - zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_namespaceURI_name, &property_namespaceURI_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_namespaceURI_name); zval property_nodeType_default_value; ZVAL_UNDEF(&property_nodeType_default_value); zend_string *property_nodeType_name = zend_string_init("nodeType", sizeof("nodeType") - 1, 1); - zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_declare_typed_property(class_entry, property_nodeType_name, &property_nodeType_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(property_nodeType_name); zval property_prefix_default_value; ZVAL_UNDEF(&property_prefix_default_value); zend_string *property_prefix_name = zend_string_init("prefix", sizeof("prefix") - 1, 1); - zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_prefix_name, &property_prefix_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_prefix_name); zval property_value_default_value; ZVAL_UNDEF(&property_value_default_value); zend_string *property_value_name = zend_string_init("value", sizeof("value") - 1, 1); - zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_value_name, &property_value_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_value_name); zval property_xmlLang_default_value; ZVAL_UNDEF(&property_xmlLang_default_value); zend_string *property_xmlLang_name = zend_string_init("xmlLang", sizeof("xmlLang") - 1, 1); - zend_declare_typed_property(class_entry, property_xmlLang_name, &property_xmlLang_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_declare_typed_property(class_entry, property_xmlLang_name, &property_xmlLang_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_VIRTUAL, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); zend_string_release(property_xmlLang_name); return class_entry; diff --git a/ext/xmlreader/tests/001.phpt b/ext/xmlreader/tests/001.phpt index bcfa02fbc9234..ab84cd0b3a222 100644 --- a/ext/xmlreader/tests/001.phpt +++ b/ext/xmlreader/tests/001.phpt @@ -28,4 +28,4 @@ try { --EXPECT-- books books -XMLReader::XML(): Argument #1 ($source) cannot be empty +XMLReader::XML(): Argument #1 ($source) must not be empty diff --git a/ext/xmlreader/tests/002.phpt b/ext/xmlreader/tests/002.phpt index e33bc0abd55a0..a0f55a2af3b4f 100644 --- a/ext/xmlreader/tests/002.phpt +++ b/ext/xmlreader/tests/002.phpt @@ -36,6 +36,6 @@ unlink($filename); ?> --EXPECT-- -XMLReader::open(): Argument #1 ($uri) cannot be empty +XMLReader::open(): Argument #1 ($uri) must not be empty books books diff --git a/ext/xmlreader/tests/003-get-errors.phpt b/ext/xmlreader/tests/003-get-errors.phpt index 81087f7e253c8..6cb2f20b8d5fe 100644 --- a/ext/xmlreader/tests/003-get-errors.phpt +++ b/ext/xmlreader/tests/003-get-errors.phpt @@ -69,7 +69,7 @@ unlink(__DIR__.'/003-get-errors.xml'); book bool(true) num: 1 -XMLReader::getAttribute(): Argument #1 ($name) cannot be empty +XMLReader::getAttribute(): Argument #1 ($name) must not be empty num: 1 NULL num: 1 diff --git a/ext/xmlreader/tests/003-move-errors.phpt b/ext/xmlreader/tests/003-move-errors.phpt index 89f4b46094432..be36d252c453b 100644 --- a/ext/xmlreader/tests/003-move-errors.phpt +++ b/ext/xmlreader/tests/003-move-errors.phpt @@ -68,7 +68,7 @@ unlink(__DIR__.'/003-move-errors.xml'); book bool(true) num: 1 -XMLReader::moveToAttribute(): Argument #1 ($name) cannot be empty +XMLReader::moveToAttribute(): Argument #1 ($name) must not be empty num: 1 bool(false) num: 1 diff --git a/ext/xmlreader/tests/003.phpt b/ext/xmlreader/tests/003.phpt index 880d8b8edd095..a581d0dea02d1 100644 --- a/ext/xmlreader/tests/003.phpt +++ b/ext/xmlreader/tests/003.phpt @@ -88,4 +88,4 @@ num: 1 idx: 2 bool(false) bool(false) -XMLReader::moveToAttribute(): Argument #1 ($name) cannot be empty +XMLReader::moveToAttribute(): Argument #1 ($name) must not be empty diff --git a/ext/xmlreader/tests/007.phpt b/ext/xmlreader/tests/007.phpt index 7e95bc7926e51..e9705cc5af66c 100644 --- a/ext/xmlreader/tests/007.phpt +++ b/ext/xmlreader/tests/007.phpt @@ -53,4 +53,4 @@ $reader->close(); --EXPECT-- file relaxNG: ok string relaxNG: ok -XMLReader::setRelaxNGSchema(): Argument #1 ($filename) cannot be empty +XMLReader::setRelaxNGSchema(): Argument #1 ($filename) must not be empty diff --git a/ext/xmlreader/tests/015-get-errors.phpt b/ext/xmlreader/tests/015-get-errors.phpt index 5bde0a9b2b4a4..3cf6134df2053 100644 --- a/ext/xmlreader/tests/015-get-errors.phpt +++ b/ext/xmlreader/tests/015-get-errors.phpt @@ -47,5 +47,5 @@ unlink(__DIR__.'/015-get-errors.xml'); ?> --EXPECTF-- Deprecated: XMLReader::getAttributeNs(): Passing null to parameter #2 ($namespace) of type string is deprecated in %s on line %d -XMLReader::getAttributeNs(): Argument #2 ($namespace) cannot be empty +XMLReader::getAttributeNs(): Argument #2 ($namespace) must not be empty ns1:num: 1 diff --git a/ext/xmlreader/tests/015-move-errors.phpt b/ext/xmlreader/tests/015-move-errors.phpt index 14c7cfd83bea3..d885c5a6fe97b 100644 --- a/ext/xmlreader/tests/015-move-errors.phpt +++ b/ext/xmlreader/tests/015-move-errors.phpt @@ -42,4 +42,4 @@ unlink(__DIR__.'/015-move-errors.xml'); ?> --EXPECTF-- Deprecated: XMLReader::moveToAttributeNs(): Passing null to parameter #2 ($namespace) of type string is deprecated in %s on line %d -XMLReader::moveToAttributeNs(): Argument #2 ($namespace) cannot be empty +XMLReader::moveToAttributeNs(): Argument #2 ($namespace) must not be empty diff --git a/ext/xmlreader/tests/setSchema_error.phpt b/ext/xmlreader/tests/setSchema_error.phpt index 1292f0fb052e1..a586c38f55320 100644 --- a/ext/xmlreader/tests/setSchema_error.phpt +++ b/ext/xmlreader/tests/setSchema_error.phpt @@ -37,7 +37,7 @@ var_dump(@$reader->setSchema('schema-bad.xsd')); $reader->close(); ?> --EXPECT-- -XMLReader::setSchema(): Argument #1 ($filename) cannot be empty +XMLReader::setSchema(): Argument #1 ($filename) must not be empty Schema must be set prior to reading Schema must be set prior to reading bool(false) diff --git a/ext/xmlreader/tests/virtual_properties.phpt b/ext/xmlreader/tests/virtual_properties.phpt new file mode 100644 index 0000000000000..57499292b8ce0 --- /dev/null +++ b/ext/xmlreader/tests/virtual_properties.phpt @@ -0,0 +1,34 @@ +--TEST-- +Virtual property tests +--EXTENSIONS-- +xmlreader +--FILE-- +getProperty("nodeType"); +var_dump($prop->isVirtual()); +var_dump($prop->getSettableType()); +var_dump($prop->getHooks()); +var_dump($prop->getRawValue(new XMLReader)); +var_dump($prop->getValue(new XMLReader)); + +$reader = XMLReader::XML("hi"); +var_dump(json_encode($reader)); +var_export($reader); echo "\n"; +var_dump(get_object_vars($reader)); + +?> +--EXPECTF-- +bool(true) +object(ReflectionNamedType)#%d (0) { +} +array(0) { +} +int(0) +int(0) +string(2) "{}" +\XMLReader::__set_state(array( +)) +array(0) { +} diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index bbb4b94814a48..2029bcbb12e7e 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -24,7 +24,6 @@ #include "ext/standard/info.h" #include "php_xmlwriter.h" #include "php_xmlwriter_arginfo.h" -#include "ext/standard/php_string.h" /* For php_dirname() */ static zend_class_entry *xmlwriter_class_entry_ce; @@ -158,7 +157,7 @@ static char *_xmlwriter_get_valid_file_path(char *source, char *resolved_path, i } memcpy(file_dirname, source, strlen(source)); - dir_len = php_dirname(file_dirname, strlen(source)); + dir_len = zend_dirname(file_dirname, strlen(source)); if (dir_len > 0) { zend_stat_t buf = {0}; @@ -818,7 +817,7 @@ PHP_FUNCTION(xmlwriter_open_uri) } if (source_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -859,7 +858,7 @@ PHP_METHOD(XMLWriter, toUri) ZEND_PARSE_PARAMETERS_END(); if (source_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } diff --git a/ext/xmlwriter/php_xmlwriter_arginfo.h b/ext/xmlwriter/php_xmlwriter_arginfo.h index fda02c49f6f81..ebccf4225ba9f 100644 --- a/ext/xmlwriter/php_xmlwriter_arginfo.h +++ b/ext/xmlwriter/php_xmlwriter_arginfo.h @@ -484,7 +484,7 @@ static zend_class_entry *register_class_XMLWriter(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XMLWriter", class_XMLWriter_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); return class_entry; } diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt index 372dade4dfcd6..3b136a9be2c88 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt @@ -15,4 +15,4 @@ Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 --EXPECT-- -xmlwriter_open_uri(): Argument #1 ($uri) cannot be empty +xmlwriter_open_uri(): Argument #1 ($uri) must not be empty diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4 index 2b8c851b3add8..ac52dc8c1ce95 100644 --- a/ext/xsl/config.m4 +++ b/ext/xsl/config.m4 @@ -15,7 +15,7 @@ if test "$PHP_XSL" != "no"; then PHP_EVAL_LIBLINE([$EXSLT_LIBS], [XSL_SHARED_LIBADD]) AC_DEFINE([HAVE_XSL_EXSLT], [1], [Define to 1 if the system has the EXSLT extension library for XSLT.]) - ], [ ]) + ], [:]) AC_DEFINE([HAVE_XSL], [1], [Define to 1 if the PHP extension 'xsl' is available.]) diff --git a/ext/xsl/php_xsl_arginfo.h b/ext/xsl/php_xsl_arginfo.h index 20559328d8181..d040928197f65 100644 --- a/ext/xsl/php_xsl_arginfo.h +++ b/ext/xsl/php_xsl_arginfo.h @@ -117,7 +117,7 @@ static zend_class_entry *register_class_XSLTProcessor(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "XSLTProcessor", class_XSLTProcessor_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_doXInclude_default_value; ZVAL_FALSE(&property_doXInclude_default_value); diff --git a/ext/zend_test/fiber_arginfo.h b/ext/zend_test/fiber_arginfo.h index c25ed876614b4..e4a0b51bebc9d 100644 --- a/ext/zend_test/fiber_arginfo.h +++ b/ext/zend_test/fiber_arginfo.h @@ -39,8 +39,7 @@ static zend_class_entry *register_class__ZendTestFiber(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestFiber", class__ZendTestFiber_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); return class_entry; } diff --git a/ext/zend_test/iterators_arginfo.h b/ext/zend_test/iterators_arginfo.h index 2661550c5f6cd..3ec78808eaa19 100644 --- a/ext/zend_test/iterators_arginfo.h +++ b/ext/zend_test/iterators_arginfo.h @@ -21,8 +21,7 @@ static zend_class_entry *register_class_ZendTest_Iterators_TraversableTest(zend_ zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTest\\Iterators", "TraversableTest", class_ZendTest_Iterators_TraversableTest_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); return class_entry; diff --git a/ext/zend_test/object_handlers_arginfo.h b/ext/zend_test/object_handlers_arginfo.h index 510a6602ab0be..84a9203fd7ea8 100644 --- a/ext/zend_test/object_handlers_arginfo.h +++ b/ext/zend_test/object_handlers_arginfo.h @@ -49,8 +49,7 @@ static zend_class_entry *register_class_DoOperationNoCast(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DoOperationNoCast", class_DoOperationNoCast_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -66,8 +65,7 @@ static zend_class_entry *register_class_LongCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "LongCastableNoOperations", class_LongCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -83,8 +81,7 @@ static zend_class_entry *register_class_FloatCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "FloatCastableNoOperations", class_FloatCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -100,8 +97,7 @@ static zend_class_entry *register_class_NumericCastableNoOperations(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "NumericCastableNoOperations", class_NumericCastableNoOperations_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); zval property_val_default_value; ZVAL_UNDEF(&property_val_default_value); @@ -117,7 +113,7 @@ static zend_class_entry *register_class_DimensionHandlersNoArrayAccess(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DimensionHandlersNoArrayAccess", class_DimensionHandlersNoArrayAccess_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zval property_read_default_value; ZVAL_FALSE(&property_read_default_value); diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index d1c587420fc2d..ac0d572147a59 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -620,7 +620,11 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestClass", class__ZendTestClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zend_class_implements(class_entry, 1, class_entry__ZendTestInterface); zend_register_class_alias("_ZendTestClassAlias", class_entry); @@ -753,7 +757,11 @@ static zend_class_entry *register_class__ZendTestMagicCall(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestMagicCall", class__ZendTestMagicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -763,7 +771,11 @@ static zend_class_entry *register_class__ZendTestChildClass(zend_class_entry *cl zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestChildClass", class__ZendTestChildClass_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry__ZendTestClass, 0); +#else class_entry = zend_register_internal_class_ex(&ce, class_entry__ZendTestClass); +#endif return class_entry; } @@ -773,7 +785,11 @@ static zend_class_entry *register_class_ZendAttributeTest(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendAttributeTest", class_ZendAttributeTest_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval const_TEST_CONST_value; ZVAL_LONG(&const_TEST_CONST_value, 1); @@ -822,8 +838,12 @@ static zend_class_entry *register_class__ZendTestTrait(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "_ZendTestTrait", class__ZendTestTrait_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_TRAIT); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_TRAIT; +#endif zval property_testProp_default_value; ZVAL_NULL(&property_testProp_default_value); @@ -852,8 +872,12 @@ static zend_class_entry *register_class_ZendTestAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestAttribute", class_ZendTestAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zend_string *attribute_name_Attribute_class_ZendTestAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestAttribute_0, 1); @@ -870,8 +894,12 @@ static zend_class_entry *register_class_ZendTestAttributeWithArguments(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestAttributeWithArguments", class_ZendTestAttributeWithArguments_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zval property_arg_default_value; ZVAL_UNDEF(&property_arg_default_value); @@ -898,8 +926,12 @@ static zend_class_entry *register_class_ZendTestRepeatableAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestRepeatableAttribute", class_ZendTestRepeatableAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zend_string *attribute_name_Attribute_class_ZendTestRepeatableAttribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); zend_attribute *attribute_Attribute_class_ZendTestRepeatableAttribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ZendTestRepeatableAttribute_0, 1); @@ -916,8 +948,12 @@ static zend_class_entry *register_class_ZendTestParameterAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif zval property_parameter_default_value; ZVAL_UNDEF(&property_parameter_default_value); @@ -940,8 +976,12 @@ static zend_class_entry *register_class_ZendTestPropertyAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestPropertyAttribute", class_ZendTestPropertyAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif #if (PHP_VERSION_ID >= 80400) class_entry->doc_comment = zend_string_init_interned("/**\n * \"Lorem ipsum\"\n * @see https://www.php.net\n * @since 8.1\n */", 82, 1); #endif @@ -968,7 +1008,11 @@ static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttr zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zend_string *attribute_name_ZendTestParameterAttribute_func_no_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); @@ -995,7 +1039,11 @@ static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParamete zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute, 0); +#else class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute); +#endif zend_string *attribute_name_ZendTestParameterAttribute_func_override_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1); @@ -1014,7 +1062,11 @@ static zend_class_entry *register_class_ZendTestClassWithPropertyAttribute(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestClassWithPropertyAttribute", class_ZendTestClassWithPropertyAttribute_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval property_attributed_default_value; ZVAL_UNDEF(&property_attributed_default_value); @@ -1035,8 +1087,12 @@ static zend_class_entry *register_class_ZendTestForbidDynamicCall(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZendTestForbidDynamicCall", class_ZendTestForbidDynamicCall_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL; +#endif return class_entry; } @@ -1109,7 +1165,11 @@ static zend_class_entry *register_class_ZendTestNS_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "Foo", class_ZendTestNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1119,7 +1179,11 @@ static zend_class_entry *register_class_ZendTestNS_UnlikelyCompileError(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "UnlikelyCompileError", class_ZendTestNS_UnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1129,7 +1193,11 @@ static zend_class_entry *register_class_ZendTestNS_NotUnlikelyCompileError(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "NotUnlikelyCompileError", class_ZendTestNS_NotUnlikelyCompileError_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } @@ -1139,7 +1207,11 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2", "Foo", class_ZendTestNS2_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif zval property_foo_default_value; ZVAL_UNDEF(&property_foo_default_value); @@ -1156,7 +1228,11 @@ static zend_class_entry *register_class_ZendTestNS2_ZendSubNS_Foo(void) zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2\\ZendSubNS", "Foo", class_ZendTestNS2_ZendSubNS_Foo_methods); +#if (PHP_VERSION_ID >= 80400) + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); +#else class_entry = zend_register_internal_class_ex(&ce, NULL); +#endif return class_entry; } diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 5d331c2fa4b82..9fc0af4fcaca4 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -56,7 +56,7 @@ static int le_zip_entry; This is always used for the first argument*/ #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \ if (path_len == 0) { \ - zend_argument_value_error(1, "cannot be empty"); \ + zend_argument_must_not_be_empty_error(1); \ RETURN_THROWS(); \ } \ if (zip_stat(za, path, flags, &sb) != 0) { \ @@ -171,7 +171,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, const char *file, s is_dir_only = 1; } else { memcpy(file_dirname, path_cleaned, path_cleaned_len); - dir_len = php_dirname(file_dirname, path_cleaned_len); + dir_len = zend_dirname(file_dirname, path_cleaned_len); if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) { len = spprintf(&file_dirname_fullpath, 0, "%s", dest); @@ -417,7 +417,7 @@ static int php_zip_parse_options(HashTable *options, zip_options *opts) } if (Z_STRLEN_P(option) == 0) { - zend_value_error("Option \"remove_path\" cannot be empty"); + zend_value_error("Option \"remove_path\" must not be empty"); return -1; } @@ -437,7 +437,7 @@ static int php_zip_parse_options(HashTable *options, zip_options *opts) } if (Z_STRLEN_P(option) == 0) { - zend_value_error("Option \"add_path\" cannot be empty"); + zend_value_error("Option \"add_path\" must not be empty"); return -1; } @@ -1184,7 +1184,7 @@ PHP_FUNCTION(zip_open) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1466,7 +1466,7 @@ PHP_METHOD(ZipArchive, open) ze_obj = Z_ZIP_P(self); if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1753,7 +1753,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* } if (ZSTR_LEN(pattern) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (options && zend_hash_num_elements(options) > 0 && (php_zip_parse_options(options, &opts) < 0)) { @@ -1871,7 +1871,7 @@ PHP_METHOD(ZipArchive, addFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -1904,7 +1904,7 @@ PHP_METHOD(ZipArchive, replaceFile) } if (ZSTR_LEN(filename) == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2168,7 +2168,7 @@ PHP_METHOD(ZipArchive, setCommentName) } if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2235,7 +2235,7 @@ PHP_METHOD(ZipArchive, setExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2296,7 +2296,7 @@ PHP_METHOD(ZipArchive, getExternalAttributesName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2363,7 +2363,7 @@ PHP_METHOD(ZipArchive, setEncryptionName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2424,7 +2424,7 @@ PHP_METHOD(ZipArchive, getCommentName) ZIP_FROM_OBJECT(intern, self); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2480,7 +2480,7 @@ PHP_METHOD(ZipArchive, setCompressionName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2540,7 +2540,7 @@ PHP_METHOD(ZipArchive, setMtimeName) ZIP_FROM_OBJECT(intern, this); if (name_len == 0) { - zend_argument_value_error(1, "cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } @@ -2654,7 +2654,7 @@ PHP_METHOD(ZipArchive, renameIndex) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } @@ -2682,7 +2682,7 @@ PHP_METHOD(ZipArchive, renameName) ZIP_FROM_OBJECT(intern, self); if (new_name_len == 0) { - zend_argument_value_error(2, "cannot be empty"); + zend_argument_must_not_be_empty_error(2); RETURN_THROWS(); } diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 2a43bc4bf76a7..79e1185cfa164 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -616,7 +616,7 @@ static zend_class_entry *register_class_ZipArchive(zend_class_entry *class_entry zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ZipArchive", class_ZipArchive_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 1, class_entry_Countable); zval const_CREATE_value; diff --git a/ext/zip/tests/oo_getcomment.phpt b/ext/zip/tests/oo_getcomment.phpt index 0257f99a577f3..a43c5ae38a53b 100644 --- a/ext/zip/tests/oo_getcomment.phpt +++ b/ext/zip/tests/oo_getcomment.phpt @@ -30,4 +30,4 @@ $zip->close(); Zip archive comment string(11) "foo comment" string(11) "foo comment" -ZipArchive::getCommentName(): Argument #1 ($name) cannot be empty +ZipArchive::getCommentName(): Argument #1 ($name) must not be empty diff --git a/ext/zip/tests/oo_getexternalattributesname_error.phpt b/ext/zip/tests/oo_getexternalattributesname_error.phpt index 13f99edabf7c0..175fdc4b7bb86 100644 --- a/ext/zip/tests/oo_getexternalattributesname_error.phpt +++ b/ext/zip/tests/oo_getexternalattributesname_error.phpt @@ -20,4 +20,4 @@ try { } ?> --EXPECT-- -ZipArchive::getExternalAttributesName(): Argument #1 ($name) cannot be empty +ZipArchive::getExternalAttributesName(): Argument #1 ($name) must not be empty diff --git a/ext/zip/tests/oo_open.phpt b/ext/zip/tests/oo_open.phpt index 058e68f9a863f..44fa46a9a6ea5 100644 --- a/ext/zip/tests/oo_open.phpt +++ b/ext/zip/tests/oo_open.phpt @@ -42,5 +42,5 @@ if ($zip->status == ZIPARCHIVE::ER_OK) { --EXPECT-- ER_OPEN: ok create: ok -ZipArchive::open(): Argument #1 ($filename) cannot be empty +ZipArchive::open(): Argument #1 ($filename) must not be empty OK diff --git a/ext/zip/tests/zip_open_error.phpt b/ext/zip/tests/zip_open_error.phpt index 567e2cb2ff7bb..2e43ac29713b4 100644 --- a/ext/zip/tests/zip_open_error.phpt +++ b/ext/zip/tests/zip_open_error.phpt @@ -21,7 +21,7 @@ echo is_resource($zip) ? "OK" : "Failure"; --EXPECTF-- Test case 1: Deprecated: Function zip_open() is deprecated since 8.0, use ZipArchive::open() instead in %s on line %d -zip_open(): Argument #1 ($filename) cannot be empty +zip_open(): Argument #1 ($filename) must not be empty Test case 2: Deprecated: Function zip_open() is deprecated since 8.0, use ZipArchive::open() instead in %s on line %d diff --git a/ext/zlib/zlib_arginfo.h b/ext/zlib/zlib_arginfo.h index 1c0c9746d3d27..c29bd68936195 100644 --- a/ext/zlib/zlib_arginfo.h +++ b/ext/zlib/zlib_arginfo.h @@ -240,8 +240,7 @@ static zend_class_entry *register_class_InflateContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "InflateContext", class_InflateContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } @@ -251,8 +250,7 @@ static zend_class_entry *register_class_DeflateContext(void) zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "DeflateContext", class_DeflateContext_methods); - class_entry = zend_register_internal_class_ex(&ce, NULL); - class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); return class_entry; } diff --git a/main/network.c b/main/network.c index f582218d1a1a7..9ca2b53b6ea5e 100644 --- a/main/network.c +++ b/main/network.c @@ -113,7 +113,9 @@ static const char *php_gai_strerror(int code) {EAI_NONAME, "Name or service not known"}, {EAI_SERVICE, "Servname not supported for ai_socktype"}, {EAI_SOCKTYPE, "ai_socktype not supported"}, +# ifdef EAI_SYSTEM {EAI_SYSTEM, "System error"}, +# endif {0, NULL} }; int i; @@ -499,11 +501,11 @@ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned po } /* }}} */ -PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_long addrlen, struct sockaddr *sa, socklen_t *sl) +PHPAPI zend_result php_network_parse_network_address_with_port(const char *addr, size_t addrlen, struct sockaddr *sa, socklen_t *sl) { char *colon; char *tmp; - int ret = FAILURE; + zend_result ret = FAILURE; short port; struct sockaddr_in *in4 = (struct sockaddr_in*)sa; struct sockaddr **psal; @@ -843,7 +845,7 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short struct sockaddr_in6 in6; #endif } local_address = {0}; - int local_address_len = 0; + size_t local_address_len = 0; if (sa->sa_family == AF_INET) { if (inet_pton(AF_INET, bindto, &local_address.in4.sin_addr) == 1) { @@ -974,7 +976,7 @@ PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short /* {{{ php_sockaddr_size * Returns the size of struct sockaddr_xx for the family */ -PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr) +PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr) { switch (((struct sockaddr *)addr)->sa_family) { case AF_INET: @@ -1099,9 +1101,9 @@ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short p return stream; } -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block) +PHPAPI zend_result php_set_sock_blocking(php_socket_t socketd, bool block) { - int ret = SUCCESS; + zend_result ret = SUCCESS; #ifdef PHP_WIN32 u_long flags; @@ -1253,7 +1255,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); } - if (res != SUCCESS) { + if (res != 0) { return NULL; } @@ -1295,7 +1297,7 @@ static struct hostent * gethostname_re (const char *host,struct hostent *hostbuf } memset((void *)(*tmphstbuf),0,*hstbuflen); - if (SUCCESS != gethostbyname_r(host,hostbuf,(struct hostent_data *)*tmphstbuf)) { + if (0 != gethostbyname_r(host,hostbuf,(struct hostent_data *)*tmphstbuf)) { return NULL; } diff --git a/main/php_network.h b/main/php_network.h index a31bc57b76aee..06da95dd68ce6 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -306,7 +306,7 @@ PHPAPI int php_network_get_peer_name(php_socket_t sock, ); PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port); -PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr); +PHPAPI socklen_t php_sockaddr_size(php_sockaddr_storage *addr); END_EXTERN_C() struct _php_netstream_data_t { @@ -336,12 +336,12 @@ PHPAPI void php_network_populate_name_from_sockaddr( socklen_t *addrlen ); -PHPAPI int php_network_parse_network_address_with_port(const char *addr, - zend_long addrlen, struct sockaddr *sa, socklen_t *sl); +PHPAPI zend_result php_network_parse_network_address_with_port(const char *addr, + size_t addrlen, struct sockaddr *sa, socklen_t *sl); PHPAPI struct hostent* php_network_gethostbyname(const char *name); -PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block); +PHPAPI zend_result php_set_sock_blocking(php_socket_t socketd, bool block); END_EXTERN_C() #define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC) diff --git a/main/streams/streams.c b/main/streams/streams.c index 0b3e5cc06cb9e..f3fb5e3cda544 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2194,7 +2194,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (!path || !*path) { - zend_value_error("Path cannot be empty"); + zend_value_error("Path must not be empty"); return NULL; } diff --git a/php.ini-development b/php.ini-development index 6f6624b1dd26b..3fd5fd578ee04 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1605,7 +1605,7 @@ zend.assertions = 1 ; With mbstring support this will automatically be converted into the encoding ; given by corresponding encode setting. When empty mbstring.internal_encoding ; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. +; intel byte order. A decode setting must not be empty. ; https://php.net/exif.encode-unicode ;exif.encode_unicode = ISO-8859-15 diff --git a/php.ini-production b/php.ini-production index fa1356e2c24a5..41f1578a2e786 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1607,7 +1607,7 @@ zend.assertions = -1 ; With mbstring support this will automatically be converted into the encoding ; given by corresponding encode setting. When empty mbstring.internal_encoding ; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. +; intel byte order. A decode setting must not be empty. ; https://php.net/exif.encode-unicode ;exif.encode_unicode = ISO-8859-15 diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index 9012d472b19c3..ff0829846b8c6 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -7,15 +7,14 @@ PHP_ARG_WITH([apxs2], [no]) if test "$PHP_APXS2" != "no"; then - if test "$PHP_APXS2" = "yes"; then + AS_VAR_IF([PHP_APXS2], [yes], [ APXS=apxs $APXS -q CFLAGS >/dev/null 2>&1 if test "$?" != "0" && test -x /usr/sbin/apxs; then APXS=/usr/sbin/apxs fi - else - PHP_EXPAND_PATH([$PHP_APXS2], [APXS]) - fi + ], + [PHP_EXPAND_PATH([$PHP_APXS2], [APXS])]) $APXS -q CFLAGS >/dev/null 2>&1 if test "$?" != "0"; then @@ -32,30 +31,26 @@ if test "$PHP_APXS2" != "no"; then AC_MSG_ERROR([Aborting]) fi - APXS_INCLUDEDIR=`$APXS -q INCLUDEDIR` - APXS_HTTPD=`$APXS -q SBINDIR`/`$APXS -q TARGET` + APXS_INCLUDEDIR=$($APXS -q INCLUDEDIR) + APXS_HTTPD=$($APXS -q SBINDIR)/$($APXS -q TARGET) AS_IF([test ! -x "$APXS_HTTPD"], [AC_MSG_ERROR(m4_text_wrap([ $APXS_HTTPD executable not found. Please, install Apache HTTP Server command-line utility. ]))]) - APXS_CFLAGS=`$APXS -q CFLAGS` - APU_BINDIR=`$APXS -q APU_BINDIR` - APR_BINDIR=`$APXS -q APR_BINDIR` + APXS_CFLAGS=$($APXS -q CFLAGS) + APU_BINDIR=$($APXS -q APU_BINDIR) + APR_BINDIR=$($APXS -q APR_BINDIR) dnl Pick up ap[ru]-N-config. - APR_CONFIG=`$APXS -q APR_CONFIG 2>/dev/null || - echo $APR_BINDIR/apr-config` - APU_CONFIG=`$APXS -q APU_CONFIG 2>/dev/null || - echo $APU_BINDIR/apu-config` + APR_CONFIG=$($APXS -q APR_CONFIG 2>/dev/null || echo $APR_BINDIR/apr-config) + APU_CONFIG=$($APXS -q APU_CONFIG 2>/dev/null || echo $APU_BINDIR/apu-config) - APR_CFLAGS="`$APR_CONFIG --cppflags --includes`" - APU_CFLAGS="`$APU_CONFIG --includes`" + APR_CFLAGS="$($APR_CONFIG --cppflags --includes)" + APU_CFLAGS="$($APU_CONFIG --includes)" for flag in $APXS_CFLAGS; do - case $flag in - -D*) APACHE_CPPFLAGS="$APACHE_CPPFLAGS $flag";; - esac + AS_CASE([$flag], [-D*], [APACHE_CPPFLAGS="$APACHE_CPPFLAGS $flag"]) done APACHE_CFLAGS="$APACHE_CPPFLAGS -I$APXS_INCLUDEDIR $APR_CFLAGS $APU_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" @@ -65,13 +60,13 @@ if test "$PHP_APXS2" != "no"; then AS_VERSION_COMPARE([$APACHE_VERSION], [2004000], [AC_MSG_ERROR([Please note that Apache version >= 2.4 is required])]) - APXS_LIBEXECDIR='$(INSTALL_ROOT)'`$APXS -q LIBEXECDIR` - if test -z `$APXS -q SYSCONFDIR`; then + APXS_LIBEXECDIR='$(INSTALL_ROOT)'$($APXS -q LIBEXECDIR) + if test -z $($APXS -q SYSCONFDIR); then INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ -i -n php" else - APXS_SYSCONFDIR='$(INSTALL_ROOT)'`$APXS -q SYSCONFDIR` + APXS_SYSCONFDIR='$(INSTALL_ROOT)'$($APXS -q SYSCONFDIR) INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ \$(mkinstalldirs) '$APXS_SYSCONFDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ @@ -82,42 +77,34 @@ if test "$PHP_APXS2" != "no"; then LIBPHP_CFLAGS="-shared" PHP_SUBST([LIBPHP_CFLAGS]) - case $host_alias in - *aix*) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-brtl -Wl,-bI:$APXS_LIBEXECDIR/httpd.exp" - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" - ;; - *darwin*) - dnl When using bundles on Darwin, we must resolve all symbols. However, the - dnl linker does not recursively look at the bundle loader and pull in its - dnl dependencies. Therefore, we must pull in the APR and APR-util libraries. - if test -x "$APR_CONFIG"; then - MH_BUNDLE_FLAGS="`$APR_CONFIG --ldflags --link-ld --libs`" - fi - if test -x "$APU_CONFIG"; then - MH_BUNDLE_FLAGS="`$APU_CONFIG --ldflags --link-ld --libs` $MH_BUNDLE_FLAGS" - fi - MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" - PHP_SUBST([MH_BUNDLE_FLAGS]) - PHP_SELECT_SAPI([apache2handler], - [bundle], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - SAPI_SHARED=libs/libphp.so - INSTALL_IT="$INSTALL_IT $SAPI_SHARED" - ;; - *) - PHP_SELECT_SAPI([apache2handler], - [shared], - [mod_php.c sapi_apache2.c apache_config.c php_functions.c], - [$APACHE_CFLAGS]) - INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" - ;; - esac + php_sapi_apache2handler_type=shared + AS_CASE([$host_alias], + [*aix*], [ + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-brtl -Wl,-bI:$APXS_LIBEXECDIR/httpd.exp" + INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL" + ], + [*darwin*], [ + dnl When using bundles on Darwin, we must resolve all symbols. However, + dnl the linker does not recursively look at the bundle loader and pull in + dnl its dependencies. Therefore, we must pull in the APR and APR-util + dnl libraries. + if test -x "$APR_CONFIG"; then + MH_BUNDLE_FLAGS="$($APR_CONFIG --ldflags --link-ld --libs)" + fi + if test -x "$APU_CONFIG"; then + MH_BUNDLE_FLAGS="$($APU_CONFIG --ldflags --link-ld --libs) $MH_BUNDLE_FLAGS" + fi + MH_BUNDLE_FLAGS="-bundle -bundle_loader $APXS_HTTPD $MH_BUNDLE_FLAGS" + PHP_SUBST([MH_BUNDLE_FLAGS]) + php_sapi_apache2handler_type=bundle + INSTALL_IT="$INSTALL_IT $SAPI_SHARED" + ], + [INSTALL_IT="$INSTALL_IT $SAPI_LIBTOOL"]) + + PHP_SELECT_SAPI([apache2handler], + [$php_sapi_apache2handler_type], + [mod_php.c sapi_apache2.c apache_config.c php_functions.c], + [$APACHE_CFLAGS]) AS_IF([$APXS_HTTPD -V 2>/dev/null | grep 'threaded:.*yes' >/dev/null 2>&1], [ APACHE_THREADED_MPM=yes diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4 index 31a6dc9953411..3752ffc4396a1 100644 --- a/sapi/cgi/config9.m4 +++ b/sapi/cgi/config9.m4 @@ -6,57 +6,47 @@ PHP_ARG_ENABLE([cgi], [no]) if test "$PHP_CGI" != "no"; then - dnl BSD systems. - AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[#include ]) - - AC_MSG_CHECKING([whether cross-process locking is required by accept()]) - case "`uname -sr`" in - SunOS\ 5.*) - AC_MSG_RESULT([yes]) - AC_DEFINE([USE_LOCKING], [1], - [Define to 1 if cross-process locking is required by 'accept()'.]) - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac - - PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/cgi/Makefile.frag]) - - dnl Set filename. - case $host_alias in - *cygwin* ) - SAPI_CGI_PATH=sapi/cgi/php-cgi.exe - ;; - * ) - SAPI_CGI_PATH=sapi/cgi/php-cgi - ;; - esac - - dnl Select SAPI. - PHP_SELECT_SAPI([cgi], - [program], - [cgi_main.c], - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) - - case $host_alias in - *aix*) - if test "$php_sapi_module" = "shared"; then - BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" - else - BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" - fi - ;; - *darwin*) - BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" - ;; - *) - BUILD_CGI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" - ;; - esac - - PHP_SUBST([SAPI_CGI_PATH]) - PHP_SUBST([BUILD_CGI]) - - AC_CONFIG_FILES([sapi/cgi/php-cgi.1]) + dnl BSD systems. + AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[#include ]) + + AC_MSG_CHECKING([whether cross-process locking is required by accept()]) + AS_CASE([$(uname -sr)], + [SunOS\ 5.*], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([USE_LOCKING], [1], + [Define to 1 if cross-process locking is required by 'accept()'.]) + ], + [AC_MSG_RESULT([no])]) + + PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/cgi/Makefile.frag]) + + dnl Set filename. + AS_CASE([$host_alias], + [*cygwin*], [SAPI_CGI_PATH=sapi/cgi/php-cgi.exe], + [SAPI_CGI_PATH=sapi/cgi/php-cgi]) + + dnl Select SAPI. + PHP_SELECT_SAPI([cgi], + [program], + [cgi_main.c], + [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + + AS_CASE([$host_alias], + [*aix*], [ + AS_VAR_IF([php_sapi_module], [shared], [ + BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ], [ + BUILD_CGI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CGI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_CGI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ]) + ], + [*darwin*], [ + BUILD_CGI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ], [ + BUILD_CGI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_CGI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CGI_PATH)" + ]) + + PHP_SUBST([SAPI_CGI_PATH]) + PHP_SUBST([BUILD_CGI]) + + AC_CONFIG_FILES([sapi/cgi/php-cgi.1]) fi diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index 5b81106064f9e..76c2d64e8c8a3 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -35,21 +35,19 @@ if test "$PHP_CLI" != "no"; then [php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c], [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) - case $host_alias in - *aix*) - if test "$php_sapi_module" = "shared"; then - BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" - else - BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" - fi - ;; - *darwin*) - BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" - ;; - *) - BUILD_CLI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" - ;; - esac + AS_CASE([$host_alias], + [*aix*], [ + AS_VAR_IF([php_sapi_module], [shared], [ + BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/.libs\/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ], [ + BUILD_CLI="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ]) + ], + [*darwin*], [ + BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ], [ + BUILD_CLI="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ]) dnl Set executable for tests. PHP_EXECUTABLE="\$(top_builddir)/\$(SAPI_CLI_PATH)" diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index bd030c2010349..a720ce32e356c 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -95,7 +95,6 @@ #include "zend_smart_str.h" #include "ext/standard/html.h" #include "ext/standard/url.h" /* for php_raw_url_decode() */ -#include "ext/standard/php_string.h" /* for php_dirname() */ #include "ext/date/php_date.h" /* for php_format_date() */ #include "php_network.h" diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index ef9956763d3a4..c385e289a70ee 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -8,31 +8,29 @@ PHP_ARG_ENABLE([embed],, AC_MSG_CHECKING([for embedded SAPI library support]) if test "$PHP_EMBED" != "no"; then - case "$PHP_EMBED" in - yes|shared) + AS_CASE([$PHP_EMBED], + [yes|shared], [ LIBPHP_CFLAGS="-shared" PHP_EMBED_TYPE=shared INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0755 $SAPI_SHARED \$(INSTALL_ROOT)\$(orig_libdir)" - ;; - static) + ], + [static], [ LIBPHP_CFLAGS="-static" PHP_EMBED_TYPE=static INSTALL_IT="\$(mkinstalldirs) \$(INSTALL_ROOT)\$(orig_libdir); \$(INSTALL) -m 0644 $SAPI_STATIC \$(INSTALL_ROOT)\$(orig_libdir)" - ;; - *) - PHP_EMBED_TYPE=no - ;; - esac - if test "$PHP_EMBED_TYPE" != "no"; then + ], + [PHP_EMBED_TYPE=]) + + AS_VAR_IF([PHP_EMBED_TYPE],, [AC_MSG_RESULT([no])], [ + AC_MSG_RESULT([$PHP_EMBED_TYPE]) PHP_SUBST([LIBPHP_CFLAGS]) + AC_SUBST([PHP_EMBED_TYPE]) PHP_SELECT_SAPI([embed], [$PHP_EMBED_TYPE], [php_embed.c], [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_INSTALL_HEADERS([sapi/embed], [php_embed.h]) - fi - AC_MSG_RESULT([$PHP_EMBED_TYPE]) - AC_SUBST([PHP_EMBED_TYPE]) + ]) else AC_MSG_RESULT([no]) fi diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 3648cae63af10..8277cd518b3e1 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -235,7 +235,7 @@ AC_DEFUN([PHP_FPM_LQ], AS_VAR_IF([php_cv_have_TCP_INFO], [yes], [AC_DEFINE([HAVE_LQ_TCP_INFO], [1], [Define to 1 if you have 'TCP_INFO'.])]) -AC_CACHE_CHECK([for TCP_CONNECTION_INFO], [php_cv_have_TCP_CONNECTION_INFO] +AC_CACHE_CHECK([for TCP_CONNECTION_INFO], [php_cv_have_TCP_CONNECTION_INFO], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [ struct tcp_connection_info ti; int x = TCP_CONNECTION_INFO; @@ -486,24 +486,24 @@ if test "$PHP_FPM" != "no"; then ]) if test -z "$PHP_FPM_USER" || test "$PHP_FPM_USER" = "yes" || test "$PHP_FPM_USER" = "no"; then - php_fpm_user="nobody" + php_fpm_user=nobody else - php_fpm_user="$PHP_FPM_USER" + php_fpm_user=$PHP_FPM_USER fi if test -z "$PHP_FPM_GROUP" || test "$PHP_FPM_GROUP" = "yes" || test "$PHP_FPM_GROUP" = "no"; then - php_fpm_group="nobody" + php_fpm_group=nobody else - php_fpm_group="$PHP_FPM_GROUP" + php_fpm_group=$PHP_FPM_GROUP fi AC_SUBST([php_fpm_user]) AC_SUBST([php_fpm_group]) - php_fpm_sysconfdir=`eval echo $sysconfdir` + php_fpm_sysconfdir=$(eval echo $sysconfdir) AC_SUBST([php_fpm_sysconfdir]) - php_fpm_localstatedir=`eval echo $localstatedir` + php_fpm_localstatedir=$(eval echo $localstatedir) AC_SUBST([php_fpm_localstatedir]) - php_fpm_prefix=`eval echo $prefix` + php_fpm_prefix=$(eval echo $prefix) AC_SUBST([php_fpm_prefix]) PHP_ADD_BUILD_DIR([sapi/fpm/fpm]) @@ -560,17 +560,15 @@ if test "$PHP_FPM" != "no"; then [$PHP_FPM_FILES $PHP_FPM_TRACE_FILES $PHP_FPM_SD_FILES], [$PHP_FPM_CFLAGS]) - case $host_alias in - *aix*) - BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" - ;; - *darwin*) - BUILD_FPM="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" - ;; - *) - BUILD_FPM="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" - ;; - esac + AS_CASE([$host_alias], + [*aix*], [ + BUILD_FPM="echo '\#! .' > php.sym && echo >>php.sym && nm -BCpg \`echo \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FPM_OBJS) | sed 's/\([A-Za-z0-9_]*\)\.lo/\1.o/g'\` | \$(AWK) '{ if (((\$\$2 == \"T\") || (\$\$2 == \"D\") || (\$\$2 == \"B\")) && (substr(\$\$3,1,1) != \".\")) { print \$\$3 } }' | sort -u >> php.sym && \$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) -Wl,-brtl -Wl,-bE:php.sym \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_FASTCGI_OBJS) \$(PHP_FPM_OBJS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" + ], + [*darwin*], [ + BUILD_FPM="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" + ], [ + BUILD_FPM="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_FASTCGI_OBJS:.lo=.o) \$(PHP_FPM_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(FPM_EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_FPM_PATH)" + ]) PHP_SUBST([SAPI_FPM_PATH]) PHP_SUBST([BUILD_FPM]) diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c index bb66c081258d5..6619b7c26f064 100644 --- a/sapi/fpm/fpm/fpm_log.c +++ b/sapi/fpm/fpm/fpm_log.c @@ -19,11 +19,7 @@ #include "fastcgi.h" #include "zlog.h" -#ifdef MAX_LINE_LENGTH -# define FPM_LOG_BUFFER MAX_LINE_LENGTH -#else -# define FPM_LOG_BUFFER 1024 -#endif +#define FPM_LOG_BUFFER 1024 static char *fpm_log_format = NULL; static int fpm_log_fd = -1; diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index b1535b26e3ef8..fca79e4bf70e8 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -189,7 +189,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog) /* {{{ * void fpm_php_trace(struct fpm_child_s *child) /* {{{ */ { - fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); FILE *slowlog; zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid); diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c index 7a55d98b046fc..4abffdf093d01 100644 --- a/sapi/fpm/fpm/fpm_process_ctl.c +++ b/sapi/fpm/fpm/fpm_process_ctl.c @@ -373,7 +373,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ } } - fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); + fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); /* this is specific to PM_STYLE_ONDEMAND */ if (wp->config->pm == PM_STYLE_ONDEMAND) { @@ -406,7 +406,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ if (idle < wp->config->pm_min_spare_servers) { if (wp->running_children >= wp->config->pm_max_children) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } @@ -425,7 +425,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ children_to_fork = MIN(children_to_fork, wp->config->pm_max_children - wp->running_children); if (children_to_fork <= 0) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } @@ -529,7 +529,7 @@ void fpm_pctl_on_socket_accept(struct fpm_event_s *ev, short which, void *arg) / if (wp->running_children >= wp->config->pm_max_children) { if (!wp->warn_max_children && !wp->shared) { - fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard); zlog(ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c index 0eb75884d367a..92c6fa8f2cca9 100644 --- a/sapi/fpm/fpm/fpm_request.c +++ b/sapi/fpm/fpm/fpm_request.c @@ -54,7 +54,7 @@ void fpm_request_accepting(void) fpm_scoreboard_proc_release(proc); /* idle++, active-- */ - fpm_scoreboard_update_commit(1, -1, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); + fpm_scoreboard_update_commit(1, -1, 0, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); } void fpm_request_reading_headers(void) @@ -98,7 +98,7 @@ void fpm_request_reading_headers(void) fpm_scoreboard_proc_release(proc); /* idle--, active++, request++ */ - fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); + fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL); } void fpm_request_info(void) @@ -199,6 +199,9 @@ void fpm_request_end(void) #endif proc->memory = memory; fpm_scoreboard_proc_release(proc); + + /* memory_peak */ + fpm_scoreboard_update_commit(0, 0, 0, 0, 0, 0, 0, proc->memory, FPM_SCOREBOARD_ACTION_SET, NULL); } void fpm_request_finished(void) diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 32f8e9ab161d8..4306d814dc07d 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -99,7 +99,7 @@ void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard) /* {{{ */ void fpm_scoreboard_update_commit( int idle, int active, int lq, int lq_len, int requests, int max_children_reached, - int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ + int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ { scoreboard = fpm_scoreboard_get_for_update(scoreboard); if (!scoreboard) { @@ -169,6 +169,9 @@ void fpm_scoreboard_update_commit( if (scoreboard->active > scoreboard->active_max) { scoreboard->active_max = scoreboard->active; } + if (scoreboard->memory_peak < memory_peak) { + scoreboard->memory_peak = memory_peak; + } fpm_unlock(scoreboard->lock); } @@ -177,11 +180,11 @@ void fpm_scoreboard_update_commit( void fpm_scoreboard_update( int idle, int active, int lq, int lq_len, int requests, int max_children_reached, - int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ + int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */ { fpm_scoreboard_update_begin(scoreboard); fpm_scoreboard_update_commit( - idle, active, lq, lq_len, requests, max_children_reached, slow_rq, action, scoreboard); + idle, active, lq, lq_len, requests, max_children_reached, slow_rq, memory_peak, action, scoreboard); } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 5aeb5555133a7..4ccd8cfb4e23f 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -66,6 +66,7 @@ struct fpm_scoreboard_s { unsigned int nprocs; int free_proc; unsigned long int slow_rq; + size_t memory_peak; struct fpm_scoreboard_s *shared; struct fpm_scoreboard_proc_s procs[] ZEND_ELEMENT_COUNT(nprocs); }; @@ -74,8 +75,8 @@ int fpm_scoreboard_init_main(void); int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp); void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard); -void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); -void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); +void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_max, int action, struct fpm_scoreboard_s *scoreboard); +void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_max, int action, struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_s *fpm_scoreboard_get(void); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index); diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 18307ccaa0889..9a06f6d874b1e 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -514,7 +514,7 @@ int fpm_sockets_init_main(void) } if (wp->listen_address_domain == FPM_AF_INET && fpm_socket_get_listening_queue(wp->listening_socket, NULL, &lq_len) >= 0) { - fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); + fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, 0, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard); } } diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index e9b6ce2d95cdb..cbf8644d99cab 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -94,6 +94,7 @@ int fpm_status_export_to_zval(zval *status) add_assoc_long(status, "max-active-processes", scoreboard.active_max); add_assoc_long(status, "max-children-reached", scoreboard.max_children_reached); add_assoc_long(status, "slow-requests", scoreboard.slow_rq); + add_assoc_long(status, "memory-peak", scoreboard.memory_peak); array_init(&fpm_proc_stats); for(i=0; imax active processes%d\n" "max children reached%u\n" "slow requests%lu\n" + "memory peak%zu\n" "\n"; if (!full) { @@ -309,7 +311,8 @@ int fpm_status_handle_request(void) /* {{{ */ "%d\n" "%d\n" "%u\n" - "%lu\n"; + "%lu\n" + "%zu\n"; if (!full) { short_post = ""; @@ -357,7 +360,8 @@ int fpm_status_handle_request(void) /* {{{ */ "\"total processes\":%d," "\"max active processes\":%d," "\"max children reached\":%u," - "\"slow requests\":%lu"; + "\"slow requests\":%lu," + "\"memory peak\":%zu"; if (!full) { short_post = "}"; @@ -426,6 +430,9 @@ int fpm_status_handle_request(void) /* {{{ */ "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value.\n" "# TYPE phpfpm_slow_requests counter\n" "phpfpm_slow_requests %lu\n" + "# HELP phpfpm_memory_peak The memory usage peak since FPM has started.\n" + "# TYPE phpfpm_memory_peak gauge\n" + "phpfpm_memory_peak %zu\n" "# EOF\n"; has_start_time = 0; @@ -457,7 +464,8 @@ int fpm_status_handle_request(void) /* {{{ */ "total processes: %d\n" "max active processes: %d\n" "max children reached: %u\n" - "slow requests: %lu\n"; + "slow requests: %lu\n" + "memory peak: %zu\n"; if (full) { full_syntax = @@ -496,7 +504,8 @@ int fpm_status_handle_request(void) /* {{{ */ scoreboard_p->idle + scoreboard_p->active, scoreboard_p->active_max, scoreboard_p->max_children_reached, - scoreboard_p->slow_rq); + scoreboard_p->slow_rq, + scoreboard_p->memory_peak); } else { spprintf(&buffer, 0, short_syntax, scoreboard_p->pool, @@ -511,7 +520,8 @@ int fpm_status_handle_request(void) /* {{{ */ scoreboard_p->idle + scoreboard_p->active, scoreboard_p->active_max, scoreboard_p->max_children_reached, - scoreboard_p->slow_rq); + scoreboard_p->slow_rq, + scoreboard_p->memory_peak); } PUTS(buffer); diff --git a/sapi/fpm/tests/fpm_get_status_basic.phpt b/sapi/fpm/tests/fpm_get_status_basic.phpt index d72a1f4d70aca..e566bedd7b29d 100644 --- a/sapi/fpm/tests/fpm_get_status_basic.phpt +++ b/sapi/fpm/tests/fpm_get_status_basic.phpt @@ -39,7 +39,7 @@ $tester->close(); Done --EXPECTF-- Test Start -array(15) { +array(16) { ["pool"]=> string(10) "unconfined" ["process-manager"]=> @@ -68,6 +68,8 @@ array(15) { int(0) ["slow-requests"]=> int(0) + ["memory-peak"]=> + int(0) ["procs"]=> array(1) { [0]=> diff --git a/sapi/fpm/tests/main-version.phpt b/sapi/fpm/tests/main-version.phpt index 40ea45ef01026..5ae83562d070b 100644 --- a/sapi/fpm/tests/main-version.phpt +++ b/sapi/fpm/tests/main-version.phpt @@ -16,6 +16,6 @@ echo "Done\n"; --EXPECTF-- string(%d) "PHP %s (fpm%s (built: %s Copyright (c) The PHP Group -Zend Engine v%s, Copyright (c) Zend Technologies +%AZend Engine v%s, Copyright (c) Zend Technologies " Done diff --git a/sapi/fpm/tests/status.inc b/sapi/fpm/tests/status.inc index dc07de563adbc..76ef7fd55e118 100644 --- a/sapi/fpm/tests/status.inc +++ b/sapi/fpm/tests/status.inc @@ -35,6 +35,7 @@ class Status 'max active processes' => '\d+', 'max children reached' => '\d+', 'slow requests' => '\d+', + 'memory peak' => '\d+', ]; /** @@ -266,6 +267,9 @@ class Status "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value\.\n" . "# TYPE phpfpm_slow_requests counter\n" . "phpfpm_slow_requests " . $fields['slow requests'] . "\n" . + "# HELP phpfpm_memory_peak The memory usage peak since FPM has started\.\n" . + "# TYPE phpfpm_memory_peak gauge\n" . + "phpfpm_memory_peak " . $fields['memory peak'] . "\n" . "# EOF)\n"; if (!preg_match($pattern, $body)) { diff --git a/sapi/fuzzer/config.m4 b/sapi/fuzzer/config.m4 index c948d37067d50..21a44cd6d886e 100644 --- a/sapi/fuzzer/config.m4 +++ b/sapi/fuzzer/config.m4 @@ -8,13 +8,15 @@ PHP_ARG_ENABLE([fuzzer], dnl For newer Clang versions see https://llvm.org/docs/LibFuzzer.html#fuzzer-usage dnl for relevant flags. -dnl Macro to define fuzzing target +dnl dnl PHP_FUZZER_TARGET(name, target-var) dnl +dnl Macro to define the fuzzing target. +dnl AC_DEFUN([PHP_FUZZER_TARGET], [ PHP_FUZZER_BINARIES="$PHP_FUZZER_BINARIES $SAPI_FUZZER_PATH/php-fuzz-$1" PHP_SUBST([$2]) - PHP_ADD_SOURCES_X([sapi/fuzzer],[fuzzer-$1.c],[],$2) + PHP_ADD_SOURCES_X([sapi/fuzzer], [fuzzer-$1.c], [], [$2]) $2="[$]$2 $FUZZER_COMMON_OBJS" ]) @@ -30,19 +32,18 @@ if test "$PHP_FUZZER" != "no"; then PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/fuzzer/Makefile.frag]) SAPI_FUZZER_PATH=sapi/fuzzer PHP_SUBST([SAPI_FUZZER_PATH]) - if test -z "$LIB_FUZZING_ENGINE"; then + AS_VAR_IF([LIB_FUZZING_ENGINE],, [ FUZZING_LIB="-fsanitize=fuzzer" - FUZZING_CC="$CC" + FUZZING_CC=$CC AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link], [ CFLAGS="$CFLAGS -fsanitize=fuzzer-no-link" CXXFLAGS="$CXXFLAGS -fsanitize=fuzzer-no-link" - ],[ - AC_MSG_ERROR([Compiler doesn't support -fsanitize=fuzzer-no-link]) - ]) - else - FUZZING_LIB="$LIB_FUZZING_ENGINE" + ], + [AC_MSG_ERROR([Compiler doesn't support -fsanitize=fuzzer-no-link])]) + ], [ + FUZZING_LIB=$LIB_FUZZING_ENGINE FUZZING_CC="$CXX -stdlib=libc++" - fi + ]) PHP_SUBST([FUZZING_LIB]) PHP_SUBST([FUZZING_CC]) @@ -55,21 +56,21 @@ if test "$PHP_FUZZER" != "no"; then PHP_ADD_SOURCES_X([sapi/fuzzer], [fuzzer-sapi.c], [], [FUZZER_COMMON_OBJS]) - PHP_FUZZER_TARGET([parser], PHP_FUZZER_PARSER_OBJS) - PHP_FUZZER_TARGET([execute], PHP_FUZZER_EXECUTE_OBJS) - PHP_FUZZER_TARGET([function-jit], PHP_FUZZER_FUNCTION_JIT_OBJS) - PHP_FUZZER_TARGET([tracing-jit], PHP_FUZZER_TRACING_JIT_OBJS) - PHP_FUZZER_TARGET([unserialize], PHP_FUZZER_UNSERIALIZE_OBJS) - PHP_FUZZER_TARGET([unserializehash], PHP_FUZZER_UNSERIALIZEHASH_OBJS) - PHP_FUZZER_TARGET([json], PHP_FUZZER_JSON_OBJS) + PHP_FUZZER_TARGET([parser], [PHP_FUZZER_PARSER_OBJS]) + PHP_FUZZER_TARGET([execute], [PHP_FUZZER_EXECUTE_OBJS]) + PHP_FUZZER_TARGET([function-jit], [PHP_FUZZER_FUNCTION_JIT_OBJS]) + PHP_FUZZER_TARGET([tracing-jit], [PHP_FUZZER_TRACING_JIT_OBJS]) + PHP_FUZZER_TARGET([unserialize], [PHP_FUZZER_UNSERIALIZE_OBJS]) + PHP_FUZZER_TARGET([unserializehash], [PHP_FUZZER_UNSERIALIZEHASH_OBJS]) + PHP_FUZZER_TARGET([json], [PHP_FUZZER_JSON_OBJS]) if test -n "$enable_exif" && test "$enable_exif" != "no"; then - PHP_FUZZER_TARGET([exif], PHP_FUZZER_EXIF_OBJS) + PHP_FUZZER_TARGET([exif], [PHP_FUZZER_EXIF_OBJS]) fi if test -n "$enable_mbstring" && test "$enable_mbstring" != "no"; then - PHP_FUZZER_TARGET([mbstring], PHP_FUZZER_MBSTRING_OBJS) + PHP_FUZZER_TARGET([mbstring], [PHP_FUZZER_MBSTRING_OBJS]) if test -n "$enable_mbregex" && test "$enable_mbregex" != "no"; then - PHP_FUZZER_TARGET([mbregex], PHP_FUZZER_MBREGEX_OBJS) + PHP_FUZZER_TARGET([mbregex], [PHP_FUZZER_MBREGEX_OBJS]) fi fi diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4 index db201300cc8a6..bb226e7482cfa 100644 --- a/sapi/litespeed/config.m4 +++ b/sapi/litespeed/config.m4 @@ -10,18 +10,16 @@ if test "$PHP_LITESPEED" != "no"; then [sapi/litespeed]) SAPI_LITESPEED_PATH=sapi/litespeed/php PHP_SELECT_SAPI([litespeed], [program], [lsapi_main.c lsapilib.c]) - case $host_alias in - *darwin*) - BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - *cygwin*) - SAPI_LITESPEED_PATH=sapi/litespeed/php.exe - BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - *) - BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - esac + AS_CASE([$host_alias], + [*darwin*], [ + BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + ], + [*cygwin*], [ + SAPI_LITESPEED_PATH=sapi/litespeed/php.exe + BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_BINARY_OBJS) \$(PHP_LITESPEED_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + ], [ + BUILD_LITESPEED="\$(LIBTOOL) --tag=CC --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_BINARY_OBJS:.lo=.o) \$(PHP_LITESPEED_OBJS:.lo=.o) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" + ]) PHP_SUBST([SAPI_LITESPEED_PATH]) PHP_SUBST([BUILD_LITESPEED]) diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index d3a3ea2144548..2314068044fb8 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -608,7 +608,6 @@ int phpdbg_skip_line_helper(void) /* {{{ */ { || opline->opcode == ZEND_RETURN || opline->opcode == ZEND_FAST_RET || opline->opcode == ZEND_GENERATOR_RETURN - || opline->opcode == ZEND_EXIT || opline->opcode == ZEND_YIELD || opline->opcode == ZEND_YIELD_FROM ) { @@ -652,7 +651,6 @@ static void phpdbg_seek_to_end(void) /* {{{ */ { case ZEND_RETURN: case ZEND_FAST_RET: case ZEND_GENERATOR_RETURN: - case ZEND_EXIT: case ZEND_YIELD: case ZEND_YIELD_FROM: zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline); diff --git a/scripts/phpize.m4 b/scripts/phpize.m4 index 22f4477e7bc27..09adfa787b54c 100644 --- a/scripts/phpize.m4 +++ b/scripts/phpize.m4 @@ -26,10 +26,7 @@ AC_DEFUN([PHP_ALWAYS_SHARED],[ test "[$]$1" = "no" && $1=yes ])dnl -AS_VAR_IF([CFLAGS],, [auto_cflags=1]) - -abs_srcdir=`(cd $srcdir && pwd)` -abs_builddir=`pwd` +PHP_INIT_BUILD_SYSTEM PKG_PROG_PKG_CONFIG AC_PROG_CC([cc gcc]) @@ -65,8 +62,6 @@ PHP_EXECUTABLE=`$PHP_CONFIG --php-binary 2>/dev/null` AS_VAR_IF([prefix],, [AC_MSG_ERROR([Cannot find php-config. Please use --with-php-config=PATH])]) -PHP_INIT_BUILD_SYSTEM - AC_MSG_CHECKING([for PHP prefix]) AC_MSG_RESULT([$prefix]) AC_MSG_CHECKING([for PHP includes]) @@ -136,9 +131,6 @@ AS_VAR_IF([PHP_DEBUG], [yes], [ dnl Always shared. PHP_BUILD_SHARED -dnl Required programs. -PHP_PROG_AWK - PHP_HELP_SEPARATOR([Extension:]) PHP_CONFIGURE_PART([Configuring extension]) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index c4a617a2e16ec..08edb81d11947 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -240,7 +240,8 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c"); + zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \ + zend_lazy_objects.c"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); var PHP_ASSEMBLER = PATH_PROG({ @@ -393,7 +394,7 @@ ARG_WITH("test-ini-ext-exclude", "Comma separated list of shared extensions to \ be excluded from the test.ini", "no"); ARG_ENABLE("native-intrinsics", "Comma separated list of intrinsic optimizations to enable. \ - Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2. \ + Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2, avx512. \ SSE and SSE2 are enabled by default. The best instruction set specified will \ automatically enable all the older instruction sets. Note, that the produced binary \ might not work properly, if the chosen instruction sets are not available on the target \ diff --git a/win32/build/confutils.js b/win32/build/confutils.js index b72950954c0f7..95a4e5ce3c136 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1040,10 +1040,10 @@ function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env add_to_flag_only = true; } - if (typeof(add_to_flag_only) != "undefined") { + if (typeof(add_to_flag_only) != "undefined" && have) { ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have); - } else if (!configure_hdr.Exists('HAVE_' + sym)) { - AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); + } else if (!configure_hdr.Exists('HAVE_' + sym) && have) { + AC_DEFINE("HAVE_" + sym, have, "Define to 1 if you have the <" + header_name + "> header file."); } return p; @@ -3073,8 +3073,9 @@ function toolset_get_compiler_version() if (full.match(/clang version ([\d\.]+)/)) { version = RegExp.$1; version = version.replace(/\./g, ''); - version = version/100 < 1 ? version*10 : version; - + if (version < 400) { + ERROR("Building with clang " + version + " is no longer supported"); + } return version; } } else if (ICC_TOOLSET) { @@ -3240,7 +3241,7 @@ function toolset_setup_common_cflags() var envCFLAGS = WshShell.Environment("PROCESS").Item("CFLAGS"); // CFLAGS for building the PHP dll - DEFINE("CFLAGS_PHP", "/D _USRDLL /D PHP7DLLTS_EXPORTS /D PHP_EXPORTS \ + DEFINE("CFLAGS_PHP", "/D _USRDLL /D PHP_EXPORTS \ /D LIBZEND_EXPORTS /D TSRM_EXPORTS /D SAPI_EXPORTS /D WINVER=" + WINVER); DEFINE('CFLAGS_PHP_OBJ', '$(CFLAGS_PHP) $(STATIC_EXT_CFLAGS)'); @@ -3337,8 +3338,6 @@ function toolset_setup_common_cflags() function toolset_setup_intrinsic_cflags() { var default_enabled = "sse2"; - /* XXX AVX and above needs to be reflected in /arch, for now SSE4.2 is - the best possible optimization.*/ var avail = WScript.CreateObject("Scripting.Dictionary"); avail.Add("sse", "__SSE__"); avail.Add("sse2", "__SSE2__"); @@ -3347,7 +3346,7 @@ function toolset_setup_intrinsic_cflags() avail.Add("sse4.1", "__SSE4_1__"); avail.Add("sse4.2", "__SSE4_2__"); /* From oldest to newest. */ - var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2"); + var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512"); if (VS_TOOLSET) { if ("disabled" == PHP_NATIVE_INTRINSICS) { @@ -3373,9 +3372,9 @@ function toolset_setup_intrinsic_cflags() AC_DEFINE(avail.Item(list[i]), 1); } - /* All means all. __AVX__ and __AVX2__ are defined by compiler. */ - ADD_FLAG("CFLAGS","/arch:AVX2"); - configure_subst.Add("PHP_SIMD_SCALE", "AVX2"); + /* All means all. __AVX__, __AVX2__, and __AVX512*__ are defined by compiler. */ + ADD_FLAG("CFLAGS","/arch:AVX512"); + configure_subst.Add("PHP_SIMD_SCALE", "AVX512"); } else { var list = PHP_NATIVE_INTRINSICS.split(","); var j = 0; @@ -3384,7 +3383,7 @@ function toolset_setup_intrinsic_cflags() var it = list[i].toLowerCase(); if (scale[k] == it) { j = k > j ? k : j; - } else if (!avail.Exists(it) && "avx2" != it && "avx" != it) { + } else if (!avail.Exists(it) && "avx512" != it && "avx2" != it && "avx" != it) { WARNING("Unknown intrinsic name '" + it + "' ignored"); } } @@ -3401,7 +3400,10 @@ function toolset_setup_intrinsic_cflags() /* There is no explicit way to enable intrinsics between SSE3 and SSE4.2. The declared macros therefore won't affect the code generation, but will enable the guarded code parts. */ - if ("avx2" == scale[j]) { + if ("avx512" == scale[j]) { + ADD_FLAG("CFLAGS","/arch:AVX512"); + j -= 3; + } else if ("avx2" == scale[j]) { ADD_FLAG("CFLAGS","/arch:AVX2"); j -= 2; } else if ("avx" == scale[j]) { diff --git a/win32/dllmain.c b/win32/dllmain.c index a507f1e169246..38d143acfedb2 100644 --- a/win32/dllmain.c +++ b/win32/dllmain.c @@ -16,9 +16,8 @@ #include -#include -#include #include +#include #ifdef HAVE_LIBXML #include @@ -38,20 +37,6 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy) switch (reason) { case DLL_PROCESS_ATTACH: - /* - * We do not need to check the return value of php_win32_init_gettimeofday() - * because the symbol bare minimum symbol we need is always available on our - * lowest supported platform. - * - * On Windows 8 or greater, we use a more precise symbol to obtain the system - * time, which is dynamically. The fallback allows us to proper support - * Vista/7/Server 2003 R2/Server 2008/Server 2008 R2. - * - * Instead simply initialize the global in win32/time.c for gettimeofday() - * use later on - */ - php_win32_init_gettimeofday(); - ret = ret && php_win32_ioutil_init(); if (!ret) { fprintf(stderr, "ioutil initialization failed"); diff --git a/win32/time.c b/win32/time.c index d1fe51458ec57..ac1abbc9e9c7b 100644 --- a/win32/time.c +++ b/win32/time.c @@ -23,44 +23,15 @@ #include #include "php_win32_globals.h" -typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); - -static MyGetSystemTimeAsFileTime timefunc = NULL; - -#ifdef PHP_EXPORTS -static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void) -{/*{{{*/ - MyGetSystemTimeAsFileTime timefunc = NULL; - HMODULE hMod = GetModuleHandle("kernel32.dll"); - - if (hMod) { - /* Max possible resolution <1us, win8/server2012 */ - timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); - } - - if(!timefunc) { - /* 100ns blocks since 01-Jan-1641 */ - timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime; - } - - return timefunc; -}/*}}}*/ - -void php_win32_init_gettimeofday(void) -{/*{{{*/ - timefunc = get_time_func(); -}/*}}}*/ -#endif - -static zend_always_inline int getfilesystemtime(struct timeval *tv) +static zend_always_inline void getfilesystemtime(struct timeval *tv) {/*{{{*/ FILETIME ft; unsigned __int64 ff = 0; ULARGE_INTEGER fft; - timefunc(&ft); + GetSystemTimePreciseAsFileTime(&ft); - /* + /* * Do not cast a pointer to a FILETIME structure to either a * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows. * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx @@ -74,8 +45,6 @@ static zend_always_inline int getfilesystemtime(struct timeval *tv) tv->tv_sec = (long)(ff / 1000000Ui64); tv->tv_usec = (long)(ff % 1000000Ui64); - - return 0; }/*}}}*/ PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) diff --git a/win32/time.h b/win32/time.h index 51090ccfd8a8c..77d1cbfd311e1 100644 --- a/win32/time.h +++ b/win32/time.h @@ -54,10 +54,4 @@ PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp ); PHPAPI int usleep(unsigned int useconds); -#ifdef PHP_EXPORTS -/* This symbols are needed only for the DllMain, but should not be exported - or be available when used with PHP binaries. */ -void php_win32_init_gettimeofday(void); -#endif - #endif