diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml new file mode 100644 index 0000000000000..c21a34534aea8 --- /dev/null +++ b/.github/actions/apt-x64/action.yml @@ -0,0 +1,68 @@ +name: apt +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo apt-get update + sudo apt-get install \ + bison \ + re2c \ + locales \ + ldap-utils \ + openssl \ + slapd \ + language-pack-de \ + libgmp-dev \ + libicu-dev \ + libtidy-dev \ + libenchant-dev \ + libaspell-dev \ + libpspell-dev \ + libsasl2-dev \ + libxpm-dev \ + libzip-dev \ + libsqlite3-dev \ + libwebp-dev \ + libonig-dev \ + libkrb5-dev \ + libgssapi-krb5-2 \ + libcurl4-openssl-dev \ + libxml2-dev \ + libxslt1-dev \ + libpq-dev \ + libreadline-dev \ + libldap2-dev \ + libsodium-dev \ + libargon2-0-dev \ + libmm-dev \ + libsnmp-dev \ + postgresql \ + postgresql-contrib \ + snmpd \ + snmp-mibs-downloader \ + freetds-dev \ + unixodbc-dev \ + llvm \ + libc-client-dev \ + dovecot-core \ + dovecot-pop3d \ + dovecot-imapd \ + sendmail \ + firebird-dev \ + liblmdb-dev \ + libtokyocabinet-dev \ + libdb-dev \ + libqdbm-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev + mkdir /opt/oracle + wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip + unzip instantclient-basiclite-linuxx64.zip + wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-sdk-linuxx64.zip + unzip instantclient-sdk-linuxx64.zip + mv instantclient_*_* /opt/oracle/instantclient + # Interferes with libldap2 headers. + rm /opt/oracle/instantclient/sdk/include/ldap.h diff --git a/.github/actions/brew/action.yml b/.github/actions/brew/action.yml new file mode 100644 index 0000000000000..36b76392048d4 --- /dev/null +++ b/.github/actions/brew/action.yml @@ -0,0 +1,34 @@ +name: brew +runs: + using: composite + steps: + - shell: bash + run: | + set -x + brew install \ + pkg-config \ + autoconf \ + bison \ + re2c + brew install \ + openssl@1.1 \ + krb5 \ + bzip2 \ + enchant \ + libffi \ + libpng \ + webp \ + freetype \ + intltool \ + icu4c \ + libiconv \ + zlib \ + t1lib \ + gd \ + libzip \ + gmp \ + tidyp \ + libxml2 \ + libxslt \ + postgresql + brew link icu4c gettext --force diff --git a/.github/actions/configure-macos/action.yml b/.github/actions/configure-macos/action.yml new file mode 100644 index 0000000000000..852d8f62b68e1 --- /dev/null +++ b/.github/actions/configure-macos/action.yml @@ -0,0 +1,71 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export PATH="/usr/local/opt/bison/bin:$PATH" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/openssl@1.1/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxslt/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/icu4c/lib/pkgconfig" + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr/local \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + --with-pgsql=/usr/local/opt/libpq \ + --with-pdo-pgsql=/usr/local/opt/libpq \ + --with-pdo-sqlite \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + --with-tidy=/usr/local/opt/tidyp \ + --with-libxml \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline=/usr/local/opt/readline \ + --enable-mbstring \ + --with-curl \ + --with-gettext=/usr/local/opt/gettext \ + --enable-sockets \ + --with-bz2=/usr/local/opt/bzip2 \ + --with-openssl \ + --with-gmp=/usr/local/opt/gmp \ + --with-iconv=/usr/local/opt/libiconv \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --with-pspell=/usr/local/opt/aspell \ + --with-kerberos \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + --enable-intl \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --enable-werror \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/configure-x64/action.yml b/.github/actions/configure-x64/action.yml new file mode 100644 index 0000000000000..f9b774218f4ef --- /dev/null +++ b/.github/actions/configure-x64/action.yml @@ -0,0 +1,84 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + 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 \ + --with-pgsql \ + --with-pdo-pgsql \ + --with-pdo-sqlite \ + --enable-intl \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --with-xpm \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --with-zlib-dir=/usr \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + --with-tidy \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline \ + --enable-mbstring \ + --with-curl \ + --with-gettext \ + --enable-sockets \ + --with-bz2 \ + --with-openssl \ + --with-gmp \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --with-pspell=/usr \ + --with-enchant=/usr \ + --with-kerberos \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + --with-ldap \ + --with-ldap-sasl \ + --with-password-argon2 \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --with-cdb \ + --enable-flatfile \ + --enable-inifile \ + --with-tcadb \ + --with-lmdb \ + --with-qdbm \ + --with-snmp \ + --with-unixODBC \ + --with-imap \ + --with-kerberos \ + --with-imap-ssl \ + --with-pdo-odbc=unixODBC,/usr \ + --with-pdo-oci=shared,instantclient,/opt/oracle/instantclient \ + --with-oci8=shared,instantclient,/opt/oracle/instantclient \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + --with-pdo-firebird \ + --with-pdo-dblib \ + --enable-werror \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/install-linux/action.yml b/.github/actions/install-linux/action.yml new file mode 100644 index 0000000000000..6db48f0ec3e1d --- /dev/null +++ b/.github/actions/install-linux/action.yml @@ -0,0 +1,14 @@ +name: Install +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo make install + sudo mkdir /etc/php.d + sudo chmod 777 /etc/php.d + echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini + echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini + echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini + echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini diff --git a/.github/actions/mssql/action.yml b/.github/actions/mssql/action.yml new file mode 100644 index 0000000000000..894380644c1ea --- /dev/null +++ b/.github/actions/mssql/action.yml @@ -0,0 +1,14 @@ +name: Create mssql container +runs: + using: composite + steps: + - shell: bash + run: | + set -x + docker run \ + -e "ACCEPT_EULA=Y" \ + -e "SA_PASSWORD=" \ + -p 1433:1433 \ + --name sql1 \ + -h sql1 \ + -d mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04 diff --git a/.github/actions/setup-x64/action.yml b/.github/actions/setup-x64/action.yml new file mode 100644 index 0000000000000..6cec51d4c8079 --- /dev/null +++ b/.github/actions/setup-x64/action.yml @@ -0,0 +1,30 @@ +name: Setup +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + sudo service mysql start + sudo service postgresql start + sudo service slapd start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';" + sudo -u postgres psql -c "CREATE DATABASE test;" + docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U SA -P "" -Q "create login pdo_test with password='password', check_policy=off; create user pdo_test for login pdo_test; grant alter, control to pdo_test;" + sudo locale-gen de_DE + + ./.github/scripts/setup-slapd.sh + + sudo cp ext/snmp/tests/snmpd.conf /etc/snmp + sudo cp ext/snmp/tests/bigtest /etc/snmp + sudo service snmpd restart + + sudo groupadd -g 5000 vmail + sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail + sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf + sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass + sudo service dovecot restart diff --git a/.github/actions/test-linux/action.yml b/.github/actions/test-linux/action.yml new file mode 100644 index 0000000000000..c7dab609820dd --- /dev/null +++ b/.github/actions/test-linux/action.yml @@ -0,0 +1,27 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export MYSQL_TEST_USER=root + export MYSQL_TEST_PASSWD=root + export PDO_MYSQL_TEST_DSN="mysql:host=localhost;dbname=test" + export PDO_MYSQL_TEST_USER=root + export PDO_MYSQL_TEST_PASS=root + export PDO_DBLIB_TEST_DSN="dblib:host=127.0.0.1;dbname=master;version=7.0" + export PDO_DBLIB_TEST_USER="pdo_test" + export PDO_DBLIB_TEST_PASS="password" + export SKIP_IO_CAPTURE_TESTS=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -j$(/usr/bin/nproc) \ + -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/actions/test-macos/action.yml b/.github/actions/test-macos/action.yml new file mode 100644 index 0000000000000..99ac49b268c76 --- /dev/null +++ b/.github/actions/test-macos/action.yml @@ -0,0 +1,20 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export CI_NO_IPV6=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -j$(sysctl -n hw.ncpu) \ + -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh new file mode 100755 index 0000000000000..7ea3cb33b3d0e --- /dev/null +++ b/.github/scripts/setup-slapd.sh @@ -0,0 +1,185 @@ +#!/bin/sh +set -ev + +# Create TLS certificate +sudo mkdir -p /etc/ldap/ssl + +alt_names() { + ( + ( + (hostname && hostname -a && hostname -A && hostname -f) | + xargs -n 1 | + sort -u | + sed -e 's/\(\S\+\)/DNS:\1/g' + ) && ( + (hostname -i && hostname -I && echo "127.0.0.1 ::1") | + xargs -n 1 | + sort -u | + sed -e 's/\(\S\+\)/IP:\1/g' + ) + ) | paste -d, -s +} + +sudo openssl req -newkey rsa:4096 -x509 -nodes -days 3650 \ + -out /etc/ldap/ssl/server.crt -keyout /etc/ldap/ssl/server.key \ + -subj "/C=US/ST=Arizona/L=Localhost/O=localhost/CN=localhost" \ + -addext "subjectAltName = `alt_names`" + +sudo chown -R openldap:openldap /etc/ldap/ssl + +# Display the TLS certificate (should be world readable) +openssl x509 -noout -text -in /etc/ldap/ssl/server.crt + +# Point to the certificate generated +if ! grep -q 'TLS_CACERT \/etc\/ldap\/ssl\/server.crt' /etc/ldap/ldap.conf; then + sudo sed -e 's|^\s*TLS_CACERT|# TLS_CACERT|' -i /etc/ldap/ldap.conf + echo 'TLS_CACERT /etc/ldap/ssl/server.crt' | sudo tee -a /etc/ldap/ldap.conf +fi + +# Configure LDAP protocols to serve. +sudo sed -e 's|^\s*SLAPD_SERVICES\s*=.*$|SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"|' -i /etc/default/slapd + +# Configure LDAP database. +DBDN=`sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(&(olcRootDN=*)(olcSuffix=*))' dn | grep -i '^dn:' | sed -e 's/^dn:\s*//'`; + +sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif + +sudo service slapd restart + +sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: $DBDN +changetype: modify +replace: olcSuffix +olcSuffix: dc=my-domain,dc=com +- +replace: olcRootDN +olcRootDN: cn=Manager,dc=my-domain,dc=com +- +replace: olcRootPW +olcRootPW: secret + +dn: cn=config +changetype: modify +add: olcTLSCACertificateFile +olcTLSCACertificateFile: /etc/ldap/ssl/server.crt +- +add: olcTLSCertificateFile +olcTLSCertificateFile: /etc/ldap/ssl/server.crt +- +add: olcTLSCertificateKeyFile +olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key +- +add: olcTLSVerifyClient +olcTLSVerifyClient: never +- +add: olcAuthzRegexp +olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com +- +replace: olcLogLevel +olcLogLevel: -1 + +dn: cn=module{0},cn=config +changetype: modify +add: olcModuleLoad +olcModuleLoad: sssvlv +- +add: olcModuleLoad +olcModuleLoad: ppolicy +- +add: olcModuleLoad +olcModuleLoad: dds +EOF + +sudo service slapd restart + +sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: olcOverlay=sssvlv,$DBDN +objectClass: olcOverlayConfig +objectClass: olcSssVlvConfig +olcOverlay: sssvlv +olcSssVlvMax: 10 +olcSssVlvMaxKeys: 5 + +dn: olcOverlay=ppolicy,$DBDN +objectClass: olcOverlayConfig +objectClass: olcPPolicyConfig +olcOverlay: ppolicy +### This would clutter our DIT and make tests to fail, while ppolicy does not +### seem to work as we expect (it does not seem to provide expected controls) +## olcPPolicyDefault: cn=default,ou=pwpolicies,dc=my-domain,dc=com +## olcPPolicyHashCleartext: FALSE +## olcPPolicyUseLockout: TRUE + +dn: olcOverlay=dds,$DBDN +objectClass: olcOverlayConfig +objectClass: olcDdsConfig +olcOverlay: dds +EOF + +sudo service slapd restart + +sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: $DBDN +changetype: modify +add: olcDbIndex +olcDbIndex: entryExpireTimestamp eq +EOF + +sudo service slapd restart + +ldapadd -H ldapi:/// -D cn=Manager,dc=my-domain,dc=com -w secret <- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + uses: ./.github/actions/setup-x64 + - name: Test + uses: ./.github/actions/test-linux + - name: Test Tracing JIT + uses: ./.github/actions/test-linux + with: + runTestsParameters: -d zend_extension=opcache.so -d opcache.jit_buffer_size=16M + MACOS_DEBUG_NTS: + runs-on: macos-10.15 + steps: + - name: git checkout + uses: actions/checkout@v2 + - name: brew + uses: ./.github/actions/brew + - name: ./configure + uses: ./.github/actions/configure-macos + with: + configurationParameters: --enable-debug --disable-zts + - name: make + run: |- + export PATH="/usr/local/opt/bison/bin:$PATH" + make -j$(sysctl -n hw.logicalcpu) >/dev/null + - name: make install + run: sudo make install + - name: Test + uses: ./.github/actions/test-macos + - name: Test Tracing JIT + uses: ./.github/actions/test-macos + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.protect_memory=1 + -d opcache.jit_buffer_size=16M diff --git a/.github/workflows/remove-needs-feedback.yml b/.github/workflows/remove-needs-feedback.yml index 8f6dfc47f1664..fded33b442081 100644 --- a/.github/workflows/remove-needs-feedback.yml +++ b/.github/workflows/remove-needs-feedback.yml @@ -7,7 +7,7 @@ on: jobs: build: - if: "contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login" + if: "github.repository_owner == 'php' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login" runs-on: ubuntu-latest steps: - uses: actions-ecosystem/action-remove-labels@v1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd1ed6f4792cb..4d18eb2c98cbe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,7 @@ If you are fixing a bug, then please submit your PR against the lowest actively supported branch of PHP that the bug affects (only green branches on [the supported version page](https://www.php.net/supported-versions.php) are supported). For example, at the time of writing, the lowest supported version is -PHP 7.3, which corresponds to the `PHP-7.3` branch in Git. Please also make sure +PHP 8.0, which corresponds to the `PHP-8.0` branch in Git. Please also make sure you add a link to the PR in the bug on [the bug tracker](https://bugs.php.net/). Pull requests implementing RFCs should be submitted against `master`. @@ -58,8 +58,8 @@ and build PHP source code. We recommend to look at our ## Filing bugs -Bugs can be filed on the [PHP bug tracker](https://bugs.php.net/). If this is -the first time you've filed a bug, we suggest reading the +Bugs can be filed on [GitHub Issues](https://github.com/php/php-src/issues/new/choose). +If this is the first time you've filed a bug, we suggest reading the [guide to reporting a bug](https://bugs.php.net/how-to-report.php). Where possible, please include a self-contained reproduction case! @@ -332,9 +332,9 @@ Currently we have the following branches in use: | master | Active development branch for PHP 8.2, which is open for backwards incompatible changes and major internal API changes. | | PHP-8.1 | Is used to release the PHP 8.1.x series. This is a current stable version and is open for bugfixes only. | | PHP-8.0 | Is used to release the PHP 8.0.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.4 | Is used to release the PHP 7.4.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.3 | Is used to release the PHP 7.3.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.2 | Is used to release the PHP 7.2.x series. This is an old stable version and is open for security fixes only. | +| PHP-7.4 | Is used to release the PHP 7.4.x series. This is an old stable version and is open for security fixes only. | +| PHP-7.3 | This branch is closed. | +| PHP-7.2 | This branch is closed. | | PHP-7.1 | This branch is closed. | | PHP-7.0 | This branch is closed. | | PHP-5.6 | This branch is closed. | @@ -349,8 +349,8 @@ Currently we have the following branches in use: The next few rules are more of a technical nature: 1. All non-security bugfix changes should first go to the lowest bugfix branch - (i.e. 7.3) and then get merged up to all other branches. All security fixes - should go to the lowest security fixes branch (i.e 7.2). If a change is not + (i.e. 8.0) and then get merged up to all other branches. All security fixes + should go to the lowest security fixes branch (i.e 7.4). If a change is not needed for later branches (i.e. fixes for features which were dropped from later branches) an empty merge should be done. diff --git a/EXTENSIONS b/EXTENSIONS index bdc1b6d3a39ea..25cf9fbd6a981 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -250,7 +250,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: com_dotnet PRIMARY MAINTAINER: Wez Furlong (2003 - 2005) - Christoph M. Becker (2018 - 2020) + Christoph M. Becker (2018 - 2022) MAINTENANCE: Maintained STATUS: Windows SINCE: 5.0 @@ -313,7 +313,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: gd PRIMARY MAINTAINER: Pierre-Alain Joye (2002 - 2016) - Christoph M. Becker (2015 - 2020) + Christoph M. Becker (2015 - 2022) MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index 6a15be588547f..dffd7eab225d7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2021 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/NEWS b/NEWS index 0a53434c36a9f..75e3600f5480a 100644 --- a/NEWS +++ b/NEWS @@ -7,23 +7,37 @@ PHP NEWS - Core: . Fixed bug #81380 (Observer may not be initialized properly). (krakjoe) + . Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov) + . Fixed bug GH-7792 (Improve class type in error messages). (ilutov) - Intl: . Update all grandfathered language tags with preferred values + . Fixed GH-7939 (Cannot unserialize IntlTimeZone objects). (cmb) - OCI8: . Added oci8.prefetch_lob_size directive to tune LOB query performance . Support for building against Oracle Client libraries 10.1 and 10.2 has been dropped. Oracle Client libraries 11.2 or newer are now required. +- PDO_ODBC: + . Fixed bug #80909 (crash with persistent connections in PDO_ODBC). (Calvin + Buckley) + - Standard: . net_get_interfaces() also reports wireless network interfaces on Windows. (Yurun) . Finished AVIF support in getimagesize(). (Yannis Guyon) + . Fixed bug GH-7847 (stripos with large haystack has bad performance). + (ilutov) + . New function memory_reset_peak_usage(). (Patrick Allaert) - Zip: . add ZipArchive::clearError() method . add ZipArchive::getStreamName() method . add ZipArchive::getStreamIndex() method +- Session: + . Fixed bug GH-7787 (Improve session write failure message for user error + handlers). (ilutov) + <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/README.md b/README.md index 771562bf5d583..d9b7bab54dffd 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,9 @@ Extension Community Library - [PECL](https://pecl.php.net). ## Contributing -Contributions are most welcome by forking the -[GitHub repository](https://github.com/php/php-src) and sending a pull request. +The PHP source code is located in the Git repository at +[github.com/php/php-src](https://github.com/php/php-src). Contributions are most +welcome by forking the repository and sending a pull request. Discussions are done on GitHub, but depending on the topic can also be relayed to the official PHP developer mailing list internals@lists.php.net. @@ -114,19 +115,15 @@ New features require an RFC and must be accepted by the developers. See [Voting on PHP features](https://wiki.php.net/rfc/voting) for more information on the process. -Bug fixes **do not** require an RFC but require a bug tracker ticket. Open a -ticket at [bugs.php.net](https://bugs.php.net) and reference the bug id using -`#NNNNNN`. +Bug fixes don't require an RFC. If the bug has a GitHub issue, reference it in +the commit message using `GH-NNNNNN`. Use `#NNNNNN` for tickets in the old +[bugs.php.net](https://bugs.php.net) bug tracker. + Fix GH-7815: php_uname doesn't recognise latest Windows versions Fix #55371: get_magic_quotes_gpc() throws deprecation warning - After removing magic quotes, the get_magic_quotes_gpc function caused a - deprecated warning. get_magic_quotes_gpc can be used to detect the - magic_quotes behavior and therefore should not raise a warning at any time. - The patch removes this warning. - -See [Git workflow](https://wiki.php.net/vcs/gitworkflow) for more details on the -pull request workflow. +See [Git workflow](https://wiki.php.net/vcs/gitworkflow) for details on how pull +requests are merged. ### Guidelines for contributors diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index c8b95d034d15c..dc0ecff44ed1b 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -188,11 +188,16 @@ TSRM_API void tsrm_shutdown(void) next_p = p->next; for (j=0; jcount; j++) { if (p->storage[j]) { - if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j]); - } - if (!resource_types_table[j].fast_offset) { - free(p->storage[j]); + if (resource_types_table) { + if (!resource_types_table[j].done) { + if (resource_types_table[j].dtor) { + resource_types_table[j].dtor(p->storage[j]); + } + + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } + } } } } @@ -531,11 +536,13 @@ void ts_free_id(ts_rsrc_id id) while (p) { if (p->count > j && p->storage[j]) { - if (resource_types_table && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j]); - } - if (!resource_types_table[j].fast_offset) { - free(p->storage[j]); + if (resource_types_table) { + if (resource_types_table[j].dtor) { + resource_types_table[j].dtor(p->storage[j]); + } + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } } p->storage[j] = NULL; } @@ -729,13 +736,13 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void) #if defined(__APPLE__) && defined(__x86_64__) // TODO: Implement support for fast JIT ZTS code ??? return 0; -#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" : "=r" (ret)); return ret; -#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("leal _tsrm_ls_cache@ntpoff,%0" diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 941d502226687..63b42dc1864a2 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -147,7 +147,7 @@ TSRM_API const char *tsrm_api_name(void); # define __has_attribute(x) 0 #endif -#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) +#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__) # define TSRM_TLS_MODEL_ATTR #elif __PIC__ # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec"))) diff --git a/UPGRADING b/UPGRADING index 4d918a85bfc17..b91229ec627ea 100644 --- a/UPGRADING +++ b/UPGRADING @@ -114,6 +114,10 @@ PHP 8.2 UPGRADE NOTES 6. New Functions ======================================== +- Standard: + . The peak memory usage can now be reset to the current usage thanks to + memory_reset_peak_usage(). + ======================================== 7. New Classes and Interfaces ======================================== @@ -126,6 +130,14 @@ PHP 8.2 UPGRADE NOTES 9. Other Changes to Extensions ======================================== +- Intl: + . IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator, + IntlPartsIterator, IntlCalendar, IntlCalendar, Collator, IntlIterator, + UConverter, IntlDateFormatter, IntlDatePatternGenerator, MessageFormatter, + ResourceBundle, Spoofchecker, IntlTimeZone and Transliterator instances are + no longer serializable. Previously, they could be serialized, but + unserialization yielded unusable objects or failed. + - OCI8: . The minimum Oracle Client library version required is now 11.2. diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 7175f0b54b4db..28fcb5e5a9540 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -17,6 +17,9 @@ PHP 8.2 INTERNALS UPGRADE NOTES zend_binary_str(n)casecmp() as one would expect. Call the appropriate wrapped function directly instead. * Removed the (ZEND_)WRONG_PARAM_COUNT_WITH_RETVAL() macros. +* php_stristr() no longer lowercases the haystack and needle as a side effect. + Call zend_str_tolower() yourself if necessary. You no longer need to copy + the haystack and needle before passing them to php_stristr(). ======================== 2. Build system changes @@ -26,6 +29,12 @@ PHP 8.2 INTERNALS UPGRADE NOTES 3. Module changes ======================== + a. ext/standard + - The PHP APIs string_natural_compare_function_ex(), + string_natural_case_compare_function(), and string_natural_compare_function() + have been removed. They always returned SUCCESS and were a wrapper around + strnatcmp_ex(). Use strnatcmp_ex() directly instead. + ======================== 4. OpCode changes ======================== diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index eac6d6b37aa73..e7f62a6814935 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -166,7 +166,13 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } else { zval c; ZVAL_COPY(&c, &ZEND_OP1_LITERAL(src)); - if (zend_optimizer_update_op1_const(op_array, opline, &c)) { + if (opline->opcode != ZEND_CASE + && opline->opcode != ZEND_CASE_STRICT + && opline->opcode != ZEND_FETCH_LIST_R + && opline->opcode != ZEND_SWITCH_LONG + && opline->opcode != ZEND_SWITCH_STRING + && opline->opcode != ZEND_MATCH + && zend_optimizer_update_op1_const(op_array, opline, &c)) { VAR_SOURCE(op1) = NULL; literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); @@ -613,53 +619,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; - case ZEND_JMPZNZ: - while (1) { - if (opline->op1_type == IS_CONST) { - ++(*opt_count); - if (zend_is_true(&ZEND_OP1_LITERAL(opline))) { - zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - block->successors[0] = block->successors[1]; - } else { - zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - } - block->successors_count = 1; - opline->op1_type = IS_UNUSED; - opline->extended_value = 0; - opline->opcode = ZEND_JMP; - break; - } else if (opline->op1_type == IS_TMP_VAR && - !zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) { - src = VAR_SOURCE(opline->op1); - if (src) { - if (src->opcode == ZEND_BOOL_NOT) { - /* T = BOOL_NOT(X) + JMPZNZ(T,L1,L2) -> NOP, JMPZNZ(X,L2,L1) */ - uint32_t tmp; - - VAR_SOURCE(opline->op1) = NULL; - COPY_NODE(opline->op1, src->op1); - tmp = block->successors[0]; - block->successors[0] = block->successors[1]; - block->successors[1] = tmp; - MAKE_NOP(src); - ++(*opt_count); - continue; - } else if (src->opcode == ZEND_BOOL || - src->opcode == ZEND_QM_ASSIGN) { - VAR_SOURCE(opline->op1) = NULL; - COPY_NODE(opline->op1, src->op1); - MAKE_NOP(src); - ++(*opt_count); - continue; - } - } - } - break; - } - break; - case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: while (1) { @@ -1025,9 +984,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op case ZEND_JMP: ZEND_SET_OP_JMP_ADDR(opline, opline->op1, new_opcodes + blocks[b->successors[0]].start); break; - case ZEND_JMPZNZ: - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[1]].start); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1239,20 +1195,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr block->len--; } else if (target_block->len == 1) { target = op_array->opcodes + target_block->start; - if (target->opcode == ZEND_JMPZNZ) { - /* JMP L, L: JMPZNZ L1,L2 -> JMPZNZ L1,L2 */ - *last_op = *target; - if (last_op->op1_type == IS_CONST) { - zval zv; - ZVAL_COPY(&zv, &ZEND_OP1_LITERAL(last_op)); - last_op->op1.constant = zend_optimizer_add_literal(op_array, &zv); - } - block->successors_count = 2; - block->successors[0] = target_block->successors[0]; - block->successors[1] = target_block->successors[1]; - ++(*opt_count); - goto optimize_jmpznz; - } else if ((target->opcode == ZEND_RETURN || + if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || target->opcode == ZEND_GENERATOR_RETURN || target->opcode == ZEND_EXIT) && @@ -1311,10 +1254,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr SAME_VAR(target->op1, last_op->op1)) { /* JMPZ(X, L), L: JMPNZ(X, L2) -> JMPZ(X, L+1) */ next = target_block->successors[1]; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZ(X, L), L: JMPZNZ(X, L2, L3) -> JMPZ(X, L2) */ - next = target_block->successors[last_op->opcode == ZEND_JMPNZ]; } else { break; } @@ -1327,14 +1266,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr follow_block = get_follow_block(cfg, block, 1, opt_count); if (target_block == follow_block) { /* L: JMP[N]Z(X, L+1) -> NOP or FREE(X) */ - if (last_op->op1_type == IS_CV) { - last_op->opcode = ZEND_CHECK_VAR; - last_op->op2.num = 0; - } else if (last_op->op1_type & (IS_VAR|IS_TMP_VAR)) { - last_op->opcode = ZEND_FREE; - last_op->op2.num = 0; - } else { - MAKE_NOP(last_op); + zend_optimizer_convert_to_free_op1(op_array, last_op); + if (last_op->opcode == ZEND_NOP) { block->len--; } block->successors_count = 1; @@ -1344,14 +1277,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr if (target->opcode == ZEND_JMP) { if (block->successors[0] == follow_block->successors[0]) { /* JMPZ(X,L1), JMP(L1) -> NOP, JMP(L1) */ - if (last_op->op1_type == IS_CV) { - last_op->opcode = ZEND_CHECK_VAR; - last_op->op2.num = 0; - } else if (last_op->op1_type & (IS_VAR|IS_TMP_VAR)) { - last_op->opcode = ZEND_FREE; - last_op->op2.num = 0; - } else { - MAKE_NOP(last_op); + zend_optimizer_convert_to_free_op1(op_array, last_op); + if (last_op->opcode == ZEND_NOP) { block->len--; } block->successors[0] = follow_block - cfg->blocks; @@ -1378,16 +1305,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr break; } } - - /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ - if (last_op->opcode == ZEND_JMPZ) { - block->successors[1] = follow_block->successors[0]; - } else { - block->successors[1] = block->successors[0]; - block->successors[0] = follow_block->successors[0]; - } - last_op->opcode = ZEND_JMPZNZ; - ++(*opt_count); } } break; @@ -1414,11 +1331,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr SAME_VAR(target->op1, last_op->op1))) { /* T = JMPZ_EX(X, L1), L1: T = JMPZ_EX({X|T}, L2) -> T = JMPZ_EX(X, L2) */ next = target_block->successors[0]; - } else if (target->opcode == ZEND_JMPZNZ && - (SAME_VAR(target->op1, last_op->result) || - SAME_VAR(target->op1, last_op->op1))) { - /* T = JMPZ_EX(X, L), L: JMPZNZ({X|T}, L2, L3) -> T = JMPZ_EX(X, L2) */ - next = target_block->successors[last_op->opcode == ZEND_JMPNZ_EX]; } else if (target->opcode == INV_EX_COND(last_op->opcode) && (SAME_VAR(target->op1, last_op->result) || SAME_VAR(target->op1, last_op->op1))) { @@ -1465,85 +1377,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr break; } break; - - case ZEND_JMPZNZ: { -optimize_jmpznz: - jmp_hitlist_count = 0; - target_block = get_target_block(cfg, block, 0, opt_count); - while (target_block->len == 1) { - target = op_array->opcodes + target_block->start; - - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X, L1, L2), L1: JMP(L3) -> JMPZNZ(X, L3, L2) */ - next = target_block->successors[0]; - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - next = target_block->successors[0]; - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - next = target_block->successors[1]; - } else { - break; - } - CHECK_LOOP(next); - block->successors[0] = next; - ++(*opt_count); - target_block = get_target_block(cfg, block, 0, opt_count); - } - - jmp_hitlist_count = 0; - follow_block = get_target_block(cfg, block, 1, opt_count); - while (follow_block->len == 1) { - target = op_array->opcodes + follow_block->start; - - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X, L1, L2), L2: JMP(L3) -> JMPZNZ(X, L1, L3) */ - next = follow_block->successors[0]; - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L2: X = JMPNZ(X, L3) -> JMPZNZ(X, L1, L3) */ - next = follow_block->successors[0]; - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L2: JMPZ(X, L3) -> JMPZNZ(X, L1, L2+1) */ - next = follow_block->successors[1]; - } else { - break; - } - CHECK_LOOP(next); - block->successors[1] = next; - ++(*opt_count); - follow_block = get_target_block(cfg, block, 1, opt_count); - } - - next_block = get_next_block(cfg, block); - if (target_block == follow_block && - !(last_op->op1_type & (IS_VAR|IS_TMP_VAR))) { - /* JMPZNZ(?,L,L) -> JMP(L) */ - last_op->opcode = ZEND_JMP; - SET_UNUSED(last_op->op1); - SET_UNUSED(last_op->op2); - last_op->extended_value = 0; - block->successors_count = 1; - ++(*opt_count); - } else if (target_block == next_block) { - /* jumping to next on Z - can follow to it and jump only on NZ */ - /* JMPZNZ(X,L1,L2) L1: -> JMPNZ(X,L2) */ - int tmp = block->successors[0]; - last_op->opcode = ZEND_JMPNZ; - block->successors[0] = block->successors[1]; - block->successors[1] = tmp; - ++(*opt_count); - } else if (follow_block == next_block) { - /* jumping to next on NZ - can follow to it and jump only on Z */ - /* JMPZNZ(X,L1,L2) L2: -> JMPZ(X,L1) */ - last_op->opcode = ZEND_JMPZ; - ++(*opt_count); - } - break; - } } } @@ -1704,18 +1537,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use case ZEND_QM_ASSIGN: case ZEND_BOOL: case ZEND_BOOL_NOT: - if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - SET_UNUSED(opline->result); - } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { - opline->opcode = ZEND_FREE; - SET_UNUSED(opline->result); - } else { - if (opline->op1_type == IS_CONST) { - literal_dtor(&ZEND_OP1_LITERAL(opline)); - } - MAKE_NOP(opline); - } + zend_optimizer_convert_to_free_op1(op_array, opline); break; case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 087add4cbed66..347d71300e324 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -139,7 +139,6 @@ static inline bool may_have_side_effects( case ZEND_JMP: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: @@ -398,7 +397,8 @@ static inline bool is_free_of_live_var(context *ctx, zend_op *opline, zend_ssa_o switch (opline->opcode) { case ZEND_FREE: /* It is always safe to remove FREEs of non-refcounted values, even if they are live. */ - if (!may_be_refcounted(ctx->ssa->var_info[ssa_op->op1_use].type)) { + if ((ctx->ssa->var_info[ssa_op->op1_use].type & (MAY_BE_REF|MAY_BE_ANY|MAY_BE_UNDEF)) != 0 + && !may_be_refcounted(ctx->ssa->var_info[ssa_op->op1_use].type)) { return 0; } ZEND_FALLTHROUGH; diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 0218a77d3f950..66c001746d799 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -627,11 +627,6 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa ZEND_ASSERT(ZEND_OP1_JMP_ADDR(opline) == op_array->opcodes + old->start); ZEND_SET_OP_JMP_ADDR(opline, opline->op1, op_array->opcodes + dst->start); break; - case ZEND_JMPZNZ: - if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) { - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, dst->start); - } - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -809,49 +804,6 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) } } break; - case ZEND_JMPZNZ: - if (opline->op1_type == IS_CONST) { - if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) { - zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - take_successor_1(ssa, block_num, block); - } else { - zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - take_successor_0(ssa, block_num, block); - } - opline->op1_type = IS_UNUSED; - opline->extended_value = 0; - opline->opcode = ZEND_JMP; - goto optimize_jmp; - } else if (block->successors_count == 2) { - if (block->successors[0] == block->successors[1]) { - take_successor_0(ssa, block_num, block); - if (block->successors[0] == next_block_num && can_follow) { - if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_UNDEF)) { - opline->opcode = ZEND_CHECK_VAR; - opline->op2.num = 0; - } else if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - zend_ssa_remove_instr(ssa, opline, ssa_op); - removed_ops++; - goto optimize_nop; - } else { - opline->opcode = ZEND_FREE; - opline->op2.num = 0; - } - } else if ((opline->op1_type == IS_CV && !(OP1_INFO() & MAY_BE_UNDEF)) || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - ZEND_ASSERT(ssa_op->op1_use >= 0); - zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use); - ssa_op->op1_use = -1; - ssa_op->op1_use_chain = -1; - opline->opcode = ZEND_JMP; - opline->op1_type = IS_UNUSED; - opline->op1.num = opline->op2.num; - goto optimize_jmp; - } - } - } - break; case ZEND_JMPZ_EX: if (ssa->vars[ssa_op->result_def].use_chain < 0 && ssa->vars[ssa_op->result_def].phi_use_chain == NULL) { @@ -1293,30 +1245,52 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx } else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE && opline->op1_type != IS_CONST && ssa->ops[op_1].op1_def == v - && ssa->ops[op_1].op1_use >= 0 - && ssa->ops[op_1].op1_use_chain == -1 - && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { + && ssa->ops[op_1].op1_use >= 0) { + int orig_var = ssa->ops[op_1].op1_use; + int ret = ssa->vars[v].use_chain; + + if (ssa->ops[op_1].op1_use_chain == -1 + && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { // op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP - int orig_var = ssa->ops[op_1].op1_use; - zend_ssa_unlink_use_chain(ssa, op_1, orig_var); + zend_ssa_unlink_use_chain(ssa, op_1, orig_var); + + if (ret >= 0) { + ssa->ops[ret].op1_use = orig_var; + ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain; + ssa->vars[orig_var].use_chain = ret; + } + + ssa->vars[v].definition = -1; + ssa->vars[v].use_chain = -1; + + ssa->ops[op_1].op1_def = -1; + ssa->ops[op_1].op1_use = -1; + + MAKE_NOP(opline); + remove_nops = 1; + } else if (ret >= 0 + && ssa->ops[ret].op1_use == v + && ssa->ops[ret].op1_use_chain == -1 + && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { + +// op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP + + zend_ssa_replace_use_chain(ssa, op_1, ret, orig_var); - int ret = ssa->vars[v].use_chain; - if (ret >= 0) { ssa->ops[ret].op1_use = orig_var; - ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain; - ssa->vars[orig_var].use_chain = ret; - } + ssa->ops[ret].op1_use_chain = ssa->ops[op_1].op1_use_chain; - ssa->vars[v].definition = -1; - ssa->vars[v].use_chain = -1; + ssa->vars[v].definition = -1; + ssa->vars[v].use_chain = -1; - ssa->ops[op_1].op1_def = -1; - ssa->ops[op_1].op1_use = -1; + ssa->ops[op_1].op1_def = -1; + ssa->ops[op_1].op1_use = -1; - MAKE_NOP(opline); - remove_nops = 1; + MAKE_NOP(opline); + remove_nops = 1; + } } } @@ -1330,6 +1304,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if (src_var >= 0 && !(ssa->var_info[src_var].type & MAY_BE_REF) + && (ssa->var_info[src_var].type & (MAY_BE_UNDEF|MAY_BE_ANY)) && ssa->vars[src_var].definition >= 0 && ssa->ops[ssa->vars[src_var].definition].result_def == src_var && ssa->ops[ssa->vars[src_var].definition].result_use < 0 @@ -1489,6 +1464,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && src_var >= 0 && !(ssa->var_info[src_var].type & MAY_BE_REF) + && (ssa->var_info[src_var].type & (MAY_BE_UNDEF|MAY_BE_ANY)) && ssa->vars[src_var].definition >= 0 && ssa->ops[ssa->vars[src_var].definition].result_def == src_var && ssa->ops[ssa->vars[src_var].definition].result_use < 0 diff --git a/Zend/Optimizer/optimize_func_calls.c b/Zend/Optimizer/optimize_func_calls.c index e2e16f90b8654..846b34b46f457 100644 --- a/Zend/Optimizer/optimize_func_calls.c +++ b/Zend/Optimizer/optimize_func_calls.c @@ -43,7 +43,7 @@ typedef struct _optimizer_call_info { uint32_t func_arg_num; } optimizer_call_info; -static void zend_delete_call_instructions(zend_op *opline) +static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opline) { int call = 0; @@ -73,17 +73,7 @@ static void zend_delete_call_instructions(zend_op *opline) case ZEND_SEND_VAL: case ZEND_SEND_VAR: if (call == 0) { - if (opline->op1_type == IS_CONST) { - MAKE_NOP(opline); - } else if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - opline->extended_value = 0; - opline->result.var = 0; - } else { - opline->opcode = ZEND_FREE; - opline->extended_value = 0; - opline->result.var = 0; - } + zend_optimizer_convert_to_free_op1(op_array, opline); } break; } @@ -144,7 +134,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o MAKE_NOP(opline); } - zend_delete_call_instructions(opline-1); + zend_delete_call_instructions(op_array, opline-1); } } } @@ -200,14 +190,18 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; - opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + if (opline->opcode != ZEND_CALLABLE_CONVERT) { + opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + } } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); literal_dtor(&op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]); fcall->op2.constant = fcall->op2.constant + 1; - opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + if (opline->opcode != ZEND_CALLABLE_CONVERT) { + opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + } } else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL || fcall->opcode == ZEND_INIT_METHOD_CALL || fcall->opcode == ZEND_NEW) { diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 4477a0270a393..770f4ce2dc231 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -27,7 +27,6 @@ * - pre-evaluate constant function calls */ -#include "php.h" #include "Optimizer/zend_optimizer.h" #include "Optimizer/zend_optimizer_internal.h" #include "zend_API.h" @@ -252,94 +251,16 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } } - /* pre-evaluate constant functions: - constant(x) - function_exists(x) - is_callable(x) - extension_loaded(x) - */ - if (!send2_opline && - Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING) { - if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "function_exists") || - zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "is_callable")) { - zend_internal_function *func; - zend_string *lc_name = zend_string_tolower( - Z_STR(ZEND_OP1_LITERAL(send1_opline))); - - if ((func = zend_hash_find_ptr(EG(function_table), lc_name)) != NULL - && func->type == ZEND_INTERNAL_FUNCTION - && func->module->type == MODULE_PERSISTENT -#ifdef ZEND_WIN32 - && func->module->handle == NULL -#endif - ) { - ZVAL_TRUE(&result); - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } - zend_string_release_ex(lc_name, 0); - break; - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "extension_loaded")) { - zend_string *lc_name = zend_string_tolower( - Z_STR(ZEND_OP1_LITERAL(send1_opline))); - zend_module_entry *m = zend_hash_find_ptr(&module_registry, - lc_name); - - zend_string_release_ex(lc_name, 0); - if (!m) { - if (PG(enable_dl)) { - break; - } else { - ZVAL_FALSE(&result); - } - } else { - if (m->type == MODULE_PERSISTENT -#ifdef ZEND_WIN32 - && m->handle == NULL -#endif - ) { - ZVAL_TRUE(&result); - } else { - break; - } - } - - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - break; - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "constant")) { - if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &result, 1)) { - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } - break; - /* dirname(IS_CONST/IS_STRING) -> IS_CONST/IS_STRING */ - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "dirname") && - IS_ABSOLUTE_PATH(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) { - zend_string *dirname = zend_string_init(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)), 0); - ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); - if (IS_ABSOLUTE_PATH(ZSTR_VAL(dirname), ZSTR_LEN(dirname))) { - ZVAL_STR(&result, dirname); - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } else { - zend_string_release_ex(dirname, 0); - } - break; - } + if (!send2_opline && Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING && + zend_optimizer_eval_special_func_call(&result, Z_STR(ZEND_OP2_LITERAL(init_opline)), Z_STR(ZEND_OP1_LITERAL(send1_opline))) == SUCCESS) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); + replace_by_const_or_qm_assign(op_array, opline, &result); + break; } + /* don't collect constants after any other function call */ collect_constants = 0; break; @@ -414,23 +335,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) collect_constants = 0; break; - case ZEND_JMPZNZ: - if (opline->op1_type == IS_CONST) { - zend_op *target_opline; - - if (zend_is_true(&ZEND_OP1_LITERAL(opline))) { - target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); /* JMPNZ */ - } else { - target_opline = ZEND_OP2_JMP_ADDR(opline); /* JMPZ */ - } - literal_dtor(&ZEND_OP1_LITERAL(opline)); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - opline->op1_type = IS_UNUSED; - opline->opcode = ZEND_JMP; - } - collect_constants = 0; - break; - case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 2b0fa7aa52ebc..93e431fece440 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -86,19 +86,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (target == opline + 1) { /* convert L: JMP L+1 to NOP */ MAKE_NOP(opline); - } else if (target->opcode == ZEND_JMPZNZ) { - /* JMP L, L: JMPZNZ L1,L2 -> JMPZNZ L1,L2 */ - *opline = *target; - if (opline->op1_type == IS_CONST) { - zval zv; - ZVAL_COPY(&zv, &ZEND_OP1_LITERAL(opline)); - opline->op1.constant = zend_optimizer_add_literal(op_array, &zv); - } - /* Jump addresses may be encoded as offsets, recompute them. */ - ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target)); - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, - ZEND_OFFSET_TO_OPLINE(target, target->extended_value)); - goto optimize_jmpznz; } else if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || target->opcode == ZEND_GENERATOR_RETURN || @@ -116,24 +103,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) (opline-1)->opcode == ZEND_JMPNZ)) { if (ZEND_OP2_JMP_ADDR(opline-1) == target) { /* JMPZ(X,L1), JMP(L1) -> NOP, JMP(L1) */ - if ((opline-1)->op1_type == IS_CV) { - (opline-1)->opcode = ZEND_CHECK_VAR; - (opline-1)->op2.num = 0; - } else if ((opline-1)->op1_type & (IS_TMP_VAR|IS_VAR)) { - (opline-1)->opcode = ZEND_FREE; - (opline-1)->op2.num = 0; - } else { - MAKE_NOP(opline-1); - } - } else { - /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ - if ((opline-1)->opcode == ZEND_JMPZ) { - (opline-1)->extended_value = ZEND_OPLINE_TO_OFFSET((opline-1), target); - } else { - (opline-1)->extended_value = ZEND_OPLINE_TO_OFFSET((opline-1), ZEND_OP2_JMP_ADDR(opline-1)); - ZEND_SET_OP_JMP_ADDR((opline-1), (opline-1)->op2, target); - } - (opline-1)->opcode = ZEND_JMPZNZ; + zend_optimizer_convert_to_free_op1(op_array, opline - 1); } } break; @@ -178,12 +148,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* convert JMPZ(X,L1), L1: JMPNZ(X,L2) to JMPZ(X,L1+1) */ target = target + 1; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(opline->op1, target->op1)) { - target = (opline->opcode == ZEND_JMPZ) ? - ZEND_OP2_JMP_ADDR(target) : - ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); } else if (target->opcode == ZEND_NOP) { target = target + 1; } else { @@ -194,15 +158,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* convert L: JMPZ L+1 to NOP */ if (target == opline + 1) { - if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - opline->op2.num = 0; - } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { - opline->opcode = ZEND_FREE; - opline->op2.num = 0; - } else { - MAKE_NOP(opline); - } + zend_optimizer_convert_to_free_op1(op_array, opline); } break; @@ -232,14 +188,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) JMPZ_EX(X,L2) */ target = ZEND_OP2_JMP_ADDR(target); CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPZNZ && - (SAME_VAR(target->op1, opline->result) || - SAME_VAR(target->op1, opline->op1))) { - /* Check for JMPZNZ with same cond variable */ - target = (opline->opcode == ZEND_JMPZ_EX) ? - ZEND_OP2_JMP_ADDR(target) : - ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); } else if (target->opcode == INV_EX_COND(opline->opcode) && (SAME_VAR(target->op1, opline->result) || SAME_VAR(target->op1, opline->op1))) { @@ -284,74 +232,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) opline->op2.num = 0; } break; - - case ZEND_JMPZNZ: -optimize_jmpznz: - jmp_hitlist_count = 0; - target = ZEND_OP2_JMP_ADDR(opline); - while (1) { - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X,L1,L2), L1: JMP(L3) => JMPZNZ(X,L3,L2), L1: JMP(L3) */ - target = ZEND_OP1_JMP_ADDR(target); - CHECK_LOOP(target); - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = ZEND_OP2_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - target = target + 1; - } else if (target->opcode == ZEND_NOP) { - target = target + 1; - } else { - break; - } - ZEND_SET_OP_JMP_ADDR(opline, opline->op2, target); - } - - jmp_hitlist_count = 0; - target = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - while (1) { - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X,L1,L2), L2: JMP(L3) => JMPZNZ(X,L1,L3), L2: JMP(L3) */ - target = ZEND_OP1_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - target = ZEND_OP2_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = target + 1; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_NOP) { - target = target + 1; - } else { - break; - } - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, target); - } - - if (ZEND_OP2_JMP_ADDR(opline) == target && - !(opline->op1_type & (IS_VAR|IS_TMP_VAR))) { - /* JMPZNZ(?,L,L) -> JMP(L) */ - opline->opcode = ZEND_JMP; - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target); - SET_UNUSED(opline->op1); - SET_UNUSED(opline->op2); - opline->extended_value = 0; - } - /* Don't convert JMPZNZ back to JMPZ/JMPNZ, because the - following JMP is not removed yet. */ - break; } opline++; } diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index df323b9000075..17af8bd62bd39 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -181,7 +181,8 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, zval *new) { } #if ZEND_DEBUG - ZEND_ASSERT(zend_is_identical(value, new)); + ZEND_ASSERT(zend_is_identical(value, new) || + (Z_TYPE_P(value) == IS_DOUBLE && Z_TYPE_P(new) == IS_DOUBLE && isnan(Z_DVAL_P(value)) && isnan(Z_DVAL_P(new)))); #endif } @@ -785,27 +786,9 @@ static inline zend_result ct_eval_func_call( return FAILURE; } - if (num_args == 1) { - /* Handle a few functions for which we manually implement evaluation here. */ - if (zend_string_equals_literal(name, "ini_get")) { - zend_ini_entry *ini_entry; - - if (Z_TYPE_P(args[0]) != IS_STRING) { - return FAILURE; - } - - ini_entry = zend_hash_find_ptr(EG(ini_directives), Z_STR_P(args[0])); - if (!ini_entry) { - ZVAL_FALSE(result); - } else if (ini_entry->modifiable != ZEND_INI_SYSTEM) { - return FAILURE; - } else if (ini_entry->value) { - ZVAL_STR_COPY(result, ini_entry->value); - } else { - ZVAL_EMPTY_STRING(result); - } - return SUCCESS; - } + if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING && + zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) { + return SUCCESS; } if (!can_ct_eval_func_call(func, name, num_args, args)) { @@ -1396,13 +1379,13 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o dup_partial_object(&zv, op1); ct_eval_assign_obj(&zv, &tmp2, op2); - if (opline->opcode == ZEND_PRE_INC_OBJ - || opline->opcode == ZEND_PRE_DEC_OBJ) { + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_PRE_DEC_OBJ) { SET_RESULT(result, &tmp2); - zval_ptr_dtor_nogc(&tmp1); } else { SET_RESULT(result, &tmp1); } + zval_ptr_dtor_nogc(&tmp1); + zval_ptr_dtor_nogc(&tmp2); SET_RESULT(op1, &zv); zval_ptr_dtor_nogc(&zv); break; @@ -1803,7 +1786,6 @@ static void sccp_mark_feasible_successors( switch (opline->opcode) { case ZEND_JMPZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: { if (ct_eval_bool_cast(&zv, op1) == FAILURE) { @@ -2126,21 +2108,31 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, value); } return 0; - } else { - zend_ssa_remove_result_def(ssa, ssa_op); - if (opline->opcode == ZEND_DO_ICALL) { - removed_ops = remove_call(ctx, opline, ssa_op); - } else if (opline->opcode == ZEND_TYPE_CHECK - && (opline->op1_type & (IS_VAR|IS_TMP_VAR)) - && (!value_known(&ctx->values[ssa_op->op1_use]) - || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use]) - || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) { + } else if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) + && (!value_known(&ctx->values[ssa_op->op2_use]) + || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op2_use]) + || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op2_use]))) { + return 0; + } else if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) + && (!value_known(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) { + if (opline->opcode == ZEND_TYPE_CHECK + || opline->opcode == ZEND_BOOL) { + zend_ssa_remove_result_def(ssa, ssa_op); /* For TYPE_CHECK we may compute the result value without knowing the * operand, based on type inference information. Make sure the operand is * freed and leave further cleanup to DCE. */ opline->opcode = ZEND_FREE; opline->result_type = IS_UNUSED; removed_ops++; + } else { + return 0; + } + } else { + zend_ssa_remove_result_def(ssa, ssa_op); + if (opline->opcode == ZEND_DO_ICALL) { + removed_ops = remove_call(ctx, opline, ssa_op); } else { zend_ssa_remove_instr(ssa, opline, ssa_op); removed_ops++; diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 380286cc0bf56..cc946c1b9ef3a 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -76,7 +76,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc } } else { ZEND_ASSERT(b->successors_count == 2); - if (i == 0 || opcode == ZEND_JMPZNZ) { + if (i == 0) { succ->flags |= ZEND_BB_TARGET; } else { succ->flags |= ZEND_BB_FOLLOW; @@ -361,13 +361,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, BB_START(i + 1); } break; - case ZEND_JMPZNZ: - BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes); - BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); - if (i + 1 < op_array->last) { - BB_START(i + 1); - } - break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -519,11 +512,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, block->successors_count = 1; block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes]; break; - case ZEND_JMPZNZ: - block->successors_count = 2; - block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes]; - block->successors[1] = block_map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]; - break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -684,6 +672,11 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze int blocks_count = cfg->blocks_count; int j, k, changed; + if (cfg->blocks_count == 1) { + blocks[0].level = 0; + return; + } + ALLOCA_FLAG(use_heap) int *postnum = do_alloca(sizeof(int) * cfg->blocks_count, use_heap); memset(postnum, -1, sizeof(int) * cfg->blocks_count); @@ -704,16 +697,14 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze for (k = 0; k < blocks[j].predecessors_count; k++) { int pred = cfg->predecessors[blocks[j].predecessor_offset + k]; - if (idom < 0) { - if (blocks[pred].idom >= 0) - idom = pred; - continue; - } - if (blocks[pred].idom >= 0) { - while (idom != pred) { - while (postnum[pred] < postnum[idom]) pred = blocks[pred].idom; - while (postnum[idom] < postnum[pred]) idom = blocks[idom].idom; + if (idom < 0) { + idom = pred; + } else { + while (idom != pred) { + while (postnum[pred] < postnum[idom]) pred = blocks[pred].idom; + while (postnum[idom] < postnum[pred]) idom = blocks[idom].idom; + } } } } @@ -777,19 +768,6 @@ static bool dominates(zend_basic_block *blocks, int a, int b) /* {{{ */ } /* }}} */ -typedef struct { - int id; - int level; -} block_info; -static int compare_block_level(const block_info *a, const block_info *b) { - return b->level - a->level; -} -static void swap_blocks(block_info *a, block_info *b) { - block_info tmp = *a; - *a = *b; - *b = tmp; -} - ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { int i, j, k, n; @@ -798,17 +776,22 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c int *entry_times, *exit_times; zend_worklist work; int flag = ZEND_FUNC_NO_LOOPS; - block_info *sorted_blocks; + int *sorted_blocks; ALLOCA_FLAG(list_use_heap) ALLOCA_FLAG(tree_use_heap) - ALLOCA_FLAG(sorted_blocks_use_heap) + + if (cfg->blocks_count == 1) { + cfg->flags |= flag; + return; + } ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap); /* We don't materialize the DJ spanning tree explicitly, as we are only interested in ancestor * queries. These are implemented by checking entry/exit times of the DFS search. */ - entry_times = do_alloca(2 * sizeof(int) * cfg->blocks_count, tree_use_heap); + entry_times = do_alloca(3 * sizeof(int) * cfg->blocks_count, tree_use_heap); exit_times = entry_times + cfg->blocks_count; + sorted_blocks = exit_times + cfg->blocks_count; memset(entry_times, -1, 2 * sizeof(int) * cfg->blocks_count); zend_worklist_push(&work, 0); @@ -838,27 +821,35 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c zend_worklist_pop(&work); } - /* Sort blocks by decreasing level, which is the order in which we want to process them */ - sorted_blocks = do_alloca(sizeof(block_info) * cfg->blocks_count, sorted_blocks_use_heap); - for (i = 0; i < cfg->blocks_count; i++) { - sorted_blocks[i].id = i; - sorted_blocks[i].level = blocks[i].level; + /* Sort blocks by level, which is the opposite order in which we want to process them */ + sorted_blocks[0] = 0; + j = 0; + n = 1; + while (j != n) { + i = j; + j = n; + for (; i < j; i++) { + int child; + for (child = blocks[sorted_blocks[i]].children; child >= 0; child = blocks[child].next_child) { + sorted_blocks[n++] = child; + } + } } - zend_sort(sorted_blocks, cfg->blocks_count, sizeof(block_info), - (compare_func_t) compare_block_level, (swap_func_t) swap_blocks); - /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ - Graphs". */ + /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs". */ + while (n > 0) { + i = sorted_blocks[--n]; - for (n = 0; n < cfg->blocks_count; n++) { - i = sorted_blocks[n].id; + if (blocks[i].predecessors_count < 2) { + /* loop header has at least two input edges */ + continue; + } - zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count)); for (j = 0; j < blocks[i].predecessors_count; j++) { int pred = cfg->predecessors[blocks[i].predecessor_offset + j]; /* A join edge is one for which the predecessor does not - immediately dominate the successor. */ + immediately dominate the successor. */ if (blocks[i].idom == pred) { continue; } @@ -868,6 +859,9 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c if (dominates(blocks, i, pred)) { blocks[i].flags |= ZEND_BB_LOOP_HEADER; flag &= ~ZEND_FUNC_NO_LOOPS; + if (!zend_worklist_len(&work)) { + zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count)); + } zend_worklist_push(&work, pred); } else { /* Otherwise it's a cross-join edge. See if it's a branch @@ -897,7 +891,6 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c } } - free_alloca(sorted_blocks, sorted_blocks_use_heap); free_alloca(entry_times, tree_use_heap); ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap); diff --git a/Zend/Optimizer/zend_cfg.h b/Zend/Optimizer/zend_cfg.h index 152502978dad4..93d455060686e 100644 --- a/Zend/Optimizer/zend_cfg.h +++ b/Zend/Optimizer/zend_cfg.h @@ -62,7 +62,6 @@ typedef struct _zend_basic_block { |JMP |ADR| | |OP1| - | |JMPZ | |ADR| |OP2|FOL| |JMPNZ | |ADR| |OP2|FOL| -|JMPZNZ | |ADR|ADR|OP2|EXT| |JMPZ_EX | |ADR| |OP2|FOL| |JMPNZ_EX | |ADR| |OP2|FOL| |JMP_SET | |ADR| |OP2|FOL| diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index f9be48ffda658..7e9988fb31bdd 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -75,8 +75,8 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa || (t3 & (MAY_BE_DOUBLE|MAY_BE_STRING))) { tmp |= MAY_BE_ARRAY_OF_DOUBLE; } - if ((t1 & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_STRING|MAY_BE_DOUBLE))) - && (t2 & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_STRING|MAY_BE_DOUBLE)))) { + if ((t1 & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_DOUBLE)) + && (t2 & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_DOUBLE))) { if ((t3 & MAY_BE_ANY) != MAY_BE_DOUBLE) { tmp |= MAY_BE_ARRAY_OF_LONG; } diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 80b01a6db26ac..b9c65fc8959dd 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2258,6 +2258,25 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in return zend_convert_type(script, prop_info->type, pce); } +static bool result_may_be_separated(zend_ssa *ssa, zend_ssa_op *ssa_op) +{ + int tmp_var = ssa_op->result_def; + + if (ssa->vars[tmp_var].use_chain >= 0 + && !ssa->vars[tmp_var].phi_use_chain) { + zend_ssa_op *use_op = &ssa->ops[ssa->vars[tmp_var].use_chain]; + + /* TODO: analize instructions between ssa_op and use_op */ + if (use_op == ssa_op + 1) { + if ((use_op->op1_use == tmp_var && use_op->op1_use_chain < 0) + || (use_op->op2_use == tmp_var && use_op->op2_use_chain < 0)) { + return 0; + } + } + } + return 1; +} + static zend_always_inline zend_result _zend_update_type_info( const zend_op_array *op_array, zend_ssa *ssa, @@ -2665,13 +2684,17 @@ static zend_always_inline zend_result _zend_update_type_info( case ZEND_ASSIGN_DIM: if (opline->op1_type == IS_CV) { tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO(), opline->op2_type); + tmp |= ssa->var_info[ssa_op->op1_def].type & (MAY_BE_ARRAY_PACKED|MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH); UPDATE_SSA_TYPE(tmp, ssa_op->op1_def); COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def); } if (ssa_op->result_def >= 0) { tmp = 0; if (t1 & MAY_BE_STRING) { - tmp |= MAY_BE_STRING; + tmp |= MAY_BE_STRING | MAY_BE_NULL; + } + if (t1 & MAY_BE_OBJECT) { + tmp |= (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF); } if (t1 & (MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL|MAY_BE_UNDEF)) { tmp |= (OP1_DATA_INFO() & (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF)); @@ -2684,9 +2707,6 @@ static zend_always_inline zend_result _zend_update_type_info( tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING; } } - if (t1 & MAY_BE_OBJECT) { - tmp |= MAY_BE_REF; - } tmp |= MAY_BE_RC1 | MAY_BE_RCN; UPDATE_SSA_TYPE(tmp, ssa_op->result_def); } @@ -2796,6 +2816,20 @@ static zend_always_inline zend_result _zend_update_type_info( tmp &= ~MAY_BE_REF; tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_RC1|MAY_BE_RCN; } + if ((tmp & (MAY_BE_RC1|MAY_BE_RCN)) == MAY_BE_RCN) { + /* refcount may be indirectly decremented. Make an exception if the result is used in the next instruction */ + if (!ssa_opcodes) { + if (ssa->vars[ssa_op->result_def].use_chain < 0 + || opline + 1 != op_array->opcodes + ssa->vars[ssa_op->result_def].use_chain) { + tmp |= MAY_BE_RC1; + } + } else { + if (ssa->vars[ssa_op->result_def].use_chain < 0 + || opline + 1 != ssa_opcodes[ssa->vars[ssa_op->result_def].use_chain]) { + tmp |= MAY_BE_RC1; + } + } + } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); COPY_SSA_OBJ_TYPE(ssa_op->op2_use, ssa_op->result_def); } @@ -3366,11 +3400,11 @@ static zend_always_inline zend_result _zend_update_type_info( if (prop_info) { /* FETCH_OBJ_R/IS for plain property increments reference counter, so it can't be 1 */ - if (ce && !ce->create_object) { + if (ce && !ce->create_object && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } else { - if (ce && !ce->create_object && !ce->__get) { + if (ce && !ce->create_object && !ce->__get && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } @@ -3396,7 +3430,9 @@ static zend_always_inline zend_result _zend_update_type_info( if (opline->result_type == IS_VAR) { tmp |= MAY_BE_REF | MAY_BE_INDIRECT; } else { - tmp &= ~MAY_BE_RC1; + if (!result_may_be_separated(ssa, ssa_op)) { + tmp &= ~MAY_BE_RC1; + } if (opline->opcode == ZEND_FETCH_STATIC_PROP_IS) { tmp |= MAY_BE_UNDEF; } @@ -3630,6 +3666,17 @@ static zend_class_entry *join_class_entries( return ce1; } +static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { + if (ce1 == ce2) { + return 1; + } + if (!(ce1->ce_flags & ZEND_ACC_LINKED)) { + /* This case could be generalized, similarly to unlinked_instanceof */ + return 0; + } + return instanceof_function(ce1, ce2); +} + static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_bitset worklist, zend_long optimization_level) { zend_basic_block *blocks = ssa->cfg.blocks; @@ -3661,7 +3708,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend if (!ce) { ce = constraint->ce; is_instanceof = 1; - } else if (is_instanceof && instanceof_function(constraint->ce, ce)) { + } else if (is_instanceof && safe_instanceof(constraint->ce, ce)) { ce = constraint->ce; } else { /* Ignore the constraint (either ce instanceof constraint->ce or @@ -4590,7 +4637,6 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_BOOL: diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index f8aee5148cbeb..e7d429ddeff47 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -30,6 +30,7 @@ #include "zend_call_graph.h" #include "zend_inference.h" #include "zend_dump.h" +#include "php.h" #ifndef ZEND_OPTIMIZER_MAX_REGISTERED_PASSES # define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES 32 @@ -121,6 +122,81 @@ zend_result zend_optimizer_eval_strlen(zval *result, zval *op1) /* {{{ */ } /* }}} */ +zend_result zend_optimizer_eval_special_func_call( + zval *result, zend_string *name, zend_string *arg) { + if (zend_string_equals_literal(name, "function_exists") || + zend_string_equals_literal(name, "is_callable")) { + zend_string *lc_name = zend_string_tolower(arg); + zend_internal_function *func = zend_hash_find_ptr(EG(function_table), lc_name); + zend_string_release_ex(lc_name, 0); + + if (func && func->type == ZEND_INTERNAL_FUNCTION + && func->module->type == MODULE_PERSISTENT +#ifdef ZEND_WIN32 + && func->module->handle == NULL +#endif + ) { + ZVAL_TRUE(result); + return SUCCESS; + } + return FAILURE; + } + if (zend_string_equals_literal(name, "extension_loaded")) { + zend_string *lc_name = zend_string_tolower(arg); + zend_module_entry *m = zend_hash_find_ptr(&module_registry, lc_name); + zend_string_release_ex(lc_name, 0); + + if (!m) { + if (PG(enable_dl)) { + return FAILURE; + } + ZVAL_FALSE(result); + return SUCCESS; + } + + if (m->type == MODULE_PERSISTENT +#ifdef ZEND_WIN32 + && m->handle == NULL +#endif + ) { + ZVAL_TRUE(result); + return SUCCESS; + } + return FAILURE; + } + if (zend_string_equals_literal(name, "constant")) { + return zend_optimizer_get_persistent_constant(arg, result, 1) ? SUCCESS : FAILURE; + } + if (zend_string_equals_literal(name, "dirname")) { + if (!IS_ABSOLUTE_PATH(ZSTR_VAL(arg), ZSTR_LEN(arg))) { + return FAILURE; + } + + zend_string *dirname = zend_string_init(ZSTR_VAL(arg), ZSTR_LEN(arg), 0); + ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); + if (IS_ABSOLUTE_PATH(ZSTR_VAL(dirname), ZSTR_LEN(dirname))) { + ZVAL_STR(result, dirname); + return SUCCESS; + } + zend_string_release_ex(dirname, 0); + return FAILURE; + } + if (zend_string_equals_literal(name, "ini_get")) { + zend_ini_entry *ini_entry = zend_hash_find_ptr(EG(ini_directives), arg); + if (!ini_entry) { + ZVAL_FALSE(result); + } else if (ini_entry->modifiable != ZEND_INI_SYSTEM) { + return FAILURE; + } else if (ini_entry->value) { + ZVAL_STR_COPY(result, ini_entry->value); + } else { + ZVAL_EMPTY_STRING(result); + } + return SUCCESS; + } + return FAILURE; +} + bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) { zval *val; @@ -132,6 +208,25 @@ bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zva return 0; } +void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline) +{ + if (opline->op1_type == IS_CV) { + opline->opcode = ZEND_CHECK_VAR; + SET_UNUSED(opline->op2); + SET_UNUSED(opline->result); + opline->extended_value = 0; + } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + opline->opcode = ZEND_FREE; + SET_UNUSED(opline->op2); + SET_UNUSED(opline->result); + opline->extended_value = 0; + } else { + ZEND_ASSERT(opline->op1_type == IS_CONST); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } +} + int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv) { int i = op_array->last_literal; @@ -609,9 +704,6 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z case ZEND_FAST_CALL: ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op1, ZEND_OP1_JMP_ADDR(opline)); break; - case ZEND_JMPZNZ: - new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -655,9 +747,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_ case ZEND_FAST_CALL: ZEND_SET_OP_JMP_ADDR(opline, opline->op1, ZEND_OP1_JMP_ADDR(opline) - shiftlist[ZEND_OP1_JMP_ADDR(opline) - op_array->opcodes]); break; - case ZEND_JMPZNZ: - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1044,9 +1133,6 @@ static void zend_redo_pass_two(zend_op_array *op_array) case ZEND_FAST_CALL: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.jmp_addr - old_opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1167,9 +1253,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) case ZEND_FAST_CALL: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.jmp_addr - old_opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1339,6 +1422,7 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (op_array->scope == ce && op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_foreach_op_array_helper(op_array, func, context); } diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index 0116e1506000d..9e295bad73dcb 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -76,6 +76,7 @@ static inline bool zend_optimizer_is_loop_var_free(const zend_op *opline) { || (opline->opcode == ZEND_FREE && opline->extended_value == ZEND_FREE_SWITCH); } +void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline); int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv); bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy); void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value); @@ -84,6 +85,8 @@ zend_result zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval zend_result zend_optimizer_eval_unary_op(zval *result, zend_uchar opcode, zval *op1); zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1); zend_result zend_optimizer_eval_strlen(zval *result, zval *op1); +zend_result zend_optimizer_eval_special_func_call( + zval *result, zend_string *name, zend_string *arg); bool zend_optimizer_update_op1_const(zend_op_array *op_array, zend_op *opline, zval *val); diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 98f60468a0e69..11f25b6825fee 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -257,7 +257,6 @@ static void place_essa_pis( */ switch (opline->opcode) { case ZEND_JMPZ: - case ZEND_JMPZNZ: bf = blocks[j].successors[0]; bt = blocks[j].successors[1]; break; @@ -1209,6 +1208,46 @@ void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var) /* {{{ */ } /* }}} */ +void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var) /* {{{ */ +{ + if (ssa->vars[var].use_chain == op) { + ssa->vars[var].use_chain = new_op; + return; + } else { + int use = ssa->vars[var].use_chain; + + while (use >= 0) { + if (ssa->ops[use].result_use == var) { + if (ssa->ops[use].res_use_chain == op) { + ssa->ops[use].res_use_chain = new_op; + return; + } else { + use = ssa->ops[use].res_use_chain; + } + } else if (ssa->ops[use].op1_use == var) { + if (ssa->ops[use].op1_use_chain == op) { + ssa->ops[use].op1_use_chain = new_op; + return; + } else { + use = ssa->ops[use].op1_use_chain; + } + } else if (ssa->ops[use].op2_use == var) { + if (ssa->ops[use].op2_use_chain == op) { + ssa->ops[use].op2_use_chain = new_op; + return; + } else { + use = ssa->ops[use].op2_use_chain; + } + } else { + break; + } + } + } + /* something wrong */ + ZEND_UNREACHABLE(); +} +/* }}} */ + void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) /* {{{ */ { if (ssa_op->result_use >= 0) { diff --git a/Zend/Optimizer/zend_ssa.h b/Zend/Optimizer/zend_ssa.h index 93fa6e673f2e8..9fde352c79cc1 100644 --- a/Zend/Optimizer/zend_ssa.h +++ b/Zend/Optimizer/zend_ssa.h @@ -149,6 +149,7 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa); ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *opline, uint32_t k, uint32_t build_flags, int ssa_vars_count, zend_ssa_op *ssa_ops, int *var); void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var); +void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var); void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to); void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op); diff --git a/Zend/README.md b/Zend/README.md index cf1f15463d2f9..26f3613c34bb3 100644 --- a/Zend/README.md +++ b/Zend/README.md @@ -119,21 +119,21 @@ ZEND_VM_HELPER_EX(, , , ) } ``` -Executor's code is generated by PHP script zend_vm_gen.php it uses +The executors code is generated by the PHP script `zend_vm_gen.php`. It uses `zend_vm_def.h` and `zend_vm_execute.skl` as input and produces `zend_vm_opcodes.h` and `zend_vm_execute.h`. The first file is a list of opcode definitions. It is included from `zend_compile.h`. The second one is an executor code itself. It is included from `zend_execute.c`. -`zend_vm_gen.php` can produce different kind of executors. You can select -different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO`. You -can disable opcode specialization using `--without-specializer`. You can include -or exclude old executor together with specialized one using -`--without-old-executor`. At last you can debug executor using original -`zend_vm_def.h` or generated file `zend_vm_execute.h`. Debugging with original -file requires `--with-lines` option. By default ZE2 uses the following command -to generate executor: +`zend_vm_gen.php` can produce different kind of executors. You can select a +different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO|HYBRID`. +You can disable opcode specialization using `--without-specializer`. +At last you can debug the executor using the original `zend_vm_def.h` or the +generated `zend_vm_execute.h` file. Debugging with the original file requires +the `--with-lines` option. By default, Zend Engine uses the following +command to generate the executor: ```bash -php zend_vm_gen.php --with-vm-kind=CALL +# Default VM kind is HYBRID +php zend_vm_gen.php --with-vm-kind=HYBRID ``` diff --git a/Zend/asm/jump_riscv64_sysv_elf_gas.S b/Zend/asm/jump_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5417e5d5e3498 --- /dev/null +++ b/Zend/asm/jump_riscv64_sysv_elf_gas.S @@ -0,0 +1,150 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "jump_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack for GP + FPU + addi sp, sp, -0xd0 + + # save fs0 - fs11 + fsd fs0, 0x00(sp) + fsd fs1, 0x08(sp) + fsd fs2, 0x10(sp) + fsd fs3, 0x18(sp) + fsd fs4, 0x20(sp) + fsd fs5, 0x28(sp) + fsd fs6, 0x30(sp) + fsd fs7, 0x38(sp) + fsd fs8, 0x40(sp) + fsd fs9, 0x48(sp) + fsd fs10, 0x50(sp) + fsd fs11, 0x58(sp) + + # save s0-s11, ra + sd s0, 0x60(sp) + sd s1, 0x68(sp) + sd s2, 0x70(sp) + sd s3, 0x78(sp) + sd s4, 0x80(sp) + sd s5, 0x88(sp) + sd s6, 0x90(sp) + sd s7, 0x98(sp) + sd s8, 0xa0(sp) + sd s9, 0xa8(sp) + sd s10, 0xb0(sp) + sd s11, 0xb8(sp) + sd ra, 0xc0(sp) + + # save RA as PC + sd ra, 0xc8(sp) + + # store SP (pointing to context-data) in A2 + mv a2, sp + + # restore SP (pointing to context-data) from A0 + mv sp, a0 + + # load fs0 - fs11 + fld fs0, 0x00(sp) + fld fs1, 0x08(sp) + fld fs2, 0x10(sp) + fld fs3, 0x18(sp) + fld fs4, 0x20(sp) + fld fs5, 0x28(sp) + fld fs6, 0x30(sp) + fld fs7, 0x38(sp) + fld fs8, 0x40(sp) + fld fs9, 0x48(sp) + fld fs10, 0x50(sp) + fld fs11, 0x58(sp) + + # load s0-s11,ra + ld s0, 0x60(sp) + ld s1, 0x68(sp) + ld s2, 0x70(sp) + ld s3, 0x78(sp) + ld s4, 0x80(sp) + ld s5, 0x88(sp) + ld s6, 0x90(sp) + ld s7, 0x98(sp) + ld s8, 0xa0(sp) + ld s9, 0xa8(sp) + ld s10, 0xb0(sp) + ld s11, 0xb8(sp) + ld ra, 0xc0(sp) + + # return transfer_t from jump + # pass transfer_t as first arg in context function + # a0 == FCTX, a1 == DATA + mv a0, a2 + + # load pc + ld a2, 0xc8(sp) + + # restore stack from GP + FPU + addi sp, sp, 0xd0 + + jr a2 +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/Zend/asm/make_riscv64_sysv_elf_gas.S b/Zend/asm/make_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5322e0fdbdec7 --- /dev/null +++ b/Zend/asm/make_riscv64_sysv_elf_gas.S @@ -0,0 +1,91 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "make_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + # shift address in a0 (allocated stack) to lower 16 byte boundary + andi a0, a0, ~0xF + + # reserve space for context-data on context-stack + addi a0, a0, -0xd0 + + # third arg of make_fcontext() == address of context-function + # store address as a PC to jump in + sd a2, 0xc8(a0) + + # save address of finish as return-address for context-function + # will be entered after context-function returns (RA register) + lla a4, finish + sd a4, 0xc0(a0) + + ret // return pointer to context-data (a0) + +finish: + # exit code is zero + li a0, 0 + # exit application + tail _exit@plt + +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/Zend/tests/array_offset_002.phpt b/Zend/tests/array_offset_002.phpt new file mode 100644 index 0000000000000..ad684c3b6e486 --- /dev/null +++ b/Zend/tests/array_offset_002.phpt @@ -0,0 +1,18 @@ +--TEST-- +Capturing array in user error handler during index conversion +--FILE-- + +--EXPECT-- +Err: Implicit conversion from float 1.0E+20 to int loses precision +array(0) { +} diff --git a/Zend/tests/bug41633_2.phpt b/Zend/tests/bug41633_2.phpt index 975d2218b55e3..bb768c0e11743 100644 --- a/Zend/tests/bug41633_2.phpt +++ b/Zend/tests/bug41633_2.phpt @@ -11,4 +11,4 @@ echo Foo::A."\n"; Fatal error: Uncaught Error: Undefined constant self::B in %s:%d Stack trace: #0 {main} - thrown in %sbug41633_2.php on line 5 + thrown in %sbug41633_2.php on line 3 diff --git a/Zend/tests/class_alias_009.phpt b/Zend/tests/class_alias_009.phpt index f17769e1f4213..bb72312577aff 100644 --- a/Zend/tests/class_alias_009.phpt +++ b/Zend/tests/class_alias_009.phpt @@ -11,4 +11,4 @@ interface c extends a, b { } ?> --EXPECTF-- -Fatal error: Class c cannot implement previously implemented interface a in %s on line %d +Fatal error: Interface c cannot implement previously implemented interface a in %s on line %d diff --git a/Zend/tests/closure_063.phpt b/Zend/tests/closure_063.phpt new file mode 100644 index 0000000000000..b53f370eb4bfc --- /dev/null +++ b/Zend/tests/closure_063.phpt @@ -0,0 +1,12 @@ +--TEST-- +Closure::bindTo leaks with "fake" closure +--FILE-- +bindTo(new stdClass); +?> +DONE +--EXPECT-- +DONE \ No newline at end of file diff --git a/Zend/tests/constants/final_constants/final_const12.phpt b/Zend/tests/constants/final_constants/final_const12.phpt index 300239f6a630e..3130af11da8bd 100644 --- a/Zend/tests/constants/final_constants/final_const12.phpt +++ b/Zend/tests/constants/final_constants/final_const12.phpt @@ -19,4 +19,4 @@ interface I3 extends I1, I2 ?> --EXPECTF-- -Fatal error: Class I3 inherits both I1::C and I2::C, which is ambiguous in %s on line %d +Fatal error: Interface I3 inherits both I1::C and I2::C, which is ambiguous in %s on line %d diff --git a/Zend/tests/dynamic_prop_deprecation_002.phpt b/Zend/tests/dynamic_prop_deprecation_002.phpt new file mode 100644 index 0000000000000..bd0d3aa5a7df9 --- /dev/null +++ b/Zend/tests/dynamic_prop_deprecation_002.phpt @@ -0,0 +1,18 @@ +--TEST-- +Dynamic properties deprecation 002 (memory leak) +--FILE-- +y]; +} catch (Throwable $ex) { + echo "Exception: " .$ex->getMessage() . "\n"; +} +?> +--EXPECT-- +Err: Creation of dynamic property class@anonymous::$y is deprecated +Exception: Cannot create dynamic property class@anonymous::$y diff --git a/Zend/tests/enum/gh8176.phpt b/Zend/tests/enum/gh8176.phpt new file mode 100644 index 0000000000000..b3dac08d0c6ba --- /dev/null +++ b/Zend/tests/enum/gh8176.phpt @@ -0,0 +1,23 @@ +--TEST-- +Enum object in property initializer +--FILE-- + +--EXPECT-- +object(AClass)#2 (1) { + ["prop"]=> + enum(AnEnum::Value) +} diff --git a/Zend/tests/enum/no-enum-implements-backed-enum.phpt b/Zend/tests/enum/no-enum-implements-backed-enum.phpt index 69922c13a8f51..c93994ad8bf58 100644 --- a/Zend/tests/enum/no-enum-implements-backed-enum.phpt +++ b/Zend/tests/enum/no-enum-implements-backed-enum.phpt @@ -7,4 +7,4 @@ enum Foo: int implements BackedEnum {} ?> --EXPECTF-- -Fatal error: Class Foo cannot implement previously implemented interface BackedEnum in %s on line %d +Fatal error: Enum Foo cannot implement previously implemented interface BackedEnum in %s on line %d diff --git a/Zend/tests/enum/no-enum-implements-unit-enum.phpt b/Zend/tests/enum/no-enum-implements-unit-enum.phpt index 458efbb67cdfa..ae1890c430518 100644 --- a/Zend/tests/enum/no-enum-implements-unit-enum.phpt +++ b/Zend/tests/enum/no-enum-implements-unit-enum.phpt @@ -7,4 +7,4 @@ enum Foo implements UnitEnum {} ?> --EXPECTF-- -Fatal error: Class Foo cannot implement previously implemented interface UnitEnum in %s on line %d +Fatal error: Enum Foo cannot implement previously implemented interface UnitEnum in %s on line %d diff --git a/Zend/tests/generators/errors/resume_running_generator_error_002.phpt b/Zend/tests/generators/errors/resume_running_generator_error_002.phpt new file mode 100644 index 0000000000000..e71e32a886dcc --- /dev/null +++ b/Zend/tests/generators/errors/resume_running_generator_error_002.phpt @@ -0,0 +1,17 @@ +--TEST-- +Memory leak when resume an already running generator +--FILE-- +send($g); +} +$gen = gen(); +try { + $gen->send($gen); +} catch (Throwable $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Cannot resume an already running generator diff --git a/Zend/tests/generators/errors/resume_running_generator_error_003.phpt b/Zend/tests/generators/errors/resume_running_generator_error_003.phpt new file mode 100644 index 0000000000000..c72f9ba87258c --- /dev/null +++ b/Zend/tests/generators/errors/resume_running_generator_error_003.phpt @@ -0,0 +1,24 @@ +--TEST-- +Use-after-free when resume an already running generator +--FILE-- +send($y); +} +$gen=gen(); +try { + $gen->send($gen); +}catch(y) { +} +?> +--EXPECTF-- +Warning: Undefined variable $y in %sresume_running_generator_error_003.php on line 4 + +Fatal error: Uncaught Error: Cannot resume an already running generator in %sresume_running_generator_error_003.php:4 +Stack trace: +#0 %sresume_running_generator_error_003.php(4): Generator->send(NULL) +#1 [internal function]: gen() +#2 %sresume_running_generator_error_003.php(8): Generator->send(Object(Generator)) +#3 {main} + thrown in %sresume_running_generator_error_003.php on line 4 diff --git a/Zend/tests/gh7771_1.phpt b/Zend/tests/gh7771_1.phpt new file mode 100644 index 0000000000000..dc24b4041c716 --- /dev/null +++ b/Zend/tests/gh7771_1.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-7771 (Incorrect file/line for class constant expression exceptions) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_1_definition.inc:4 +Stack trace: +#0 {main} + thrown in %sgh7771_1_definition.inc on line 4 diff --git a/Zend/tests/gh7771_1_definition.inc b/Zend/tests/gh7771_1_definition.inc new file mode 100644 index 0000000000000..16e94f41a0fa4 --- /dev/null +++ b/Zend/tests/gh7771_1_definition.inc @@ -0,0 +1,5 @@ + +--EXPECTF-- +Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_2_definition.inc:6 +Stack trace: +#0 {main} + thrown in %sgh7771_2_definition.inc on line 6 diff --git a/Zend/tests/gh7771_2_definition.inc b/Zend/tests/gh7771_2_definition.inc new file mode 100644 index 0000000000000..0162a9c8bf1ed --- /dev/null +++ b/Zend/tests/gh7771_2_definition.inc @@ -0,0 +1,8 @@ + 'class y{const y="$y";}', + 'D' => 'class D{const HW=space1\C::y;}' +]; +spl_autoload_register(function($class) use ($classlist) { + eval($classlist[$class]); +}); +var_dump(D::HW); +?> +--EXPECTF-- +Fatal error: Constant expression contains invalid operations in %sgh7771_3.php(7) : eval()'d code(1) : eval()'d code on line 1 + diff --git a/Zend/tests/gh7792_1.phpt b/Zend/tests/gh7792_1.phpt new file mode 100644 index 0000000000000..a342f169d937c --- /dev/null +++ b/Zend/tests/gh7792_1.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum B must implement 1 abstract private method (A::a) in %s on line %d diff --git a/Zend/tests/gh7792_2.phpt b/Zend/tests/gh7792_2.phpt new file mode 100644 index 0000000000000..41f47a6e870ac --- /dev/null +++ b/Zend/tests/gh7792_2.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo cannot implement interface Throwable in %s on line %d diff --git a/Zend/tests/gh7792_3.phpt b/Zend/tests/gh7792_3.phpt new file mode 100644 index 0000000000000..67e2c1c99dda1 --- /dev/null +++ b/Zend/tests/gh7792_3.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo inherits both A::FOO and B::FOO, which is ambiguous in %s on line %d diff --git a/Zend/tests/gh7792_4.phpt b/Zend/tests/gh7792_4.phpt new file mode 100644 index 0000000000000..0d09835d7ee3a --- /dev/null +++ b/Zend/tests/gh7792_4.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo cannot implement previously implemented interface A in %s on line %d diff --git a/Zend/tests/gh7792_5.phpt b/Zend/tests/gh7792_5.phpt new file mode 100644 index 0000000000000..824ed9ed1810d --- /dev/null +++ b/Zend/tests/gh7792_5.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECT-- +Fatal error: Enum Foo must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown on line 0 diff --git a/Zend/tests/gh7958.phpt b/Zend/tests/gh7958.phpt new file mode 100644 index 0000000000000..d9f3b8940a4a4 --- /dev/null +++ b/Zend/tests/gh7958.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-7958 (Nested CallbackFilterIterator is leaking memory) +--FILE-- +iterator = new ArrayIterator($data); + echo '-- c ' . spl_object_id($this) . "\n"; + } + + public function __destruct() + { + echo '-- d ' . spl_object_id($this) . "\n"; + } + + public function filter() + { + $this->iterator = new \CallbackFilterIterator($this->iterator, fn() => true); + $this->iterator->rewind(); + } +} + +$action = new Action(['a', 'b']); +$action->filter(); +$action->filter(); +print_r(iterator_to_array($action->iterator)); +$action = null; +gc_collect_cycles(); +echo "==DONE==\n"; +?> +--EXPECT-- +-- c 1 +Array +( + [0] => a + [1] => b +) +-- d 1 +==DONE== diff --git a/Zend/tests/gh8083.phpt b/Zend/tests/gh8083.phpt new file mode 100644 index 0000000000000..a98de47cbf375 --- /dev/null +++ b/Zend/tests/gh8083.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-8083 (var_dump() on closure with static variable segfaults) +--FILE-- + +--EXPECT-- +object(Closure)#1 (1) { + ["static"]=> + array(1) { + ["i"]=> + NULL + } +} diff --git a/Zend/tests/memory_reset_peak_usage.phpt b/Zend/tests/memory_reset_peak_usage.phpt new file mode 100644 index 0000000000000..0599e7c313c41 --- /dev/null +++ b/Zend/tests/memory_reset_peak_usage.phpt @@ -0,0 +1,23 @@ +--TEST-- +void memory_reset_peak_usage(); +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- + $m0); +unset($array0, $array1); +memory_reset_peak_usage(); +var_dump(memory_get_peak_usage() < $m1); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/nullsafe_operator/040.phpt b/Zend/tests/nullsafe_operator/040.phpt new file mode 100644 index 0000000000000..1bfdaf753df85 --- /dev/null +++ b/Zend/tests/nullsafe_operator/040.phpt @@ -0,0 +1,19 @@ +--TEST-- +Memory leak in JMP_NULL +--FILE-- +null); +} + +$foo2 = &returns_ref2(); +$foo2 = 'foo'; +var_dump($foo); +?> +--EXPECT-- +string(3) "foo" diff --git a/Zend/tests/objects_014.phpt b/Zend/tests/objects_014.phpt index 138fd4f294660..858de748b8e2e 100644 --- a/Zend/tests/objects_014.phpt +++ b/Zend/tests/objects_014.phpt @@ -12,4 +12,4 @@ interface bar extends foo, foo { echo "Done\n"; ?> --EXPECTF-- -Fatal error: Class bar cannot implement previously implemented interface foo in %s on line %d +Fatal error: Interface bar cannot implement previously implemented interface foo in %s on line %d diff --git a/Zend/tests/record_errors_001.phpt b/Zend/tests/record_errors_001.phpt new file mode 100644 index 0000000000000..dd3c0ba487ea0 --- /dev/null +++ b/Zend/tests/record_errors_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +Error recording in error handler +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Error: Return type of DateTime@anonymous::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice diff --git a/Zend/zend.c b/Zend/zend.c index c37cd9ed97453..ca56e74615c8a 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -665,6 +665,22 @@ static void function_copy_ctor(zval *zv) /* {{{ */ } func->common.arg_info = new_arg_info + 1; } + if (old_func->common.attributes) { + zend_attribute *old_attr; + + func->common.attributes = NULL; + + ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) { + uint32_t i; + zend_attribute *attr; + + attr = zend_add_attribute(&func->common.attributes, old_attr->name, old_attr->argc, old_attr->flags, old_attr->offset, old_attr->lineno); + + for (i = 0 ; i < old_attr->argc; i++) { + ZVAL_DUP(&attr->args[i].value, &old_attr->args[i].value); + } + } ZEND_HASH_FOREACH_END(); + } } /* }}} */ @@ -1232,8 +1248,6 @@ ZEND_API void zend_deactivate(void) /* {{{ */ /* we're no longer executing anything */ EG(current_execute_data) = NULL; - zend_observer_deactivate(); - zend_try { shutdown_scanner(); } zend_end_try(); @@ -1312,6 +1326,10 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zend_stack loop_var_stack; zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; + bool orig_record_errors; + uint32_t orig_num_errors; + zend_error_info **orig_errors; + zend_result res; /* If we're executing a function during SCCP, count any warnings that may be emitted, * but don't perform any other error handling. */ @@ -1405,7 +1423,20 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( CG(in_compilation) = 0; } - if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) { + orig_record_errors = EG(record_errors); + orig_num_errors = EG(num_errors); + orig_errors = EG(errors); + EG(record_errors) = false; + EG(num_errors) = 0; + EG(errors) = NULL; + + res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params); + + EG(record_errors) = orig_record_errors; + EG(num_errors) = orig_num_errors; + EG(errors) = orig_errors; + + if (res == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_FALSE) { zend_error_cb(orig_type, error_filename, error_lineno, message); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3ef291c315596..6ce9f593e17dd 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4783,14 +4783,16 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved) /* {{{ */ } /* }}} */ -ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce) /* {{{ */ +ZEND_API ZEND_COLD const char *zend_get_object_type_case(const zend_class_entry *ce, bool upper_case) /* {{{ */ { - if(ce->ce_flags & ZEND_ACC_TRAIT) { - return "trait"; + if (ce->ce_flags & ZEND_ACC_TRAIT) { + return upper_case ? "Trait" : "trait"; } else if (ce->ce_flags & ZEND_ACC_INTERFACE) { - return "interface"; + return upper_case ? "Interface" : "interface"; + } else if (ce->ce_flags & ZEND_ACC_ENUM) { + return upper_case ? "Enum" : "enum"; } else { - return "class"; + return upper_case ? "Class" : "class"; } } /* }}} */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ecb6e8296befb..705fe25e7665a 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -721,7 +721,17 @@ static zend_always_inline zend_result zend_forbid_dynamic_call(void) return SUCCESS; } -ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce); +ZEND_API ZEND_COLD const char *zend_get_object_type_case(const zend_class_entry *ce, bool upper_case); + +static zend_always_inline const char *zend_get_object_type(const zend_class_entry *ce) +{ + return zend_get_object_type_case(ce, false); +} + +static zend_always_inline const char *zend_get_object_type_uc(const zend_class_entry *ce) +{ + return zend_get_object_type_case(ce, true); +} ZEND_API bool zend_is_iterable(zval *iterable); diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index ace032e5e72d5..e2d06c1762dd9 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -196,7 +196,7 @@ typedef struct _zend_mm_free_slot zend_mm_free_slot; typedef struct _zend_mm_chunk zend_mm_chunk; typedef struct _zend_mm_huge_list zend_mm_huge_list; -int zend_mm_use_huge_pages = 0; +static bool zend_mm_use_huge_pages = false; /* * Memory is retrieved from OS by chunks of fixed size 2MB. @@ -425,12 +425,14 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) int flags = MAP_PRIVATE | MAP_ANON; #if defined(MAP_EXCL) flags |= MAP_FIXED | MAP_EXCL; +#elif defined(MAP_TRYFIXED) + flags |= MAP_TRYFIXED; #endif /* MAP_FIXED leads to discarding of the old mapping, so it can't be used. */ void *ptr = mmap(addr, size, PROT_READ | PROT_WRITE, flags /*| MAP_POPULATE | MAP_HUGETLB*/, ZEND_MM_FD, 0); if (ptr == MAP_FAILED) { -#if ZEND_MM_ERROR && !defined(MAP_EXCL) +#if ZEND_MM_ERROR && !defined(MAP_EXCL) && !defined(MAP_TRYFIXED) fprintf(stderr, "\nmmap() failed: [%d] %s\n", errno, strerror(errno)); #endif return NULL; @@ -1910,7 +1912,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) int page_num; zend_mm_page_info info; uint32_t i, free_counter; - int has_free_pages; + bool has_free_pages; size_t collected = 0; #if ZEND_MM_CUSTOM @@ -1920,7 +1922,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) #endif for (i = 0; i < ZEND_MM_BINS; i++) { - has_free_pages = 0; + has_free_pages = false; p = heap->free_slot[i]; while (p != NULL) { chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(p, ZEND_MM_CHUNK_SIZE); @@ -1939,7 +1941,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) ZEND_ASSERT(ZEND_MM_SRUN_BIN_NUM(info) == i); free_counter = ZEND_MM_SRUN_FREE_COUNTER(info) + 1; if (free_counter == bin_elements[i]) { - has_free_pages = 1; + has_free_pages = true; } chunk->map[page_num] = ZEND_MM_SRUN_EX(i, free_counter); p = p->next_free_slot; @@ -2023,7 +2025,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, uint32_t i, uint32_t j, zend_leak_info *leak) { - int empty = 1; + bool empty = true; zend_long count = 0; int bin_num = ZEND_MM_SRUN_BIN_NUM(p->map[i]); zend_mm_debug_info *dbg = (zend_mm_debug_info*)((char*)p + ZEND_MM_PAGE_SIZE * i + bin_data_size[bin_num] * (j + 1) - ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))); @@ -2036,7 +2038,7 @@ static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, uint32_t i, uint32_t dbg->filename = NULL; dbg->lineno = 0; } else { - empty = 0; + empty = false; } } j++; @@ -2669,7 +2671,20 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_API zend_result zend_set_memory_limit(size_t memory_limit) { #if ZEND_MM_LIMIT - if (UNEXPECTED(memory_limit < AG(mm_heap)->real_size)) { + zend_mm_heap *heap = AG(mm_heap); + + if (UNEXPECTED(memory_limit < heap->real_size)) { + if (memory_limit >= heap->real_size - heap->cached_chunks_count * ZEND_MM_CHUNK_SIZE) { + /* free some cached chunks to fit into new memory limit */ + do { + zend_mm_chunk *p = heap->cached_chunks; + heap->cached_chunks = p->next; + zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); + heap->cached_chunks_count--; + heap->real_size -= ZEND_MM_CHUNK_SIZE; + } while (memory_limit < heap->real_size); + return SUCCESS; + } return FAILURE; } AG(mm_heap)->limit = memory_limit; @@ -2711,6 +2726,14 @@ ZEND_API size_t zend_memory_peak_usage(bool real_usage) return 0; } +ZEND_API void zend_memory_reset_peak_usage(void) +{ +#if ZEND_MM_STAT + AG(mm_heap)->real_peak = AG(mm_heap)->real_size; + AG(mm_heap)->peak = AG(mm_heap)->size; +#endif +} + ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown) { zend_mm_shutdown(AG(mm_heap), full_shutdown, silent); @@ -2803,7 +2826,7 @@ static void *tracked_realloc(void *ptr, size_t new_size) { return ptr; } -static void tracked_free_all() { +static void tracked_free_all(void) { HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs; zend_ulong h; ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) { @@ -2846,7 +2869,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES"); if (tmp && ZEND_ATOL(tmp)) { - zend_mm_use_huge_pages = 1; + zend_mm_use_huge_pages = true; } alloc_globals->mm_heap = zend_mm_init(); } diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 9603af8a27d3f..f517b1231d1d2 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -229,6 +229,7 @@ ZEND_API bool is_zend_ptr(const void *ptr); ZEND_API size_t zend_memory_usage(bool real_usage); ZEND_API size_t zend_memory_peak_usage(bool real_usage); +ZEND_API void zend_memory_reset_peak_usage(void); /* fast cache for HashTables */ #define ALLOC_HASHTABLE(ht) \ diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 0d69bfbaca369..f1ea28112bdde 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -420,6 +420,19 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki } #endif +zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1) { + if (op0->kind == ZEND_AST_ZVAL && op1->kind == ZEND_AST_ZVAL) { + zval *zv0 = zend_ast_get_zval(op0); + zval *zv1 = zend_ast_get_zval(op1); + if (!zend_binary_op_produces_error(ZEND_CONCAT, zv0, zv1) && + concat_function(zv0, zv0, zv1) == SUCCESS) { + zval_ptr_dtor_nogc(zv1); + return zend_ast_create_zval(zv0); + } + } + return zend_ast_create_binary_op(ZEND_CONCAT, op0, op1); +} + static inline bool is_power_of_two(uint32_t n) { return ((n != 0) && (n == (n & (~n + 1)))); } @@ -776,7 +789,29 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast { zend_string *class_name = zend_ast_get_str(ast->child[0]); zend_string *const_name = zend_ast_get_str(ast->child[1]); - zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr); + zval *zv; + bool bailout = 0; + + zend_string *previous_filename; + zend_long previous_lineno; + if (scope) { + previous_filename = EG(filename_override); + previous_lineno = EG(lineno_override); + EG(filename_override) = scope->info.user.filename; + EG(lineno_override) = zend_ast_get_lineno(ast); + } + zend_try { + zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr); + } zend_catch { + bailout = 1; + } zend_end_try(); + if (scope) { + EG(filename_override) = previous_filename; + EG(lineno_override) = previous_lineno; + } + if (bailout) { + zend_bailout(); + } if (UNEXPECTED(zv == NULL)) { ZVAL_UNDEF(result); @@ -938,6 +973,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) zend_ast *new = (zend_ast*)buf; new->kind = ast->kind; new->attr = ast->attr; + new->lineno = ast->lineno; buf = (void*)((char*)buf + zend_ast_size(children)); for (i = 0; i < children; i++) { if (ast->child[i]) { diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 86f153580063c..d2940bbe633a8 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -355,6 +355,9 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1); } + +zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1); + static zend_always_inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1); } diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index 9ba27958d77c1..8a37375247269 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -205,6 +205,7 @@ ZEND_API bool zend_is_attribute_repeated(HashTable *attributes, zend_attribute * static void attr_free(zval *v) { zend_attribute *attr = Z_PTR_P(v); + bool persistent = attr->flags & ZEND_ATTRIBUTE_PERSISTENT; zend_string_release(attr->name); zend_string_release(attr->lcname); @@ -213,10 +214,14 @@ static void attr_free(zval *v) if (attr->args[i].name) { zend_string_release(attr->args[i].name); } - zval_ptr_dtor(&attr->args[i].value); + if (persistent) { + zval_internal_ptr_dtor(&attr->args[i].value); + } else { + zval_ptr_dtor(&attr->args[i].value); + } } - pefree(attr, attr->flags & ZEND_ATTRIBUTE_PERSISTENT); + pefree(attr, persistent); } ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_string *name, uint32_t argc, uint32_t flags, uint32_t offset, uint32_t lineno) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 122931ff7aebb..e141d0956dc95 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -775,7 +775,8 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) { - zend_create_closure_ex(res, func, scope, called_scope, this_ptr, /* is_fake */ false); + zend_create_closure_ex(res, func, scope, called_scope, this_ptr, + /* is_fake */ (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0); } ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */ diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index fcaf33d5e721c..ebfbab799795d 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -208,7 +208,7 @@ static inline int zend_cpu_supports_avx2(void) { /* __builtin_cpu_supports has pclmul from gcc9 */ #if PHP_HAVE_BUILTIN_CPU_SUPPORTS && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) ZEND_NO_SANITIZE_ADDRESS -static inline int zend_cpu_supports_pclmul() { +static inline int zend_cpu_supports_pclmul(void) { #if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); #endif diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 7138713510120..85e21c64a037b 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -67,8 +67,13 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr return SUCCESS; } + bool can_extend = (class_type->ce_flags & ZEND_ACC_ENUM) == 0; + zend_error_noreturn(E_ERROR, - "Class %s cannot implement interface %s, extend Exception or Error instead", + can_extend + ? "%s %s cannot implement interface %s, extend Exception or Error instead" + : "%s %s cannot implement interface %s", + zend_get_object_type_uc(class_type), ZSTR_VAL(class_type->name), ZSTR_VAL(interface->name)); return FAILURE; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5f7c8d10e59c1..5b2ce68ffb3b7 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2073,8 +2073,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht GC_ADDREF(ht); } zend_undefined_offset(lval); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } return NULL; } if (EG(exception)) { @@ -2095,8 +2097,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, /* Key may be released while throwing the undefined index warning. */ zend_string_addref(offset); zend_undefined_index(offset); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } retval = NULL; } else if (EG(exception)) { retval = NULL; @@ -2245,6 +2249,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval } } +static zend_never_inline zend_uchar slow_index_convert_w(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC) +{ + switch (Z_TYPE_P(dim)) { + case IS_UNDEF: { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + ZVAL_UNDEFINED_OP2(); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + ZEND_FALLTHROUGH; + } + case IS_NULL: + value->str = ZSTR_EMPTY_ALLOC(); + return IS_STRING; + case IS_DOUBLE: + value->lval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), value->lval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + } + return IS_LONG; + case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + value->lval = Z_RES_HANDLE_P(dim); + return IS_LONG; + case IS_FALSE: + value->lval = 0; + return IS_LONG; + case IS_TRUE: + value->lval = 1; + return IS_LONG; + default: + zend_illegal_offset(); + return IS_NULL; + } +} + static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type EXECUTE_DATA_DC) { zval *retval = NULL; @@ -2306,8 +2384,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht goto try_again; } else { zend_value val; - zend_uchar t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC); + zend_uchar t; + if (type != BP_VAR_W && type != BP_VAR_RW) { + t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC); + } else { + t = slow_index_convert_w(ht, dim, &val EXECUTE_DATA_CC); + } if (t == IS_STRING) { offset_key = val.str; goto str_index; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fed3ae1d29963..e791f986f8e74 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -192,6 +192,9 @@ void init_executor(void) /* {{{ */ EG(num_errors) = 0; EG(errors) = NULL; + EG(filename_override) = NULL; + EG(lineno_override) = -1; + zend_fiber_init(); zend_weakrefs_init(); @@ -329,6 +332,18 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) ZVAL_UNDEF(&c->value); } } ZEND_HASH_FOREACH_END(); + + /* properties may contain objects as well */ + if (ce->default_properties_table) { + zval *p = ce->default_properties_table; + zval *end = p + ce->default_properties_count; + + while (p != end) { + i_zval_ptr_dtor(p); + ZVAL_UNDEF(p); + p++; + } + } } if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { @@ -450,6 +465,8 @@ void shutdown_executor(void) /* {{{ */ if (EG(ht_iterators) != EG(ht_iterators_slots)) { efree(EG(ht_iterators)); } + + ZEND_ASSERT(EG(filename_override) == NULL); } #if ZEND_DEBUG @@ -579,21 +596,18 @@ ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t a ZEND_API const char *zend_get_executed_filename(void) /* {{{ */ { - zend_execute_data *ex = EG(current_execute_data); - - while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { - ex = ex->prev_execute_data; - } - if (ex) { - return ZSTR_VAL(ex->func->op_array.filename); - } else { - return "[no active file]"; - } + zend_string *filename = zend_get_executed_filename_ex(); + return filename != NULL ? ZSTR_VAL(filename) : "[no active file]"; } /* }}} */ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */ { + zend_string *filename_override = EG(filename_override); + if (filename_override != NULL) { + return filename_override; + } + zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { @@ -609,6 +623,11 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */ ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */ { + zend_long lineno_override = EG(lineno_override); + if (lineno_override != -1) { + return lineno_override; + } + zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 4d4b1ffe09b41..cbad169732e41 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -203,7 +203,7 @@ static int zend_extension_startup(zend_extension *extension) } -void zend_startup_extensions_mechanism() +void zend_startup_extensions_mechanism(void) { /* Startup extensions mechanism */ zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1); @@ -212,7 +212,7 @@ void zend_startup_extensions_mechanism() } -void zend_startup_extensions() +void zend_startup_extensions(void) { zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup); } @@ -267,8 +267,17 @@ ZEND_API int zend_get_resource_handle(const char *module_name) ZEND_API int zend_get_op_array_extension_handle(const char *module_name) { + int handle = zend_op_array_extension_handles++; zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int)); - return zend_op_array_extension_handles++; + return handle; +} + +ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles) +{ + int handle = zend_op_array_extension_handles; + zend_op_array_extension_handles += handles; + zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int)); + return handle; } ZEND_API zend_extension *zend_get_extension(const char *extension_name) diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 3b8e2b3453ade..95eb8dd10ef67 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -115,6 +115,7 @@ extern ZEND_API int zend_op_array_extension_handles; ZEND_API int zend_get_resource_handle(const char *module_name); ZEND_API int zend_get_op_array_extension_handle(const char *module_name); +ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles); ZEND_API void zend_extension_dispatch_message(int message, void *arg); END_EXTERN_C() diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index de7353013f0b4..3319b7aa34e64 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1695,7 +1695,7 @@ ZEND_API void zend_get_gc_buffer_grow(zend_get_gc_buffer *gc_buffer) { gc_buffer->cur = gc_buffer->start + old_capacity; } -static void zend_get_gc_buffer_release() { +static void zend_get_gc_buffer_release(void) { zend_get_gc_buffer *gc_buffer = &EG(get_gc_buffer); efree(gc_buffer->start); gc_buffer->start = gc_buffer->end = gc_buffer->cur = NULL; diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 965b9edb60b8f..c73563ec2f399 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -937,7 +937,7 @@ ZEND_METHOD(Generator, send) root = zend_generator_get_current(generator); /* Put sent value in the target VAR slot, if it is used */ - if (root->send_target) { + if (root->send_target && !(root->flags & ZEND_GENERATOR_CURRENTLY_RUNNING)) { ZVAL_COPY(root->send_target, value); } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 1726dee9ac12a..ccee57b3fb1bd 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -266,6 +266,10 @@ struct _zend_executor_globals { uint32_t num_errors; zend_error_info **errors; + /* Override filename or line number of thrown errors and exceptions */ + zend_string *filename_override; + zend_long lineno_override; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 82af3d8afa75a..2709fb5639186 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1285,7 +1285,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface) /* {{{ */ { if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce) == FAILURE) { - zend_error_noreturn(E_CORE_ERROR, "Class %s could not implement interface %s", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); + zend_error_noreturn(E_CORE_ERROR, "%s %s could not implement interface %s", zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); } /* This should be prevented by the class lookup logic. */ ZEND_ASSERT(ce != iface); @@ -1610,7 +1610,8 @@ static bool do_inherit_constant_check( if (old_constant->ce != parent_constant->ce && old_constant->ce != ce) { zend_error_noreturn(E_COMPILE_ERROR, - "Class %s inherits both %s::%s and %s::%s, which is ambiguous", + "%s %s inherits both %s::%s and %s::%s, which is ambiguous", + zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ZSTR_VAL(old_constant->ce->name), ZSTR_VAL(name), ZSTR_VAL(parent_constant->ce->name), ZSTR_VAL(name)); @@ -1729,7 +1730,10 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry if (interfaces[j] == iface) { if (j >= num_parent_interfaces) { efree(interfaces); - zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); + zend_error_noreturn(E_COMPILE_ERROR, "%s %s cannot implement previously implemented interface %s", + zend_get_object_type_uc(ce), + ZSTR_VAL(ce->name), + ZSTR_VAL(iface->name)); return; } /* skip duplications */ @@ -2311,6 +2315,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */ zend_function *func; zend_abstract_info ai; bool is_explicit_abstract = (ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) != 0; + bool can_be_abstract = (ce->ce_flags & ZEND_ACC_ENUM) == 0; memset(&ai, 0, sizeof(ai)); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, func) { @@ -2324,9 +2329,10 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */ } ZEND_HASH_FOREACH_END(); if (ai.cnt) { - zend_error_noreturn(E_ERROR, !is_explicit_abstract - ? "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")" - : "Class %s must implement %d abstract private method%s (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + zend_error_noreturn(E_ERROR, !is_explicit_abstract && can_be_abstract + ? "%s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")" + : "%s %s must implement %d abstract private method%s (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ai.cnt, ai.cnt > 1 ? "s" : "", DISPLAY_ABSTRACT_FN(0), diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 83162d3b46066..1fa2493f17af5 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -181,6 +181,14 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter) } /* }}} */ +ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n) +{ + zend_user_iterator *iter = (zend_user_iterator*)_iter; + *table = &iter->it.data; + *n = 1; + return NULL; +} + static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = { zend_user_it_dtor, zend_user_it_valid, @@ -189,7 +197,7 @@ static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = zend_user_it_move_forward, zend_user_it_rewind, zend_user_it_invalidate_current, - NULL, /* get_gc */ + zend_user_it_get_gc, }; /* {{{ zend_user_it_get_iterator */ @@ -258,7 +266,8 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en } } } - zend_error_noreturn(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s", + zend_error_noreturn(E_CORE_ERROR, "%s %s must implement interface %s as part of either %s or %s", + zend_get_object_type_uc(class_type), ZSTR_VAL(class_type->name), ZSTR_VAL(zend_ce_traversable->name), ZSTR_VAL(zend_ce_iterator->name), diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h index 2799e2c438154..a8351ee9a7823 100644 --- a/Zend/zend_interfaces.h +++ b/Zend/zend_interfaces.h @@ -55,6 +55,7 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter); ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter); ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter); +ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n); ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *iterator); ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a8bddfae50a3e..f6ba5465abebb 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1129,7 +1129,7 @@ expr: | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } | expr '^' expr { $$ = zend_ast_create_binary_op(ZEND_BW_XOR, $1, $3); } - | expr '.' expr { $$ = zend_ast_create_binary_op(ZEND_CONCAT, $1, $3); } + | expr '.' expr { $$ = zend_ast_create_concat_op($1, $3); } | expr '+' expr { $$ = zend_ast_create_binary_op(ZEND_ADD, $1, $3); } | expr '-' expr { $$ = zend_ast_create_binary_op(ZEND_SUB, $1, $3); } | expr '*' expr { $$ = zend_ast_create_binary_op(ZEND_MUL, $1, $3); } diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h index f2fe96f19a72c..aa726e0cdd32d 100644 --- a/Zend/zend_map_ptr.h +++ b/Zend/zend_map_ptr.h @@ -69,9 +69,13 @@ # error "Unknown ZEND_MAP_PTR_KIND" #endif +BEGIN_EXTERN_C() + ZEND_API void zend_map_ptr_reset(void); ZEND_API void *zend_map_ptr_new(void); ZEND_API void zend_map_ptr_extend(size_t last); ZEND_API void zend_alloc_ce_cache(zend_string *type_name); +END_EXTERN_C() + #endif /* ZEND_MAP_PTR_H */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index e75ff8318cb48..746897f641e0e 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -277,10 +277,22 @@ static ZEND_COLD zend_never_inline void zend_forbidden_dynamic_property( ZSTR_VAL(ce->name), ZSTR_VAL(member)); } -static ZEND_COLD zend_never_inline void zend_deprecated_dynamic_property( - zend_class_entry *ce, zend_string *member) { +static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( + zend_object *obj, zend_string *member) { + GC_ADDREF(obj); zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated", - ZSTR_VAL(ce->name), ZSTR_VAL(member)); + ZSTR_VAL(obj->ce->name), ZSTR_VAL(member)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_class_entry *ce = obj->ce; + zend_objects_store_del(obj); + if (!EG(exception)) { + /* We cannot continue execution and have to throw an exception */ + zend_throw_error(NULL, "Cannot create dynamic property %s::$%s", + ZSTR_VAL(ce->name), ZSTR_VAL(member)); + } + return 0; + } + return 1; } static ZEND_COLD zend_never_inline void zend_readonly_property_modification_scope_error( @@ -880,7 +892,10 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva goto exit; } if (UNEXPECTED(!(zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES))) { - zend_deprecated_dynamic_property(zobj->ce, name); + if (UNEXPECTED(!zend_deprecated_dynamic_property(zobj, name))) { + variable_ptr = &EG(error_zval); + goto exit; + } } Z_TRY_ADDREF_P(value); @@ -1063,7 +1078,9 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam return &EG(error_zval); } if (UNEXPECTED(!(zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES))) { - zend_deprecated_dynamic_property(zobj->ce, name); + if (UNEXPECTED(!zend_deprecated_dynamic_property(zobj, name))) { + return &EG(error_zval); + } } if (UNEXPECTED(!zobj->properties)) { rebuild_object_properties(zobj); diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index 6574fc68d1c34..508cff3212a7c 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -31,13 +31,6 @@ #define ZEND_OBSERVABLE_FN(fn_flags) \ (!(fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) -typedef struct _zend_observer_fcall_data { - // points after the last handler - zend_observer_fcall_handlers *end; - // a variadic array using "struct hack" - zend_observer_fcall_handlers handlers[1]; -} zend_observer_fcall_data; - zend_llist zend_observers_fcall_list; zend_llist zend_observer_error_callbacks; zend_llist zend_observer_fiber_init; @@ -46,33 +39,18 @@ zend_llist zend_observer_fiber_destroy; int zend_observer_fcall_op_array_extension; -ZEND_TLS zend_arena *fcall_handlers_arena; ZEND_TLS zend_execute_data *first_observed_frame; ZEND_TLS zend_execute_data *current_observed_frame; // Call during minit/startup ONLY -ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) { - if (!ZEND_OBSERVER_ENABLED) { - /* We don't want to get an extension handle unless an ext installs an observer */ - zend_observer_fcall_op_array_extension = - zend_get_op_array_extension_handle("Zend Observer"); - - /* ZEND_CALL_TRAMPOLINE has SPEC(OBSERVER) but zend_init_call_trampoline_op() - * is called before any extensions have registered as an observer. So we - * adjust the offset to the observed handler when we know we need to observe. */ - ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op)); - - /* ZEND_HANDLE_EXCEPTION also has SPEC(OBSERVER) and no observer extensions - * exist when zend_init_exception_op() is called. */ - ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)); - ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1); - ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2); - } +ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) +{ zend_llist_add_element(&zend_observers_fcall_list, &init); } // Called by engine before MINITs -ZEND_API void zend_observer_startup(void) { +ZEND_API void zend_observer_startup(void) +{ zend_llist_init(&zend_observers_fcall_list, sizeof(zend_observer_fcall_init), NULL, 1); zend_llist_init(&zend_observer_error_callbacks, sizeof(zend_observer_error_cb), NULL, 1); zend_llist_init(&zend_observer_fiber_init, sizeof(zend_observer_fiber_init_handler), NULL, 1); @@ -82,23 +60,40 @@ ZEND_API void zend_observer_startup(void) { zend_observer_fcall_op_array_extension = -1; } -ZEND_API void zend_observer_activate(void) { - if (ZEND_OBSERVER_ENABLED) { - fcall_handlers_arena = zend_arena_create(4096); - } else { - fcall_handlers_arena = NULL; +ZEND_API void zend_observer_post_startup(void) +{ + if (zend_observers_fcall_list.count) { + /* We don't want to get an extension handle unless an ext installs an observer + * Allocate each a begin and an end pointer */ + zend_observer_fcall_op_array_extension = + zend_get_op_array_extension_handles("Zend Observer", (int) zend_observers_fcall_list.count * 2); + + /* ZEND_CALL_TRAMPOLINE has SPEC(OBSERVER) but zend_init_call_trampoline_op() + * is called before any extensions have registered as an observer. So we + * adjust the offset to the observed handler when we know we need to observe. */ + ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op)); + + /* ZEND_HANDLE_EXCEPTION also has SPEC(OBSERVER) and no observer extensions + * exist when zend_init_exception_op() is called. */ + ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)); + ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op) + 1); + ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op) + 2); } +} + +ZEND_API void zend_observer_activate(void) +{ first_observed_frame = NULL; current_observed_frame = NULL; } -ZEND_API void zend_observer_deactivate(void) { - if (fcall_handlers_arena) { - zend_arena_destroy(fcall_handlers_arena); - } +ZEND_API void zend_observer_deactivate(void) +{ + // now empty and unused, but kept for ABI compatibility } -ZEND_API void zend_observer_shutdown(void) { +ZEND_API void zend_observer_shutdown(void) +{ zend_llist_destroy(&zend_observers_fcall_list); zend_llist_destroy(&zend_observer_error_callbacks); zend_llist_destroy(&zend_observer_fiber_init); @@ -106,88 +101,76 @@ ZEND_API void zend_observer_shutdown(void) { zend_llist_destroy(&zend_observer_fiber_destroy); } -static void zend_observer_fcall_install(zend_execute_data *execute_data) { - zend_llist_element *element; +static void zend_observer_fcall_install(zend_execute_data *execute_data) +{ zend_llist *list = &zend_observers_fcall_list; zend_function *function = execute_data->func; zend_op_array *op_array = &function->op_array; - if (fcall_handlers_arena == NULL) { - return; - } - ZEND_ASSERT(function->type != ZEND_INTERNAL_FUNCTION); - zend_llist handlers_list; - zend_llist_init(&handlers_list, sizeof(zend_observer_fcall_handlers), NULL, 0); - for (element = list->head; element; element = element->next) { + ZEND_ASSERT(RUN_TIME_CACHE(op_array)); + zend_observer_fcall_begin_handler *begin_handlers = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array); + zend_observer_fcall_end_handler *end_handlers = (zend_observer_fcall_end_handler *)begin_handlers + list->count, *end_handlers_start = end_handlers; + + *begin_handlers = ZEND_OBSERVER_NOT_OBSERVED; + *end_handlers = ZEND_OBSERVER_NOT_OBSERVED; + + for (zend_llist_element *element = list->head; element; element = element->next) { zend_observer_fcall_init init; memcpy(&init, element->data, sizeof init); zend_observer_fcall_handlers handlers = init(execute_data); - if (handlers.begin || handlers.end) { - zend_llist_add_element(&handlers_list, &handlers); + if (handlers.begin) { + *(begin_handlers++) = handlers.begin; } - } - - ZEND_ASSERT(RUN_TIME_CACHE(op_array)); - void *ext; - if (handlers_list.count) { - size_t size = sizeof(zend_observer_fcall_data) + (handlers_list.count - 1) * sizeof(zend_observer_fcall_handlers); - zend_observer_fcall_data *fcall_data = zend_arena_alloc(&fcall_handlers_arena, size); - zend_observer_fcall_handlers *handlers = fcall_data->handlers; - for (element = handlers_list.head; element; element = element->next) { - memcpy(handlers++, element->data, sizeof *handlers); + if (handlers.end) { + *(end_handlers++) = handlers.end; } - fcall_data->end = handlers; - ext = fcall_data; - } else { - ext = ZEND_OBSERVER_NOT_OBSERVED; } - - ZEND_OBSERVER_DATA(op_array) = ext; - zend_llist_destroy(&handlers_list); + + // end handlers are executed in reverse order + for (--end_handlers; end_handlers_start < end_handlers; --end_handlers, ++end_handlers_start) { + zend_observer_fcall_end_handler tmp = *end_handlers; + *end_handlers = *end_handlers_start; + *end_handlers_start = tmp; + } } static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_data) { - zend_op_array *op_array; - uint32_t fn_flags; - zend_observer_fcall_data *fcall_data; - zend_observer_fcall_handlers *handlers, *end; - if (!ZEND_OBSERVER_ENABLED) { return; } - op_array = &execute_data->func->op_array; - fn_flags = op_array->fn_flags; + zend_op_array *op_array = &execute_data->func->op_array; + uint32_t fn_flags = op_array->fn_flags; if (!ZEND_OBSERVABLE_FN(fn_flags)) { return; } - fcall_data = ZEND_OBSERVER_DATA(op_array); - if (!fcall_data) { + zend_observer_fcall_begin_handler *handler = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array); + if (!*handler) { zend_observer_fcall_install(execute_data); - fcall_data = ZEND_OBSERVER_DATA(op_array); } - ZEND_ASSERT(fcall_data); - if (fcall_data == ZEND_OBSERVER_NOT_OBSERVED) { - return; - } + zend_observer_fcall_begin_handler *possible_handlers_end = handler + zend_observers_fcall_list.count; - if (first_observed_frame == NULL) { - first_observed_frame = execute_data; + zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)possible_handlers_end; + if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) { + if (first_observed_frame == NULL) { + first_observed_frame = execute_data; + } + current_observed_frame = execute_data; } - current_observed_frame = execute_data; - end = fcall_data->end; - for (handlers = fcall_data->handlers; handlers != end; ++handlers) { - if (handlers->begin) { - handlers->begin(execute_data); - } + if (*handler == ZEND_OBSERVER_NOT_OBSERVED) { + return; } + + do { + (*handler)(execute_data); + } while (++handler != possible_handlers_end && *handler != NULL); } ZEND_API void ZEND_FASTCALL zend_observer_generator_resume(zend_execute_data *execute_data) @@ -203,43 +186,48 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute } } -ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( - zend_execute_data *execute_data, - zval *return_value) +static inline bool zend_observer_is_skipped_frame(zend_execute_data *execute_data) { + zend_function *func = execute_data->func; + + if (!func || func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) { + return true; + } + + zend_observer_fcall_end_handler end_handler = (&ZEND_OBSERVER_DATA(&func->op_array))[zend_observers_fcall_list.count]; + if (end_handler == NULL || end_handler == ZEND_OBSERVER_NOT_OBSERVED) { + return true; + } + + return false; +} + +ZEND_API void ZEND_FASTCALL zend_observer_fcall_end(zend_execute_data *execute_data, zval *return_value) { zend_function *func = execute_data->func; - zend_observer_fcall_data *fcall_data; - zend_observer_fcall_handlers *handlers, *end; if (!ZEND_OBSERVER_ENABLED || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) { return; } - fcall_data = (zend_observer_fcall_data*)ZEND_OBSERVER_DATA(&func->op_array); + zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(&func->op_array) + zend_observers_fcall_list.count; // TODO: Fix exceptions from generators // ZEND_ASSERT(fcall_data); - if (!fcall_data || fcall_data == ZEND_OBSERVER_NOT_OBSERVED) { + if (!*handler || *handler == ZEND_OBSERVER_NOT_OBSERVED) { return; } - handlers = fcall_data->end; - end = fcall_data->handlers; - while (handlers-- != end) { - if (handlers->end) { - handlers->end(execute_data, return_value); - } - } + zend_observer_fcall_end_handler *possible_handlers_end = handler + zend_observers_fcall_list.count; + do { + (*handler)(execute_data, return_value); + } while (++handler != possible_handlers_end && *handler != NULL); if (first_observed_frame == execute_data) { first_observed_frame = NULL; current_observed_frame = NULL; } else { zend_execute_data *ex = execute_data->prev_execute_data; - while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION - || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) - || !ZEND_OBSERVER_DATA(&ex->func->op_array) - || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { + while (ex && zend_observer_is_skipped_frame(ex)) { ex = ex->prev_execute_data; } current_observed_frame = ex; @@ -255,7 +243,6 @@ ZEND_API void zend_observer_fcall_end_all(void) } ex = ex->prev_execute_data; } - current_observed_frame = NULL; } ZEND_API void zend_observer_error_register(zend_observer_error_cb cb) @@ -265,11 +252,8 @@ ZEND_API void zend_observer_error_register(zend_observer_error_cb cb) void zend_observer_error_notify(int type, zend_string *error_filename, uint32_t error_lineno, zend_string *message) { - zend_llist_element *element; - zend_observer_error_cb callback; - - for (element = zend_observer_error_callbacks.head; element; element = element->next) { - callback = *(zend_observer_error_cb *) (element->data); + for (zend_llist_element *element = zend_observer_error_callbacks.head; element; element = element->next) { + zend_observer_error_cb callback = *(zend_observer_error_cb *) (element->data); callback(type, error_filename, error_lineno, message); } } diff --git a/Zend/zend_observer.h b/Zend/zend_observer.h index 8df0ed3247526..b43ff1e4f6557 100644 --- a/Zend/zend_observer.h +++ b/Zend/zend_observer.h @@ -57,6 +57,7 @@ typedef zend_observer_fcall_handlers (*zend_observer_fcall_init)(zend_execute_da ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init); ZEND_API void zend_observer_startup(void); // Called by engine before MINITs +ZEND_API void zend_observer_post_startup(void); // Called by engine after MINITs ZEND_API void zend_observer_activate(void); ZEND_API void zend_observer_deactivate(void); ZEND_API void zend_observer_shutdown(void); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index b215e5120af5b..9e27c2fea142b 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -156,6 +156,11 @@ ZEND_API void zend_function_dtor(zval *zv) /* For methods this will be called explicitly. */ if (!function->common.scope) { zend_free_internal_arg_info(&function->internal_function); + + if (function->common.attributes) { + zend_hash_release(function->common.attributes); + function->common.attributes = NULL; + } } if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) { @@ -433,11 +438,17 @@ ZEND_API void destroy_zend_class(zval *zv) zend_hash_destroy(&ce->properties_info); zend_string_release_ex(ce->name, 1); - /* TODO: eliminate this loop for classes without functions with arg_info */ + /* TODO: eliminate this loop for classes without functions with arg_info / attributes */ ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) { - if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) && - fn->common.scope == ce) { - zend_free_internal_arg_info(&fn->internal_function); + if (fn->common.scope == ce) { + if (fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) { + zend_free_internal_arg_info(&fn->internal_function); + } + + if (fn->common.attributes) { + zend_hash_release(fn->common.attributes); + fn->common.attributes = NULL; + } } } ZEND_HASH_FOREACH_END(); @@ -1077,10 +1088,6 @@ ZEND_API void pass_two(zend_op_array *op_array) case ZEND_JMP: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); break; - case ZEND_JMPZNZ: - /* absolute index to relative offset */ - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index de3664f5c653f..8a0cc8131be44 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1997,7 +1997,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool int ret; if (case_insensitive) { - ret = zend_binary_strcasecmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)); + ret = zend_binary_strcasecmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); } else { ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); } @@ -2043,7 +2043,7 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* zend_string *tmp_str1, *tmp_str2; zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); - int ret = zend_binary_strcasecmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)); + int ret = zend_binary_strcasecmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); zend_tmp_string_release(tmp_str1); zend_tmp_string_release(tmp_str2); diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index eb88eedb79da1..346706d22beae 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -919,6 +919,67 @@ static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */ } /* }}} */ +static zend_always_inline bool zend_strnieq(const char *ptr1, const char *ptr2, size_t num) +{ + const char *end = ptr1 + num; + while (ptr1 < end) { + if (zend_tolower_ascii(*ptr1++) != zend_tolower_ascii(*ptr2++)) { + return 0; + } + } + return 1; +} + +static zend_always_inline const char * +zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const char *end) +{ + ZEND_ASSERT(end >= haystack); + + if (UNEXPECTED(needle_len == 0)) { + return haystack; + } + + if (UNEXPECTED(needle_len > (size_t)(end - haystack))) { + return NULL; + } + + const char first_lower = zend_tolower_ascii(*needle); + const char first_upper = zend_toupper_ascii(*needle); + const char *p_lower = (const char *)memchr(haystack, first_lower, end - haystack); + const char *p_upper = NULL; + if (first_lower != first_upper) { + // If the needle length is 1 we don't need to look beyond p_lower as it is a guaranteed match + size_t upper_search_length = end - (needle_len == 1 && p_lower != NULL ? p_lower : haystack); + p_upper = (const char *)memchr(haystack, first_upper, upper_search_length); + } + const char *p = !p_upper || (p_lower && p_lower < p_upper) ? p_lower : p_upper; + + if (needle_len == 1) { + return p; + } + + const char needle_end_lower = zend_tolower_ascii(needle[needle_len - 1]); + const char needle_end_upper = zend_toupper_ascii(needle[needle_len - 1]); + end -= needle_len; + + while (p && p <= end) { + if (needle_end_lower == p[needle_len - 1] || needle_end_upper == p[needle_len - 1]) { + if (zend_strnieq(needle + 1, p + 1, needle_len - 2)) { + return p; + } + } + if (p_lower == p) { + p_lower = (const char *)memchr(p_lower + 1, first_lower, end - p_lower); + } + if (p_upper == p) { + p_upper = (const char *)memchr(p_upper + 1, first_upper, end - p_upper); + } + p = !p_upper || (p_lower && p_lower < p_upper) ? p_lower : p_upper; + } + + return NULL; +} + END_EXTERN_C() diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index aadc62558e601..ae2c734b09b4e 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -214,7 +214,10 @@ static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ { switch (fh->type) { case ZEND_HANDLE_FP: - fclose(fh->handle.fp); + if (fh->handle.fp) { + fclose(fh->handle.fp); + fh->handle.fp = NULL; + } break; case ZEND_HANDLE_STREAM: if (fh->handle.stream.closer && fh->handle.stream.handle) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f0ad4037eb145..5207a09d34dea 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3010,41 +3010,6 @@ ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = OP1_TYPE; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE @@ -7577,39 +7542,44 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMPVARCV, JMP_ADDR) +ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE - zval *val; + zval *val, *result; val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - if (OP1_TYPE != IS_CONST) { - ZVAL_DEREF(val); - } - - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + FREE_OP1(); + break; } } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } ZEND_VM_HOT_HANDLER(31, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 78dab76a303fb..cb9654688e919 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4086,41 +4086,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_ ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = RT_CONSTANT(opline, opline->op1); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = IS_CONST; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -5261,36 +5226,41 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *val, *result; val = RT_CONSTANT(opline, opline->op1); - if (IS_CONST != IS_CONST) { - ZVAL_DEREF(val); - } - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + break; } } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -12092,41 +12062,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR ZEND_VM_TAIL_CALL(zend_bw_not_helper_SPEC(op1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - - val = EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST) { - ZVAL_DEREF(val); - } - - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); - - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } - - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } -} - static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14241,41 +14176,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_ ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -19423,6 +19323,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22306,6 +22246,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -38123,41 +38103,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HAND ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = IS_CV; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -38974,6 +38919,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_ ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = EX_VAR(opline->op1.var); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53094,11 +53079,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPNZ_SPEC_CV_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_CV_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_CONST_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, @@ -54370,10 +54350,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_CONST_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_TMP_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_CV_LABEL, (void*)&&ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_LABEL, @@ -55718,10 +55698,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_CONST) ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_CONST): - VM_TRACE(ZEND_JMPZNZ_SPEC_CONST) - ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_CONST): VM_TRACE(ZEND_JMPZ_EX_SPEC_CONST) ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56553,10 +56529,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_BW_NOT_SPEC_TMPVARCV) ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMP_NULL_SPEC_TMPVARCV): - VM_TRACE(ZEND_JMP_NULL_SPEC_TMPVARCV) - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV): VM_TRACE(ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56997,10 +56969,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_TMPVAR) ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPZNZ_SPEC_TMPVAR) - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR): VM_TRACE(ZEND_JMPZ_EX_SPEC_TMPVAR) ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -57458,6 +57426,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_TMP) ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_TMP): + VM_TRACE(ZEND_JMP_NULL_SPEC_TMP) + ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_TMP): VM_TRACE(ZEND_QM_ASSIGN_SPEC_TMP) ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -57763,6 +57735,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_VAR) ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_VAR): + VM_TRACE(ZEND_JMP_NULL_SPEC_VAR) + ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR): VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR) ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -58763,10 +58739,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_CV) ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_CV): - VM_TRACE(ZEND_JMPZNZ_SPEC_CV) - ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_CV): VM_TRACE(ZEND_JMPZ_EX_SPEC_CV) ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -58900,6 +58872,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_CV) ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_CV): + VM_TRACE(ZEND_JMP_NULL_SPEC_CV) + ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_CV): VM_TRACE(ZEND_QM_ASSIGN_SPEC_CV) ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61154,11 +61130,6 @@ void zend_vm_init(void) ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, ZEND_JMPZ_EX_SPEC_CONST_HANDLER, ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, @@ -62430,10 +62401,10 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER, ZEND_JMP_NULL_SPEC_CONST_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, + ZEND_JMP_NULL_SPEC_TMP_HANDLER, + ZEND_JMP_NULL_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, + ZEND_JMP_NULL_SPEC_CV_HANDLER, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER, @@ -63389,165 +63360,165 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, + 3448, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, - 1276 | SPEC_RULE_OP1, - 1281 | SPEC_RULE_OP2, - 1286, - 1287 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1276 | SPEC_RULE_OP2, + 1281, + 1282 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1292 | SPEC_RULE_OP1, 1297 | SPEC_RULE_OP1, - 1302 | SPEC_RULE_OP1, - 1307 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1302 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1327 | SPEC_RULE_OP2, 1332 | SPEC_RULE_OP2, 1337 | SPEC_RULE_OP2, - 1342 | SPEC_RULE_OP2, - 1347, - 1348, + 1342, + 1343, + 1344, + 1345 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, 1349, - 1350 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 1354, - 1355 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1365, - 1366, - 1367 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1392 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 1442 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1467 | SPEC_RULE_OP1, - 1472, - 1473, - 1474 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1499 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1524 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1534 | SPEC_RULE_OP1, - 1539 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1564 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1589 | SPEC_RULE_OP1, - 1594, - 1595, - 1596 | SPEC_RULE_OP1, - 1601 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1626 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1651 | SPEC_RULE_OP1, - 1656 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1681 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1706 | SPEC_RULE_OP1, - 1711 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1736 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1761 | SPEC_RULE_OP1, - 1766 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1791 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1816 | SPEC_RULE_OP1, - 1821 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1846 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1871 | SPEC_RULE_OP1, - 1876 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1901 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1926 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1951, - 1952 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 1962, - 1963, - 1964, - 1965, - 1966, - 1967 | SPEC_RULE_OP2, - 1972, - 1973 | SPEC_RULE_OP1, - 1978 | SPEC_RULE_OP2, - 1983 | SPEC_RULE_OP1, - 1988 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1998 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2023 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2048 | SPEC_RULE_OP1, - 2053 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2078 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 2128 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2153 | SPEC_RULE_OP2, - 2158, + 1350 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1360, + 1361, + 1362 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1387 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1437 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1462 | SPEC_RULE_OP1, + 1467, + 1468, + 1469 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1494 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1519 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1529 | SPEC_RULE_OP1, + 1534 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 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, + 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 | SPEC_RULE_OP1, - 2169, + 2164, + 2165 | SPEC_RULE_OP1, 2170 | SPEC_RULE_OP1, 2175 | SPEC_RULE_OP1, - 2180 | SPEC_RULE_OP1, - 2185, - 2186, - 2187 | SPEC_RULE_OP2, - 2192 | SPEC_RULE_RETVAL, - 2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2198 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2252 | SPEC_RULE_OP1, - 2257, - 2258 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2283, - 2284 | SPEC_RULE_OP1, + 2180, + 2181, + 2182 | SPEC_RULE_OP2, + 2187 | SPEC_RULE_RETVAL, + 2189 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2193 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2247 | SPEC_RULE_OP1, + 2252, + 2253 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2278, + 2279 | SPEC_RULE_OP1, + 2284, + 2285, + 2286, + 2287, + 2288, 2289, 2290, - 2291, - 2292, - 2293, - 2294, - 2295, - 2296 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2321, - 2322, - 2323, - 2324 | SPEC_RULE_OP1, - 2329, - 2330 | SPEC_RULE_ISSET, - 2332 | SPEC_RULE_OP2, - 2337, - 2338 | SPEC_RULE_OP1, - 2343 | SPEC_RULE_OBSERVER, - 2345, - 2346 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2371 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 2381, - 2382, - 2383, - 2384, - 2385 | SPEC_RULE_OP1, - 2390, - 2391, - 2392 | SPEC_RULE_OP1, - 2397 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2422, - 2423 | SPEC_RULE_OP1, + 2291 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2316, + 2317, + 2318, + 2319 | SPEC_RULE_OP1, + 2324, + 2325 | SPEC_RULE_ISSET, + 2327 | SPEC_RULE_OP2, + 2332, + 2333 | SPEC_RULE_OP1, + 2338 | SPEC_RULE_OBSERVER, + 2340, + 2341 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2366 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2376, + 2377, + 2378, + 2379, + 2380 | SPEC_RULE_OP1, + 2385, + 2386, + 2387 | SPEC_RULE_OP1, + 2392 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2417, + 2418 | SPEC_RULE_OP1, + 2423, + 2424, + 2425, + 2426, + 2427, 2428, 2429, 2430, - 2431, - 2432, - 2433, - 2434, - 2435, - 2436 | SPEC_RULE_OP1, - 2441, - 2442, - 2443, - 2444 | SPEC_RULE_OP2, - 2449, + 2431 | SPEC_RULE_OP1, + 2436, + 2437, + 2438, + 2439 | SPEC_RULE_OP2, + 2444, + 2445 | SPEC_RULE_OP1, 2450 | SPEC_RULE_OP1, 2455 | SPEC_RULE_OP1, 2460 | SPEC_RULE_OP1, 2465 | SPEC_RULE_OP1, - 2470 | SPEC_RULE_OP1, - 2475, - 2476 | SPEC_RULE_OP1, - 2481 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2506 | SPEC_RULE_OP1, - 2511 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2470, + 2471 | SPEC_RULE_OP1, + 2476 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2501 | SPEC_RULE_OP1, + 2506 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2531 | SPEC_RULE_OP1, 2536 | SPEC_RULE_OP1, - 2541 | SPEC_RULE_OP1, - 2546, - 2547, - 2548, - 2549, - 3453 + 2541, + 2542, + 2543, + 2544, + 3448 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -63720,7 +63691,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 = 2552 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2547 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63728,7 +63699,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 = 2577 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2572 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63736,7 +63707,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 = 2602 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2597 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63747,17 +63718,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 = 2627 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2622 | 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 = 2652 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2647 | 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 = 2677 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2672 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -63768,17 +63739,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 = 2702 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2697 | 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 = 2727 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2722 | 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 = 2752 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2747 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -63789,14 +63760,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 = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2772 | 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 = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2847 | 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 = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3072 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -63807,14 +63778,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 = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2922 | 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 = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2997 | 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 = 3082 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -63825,12 +63796,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 = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2772 | 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 = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -63841,12 +63812,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 = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2922 | 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 = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -63854,12 +63825,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 = 3087 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3082 | 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 = 3162 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3157 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -63867,74 +63838,74 @@ 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 = 3237 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3232 | 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 = 3312 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3307 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3399 | SPEC_RULE_OP1; + spec = 3394 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3404 | SPEC_RULE_OP1; + spec = 3399 | 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 = 3409 | SPEC_RULE_OP1; + spec = 3404 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3387 | SPEC_RULE_RETVAL; + spec = 3382 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3389 | SPEC_RULE_RETVAL; + spec = 3384 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3391 | SPEC_RULE_RETVAL; + spec = 3386 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3393 | SPEC_RULE_RETVAL; + spec = 3388 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3395; + spec = 3390; } else if (op1_info == MAY_BE_LONG) { - spec = 3396; + spec = 3391; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3397; + spec = 3392; } else if (op1_info == MAY_BE_LONG) { - spec = 3398; + spec = 3393; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2551; + spec = 2546; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2550; + spec = 2545; } 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 = 3449; + spec = 3444; } 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 = 3444 | SPEC_RULE_OP1; + spec = 3439 | 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 = 3451 | SPEC_RULE_RETVAL; + spec = 3446 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -63942,17 +63913,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 = 3414 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3409 | 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 = 3450; + spec = 3445; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3439 | SPEC_RULE_OP1; + spec = 3434 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 0fba09b294164..ed3b9fecf1d8a 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2651,7 +2651,8 @@ function gen_vm($def, $skel) { fputs($f, "ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) {\n"); fputs($f, "\tzend_uchar opcode;\n"); fputs($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n"); - fputs($f, "\t\tif (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) {\n"); + fputs($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n"); + fputs($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n"); fputs($f, "\t\t\treturn opcode;\n"); fputs($f, "\t\t}\n"); fputs($f, "\t}\n"); diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index a5796187e11be..5f651ded1f35f 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -575,1278 +575,1274 @@ _(1262, ZEND_JMPNZ_SPEC_TMPVAR) \ _(1263, ZEND_JMPNZ_SPEC_TMPVAR) \ _(1265, ZEND_JMPNZ_SPEC_CV) \ - _(1266, ZEND_JMPZNZ_SPEC_CONST) \ - _(1267, ZEND_JMPZNZ_SPEC_TMPVAR) \ - _(1268, ZEND_JMPZNZ_SPEC_TMPVAR) \ - _(1270, ZEND_JMPZNZ_SPEC_CV) \ - _(1271, ZEND_JMPZ_EX_SPEC_CONST) \ - _(1272, ZEND_JMPZ_EX_SPEC_TMPVAR) \ - _(1273, ZEND_JMPZ_EX_SPEC_TMPVAR) \ - _(1275, ZEND_JMPZ_EX_SPEC_CV) \ - _(1276, ZEND_JMPNZ_EX_SPEC_CONST) \ - _(1277, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ - _(1278, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ - _(1280, ZEND_JMPNZ_EX_SPEC_CV) \ - _(1281, ZEND_CASE_SPEC_TMPVAR_CONST) \ - _(1282, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1283, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1285, ZEND_CASE_SPEC_TMPVAR_CV) \ - _(1286, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \ - _(1287, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ - _(1288, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ - _(1293, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED) \ - _(1294, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \ - _(1297, ZEND_CAST_SPEC_CONST) \ - _(1298, ZEND_CAST_SPEC_TMP) \ - _(1299, ZEND_CAST_SPEC_VAR) \ - _(1301, ZEND_CAST_SPEC_CV) \ - _(1302, ZEND_BOOL_SPEC_CONST) \ - _(1303, ZEND_BOOL_SPEC_TMPVAR) \ - _(1304, ZEND_BOOL_SPEC_TMPVAR) \ - _(1306, ZEND_BOOL_SPEC_CV) \ - _(1307, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \ - _(1308, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ - _(1309, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ - _(1311, ZEND_FAST_CONCAT_SPEC_CONST_CV) \ + _(1266, ZEND_JMPZ_EX_SPEC_CONST) \ + _(1267, ZEND_JMPZ_EX_SPEC_TMPVAR) \ + _(1268, ZEND_JMPZ_EX_SPEC_TMPVAR) \ + _(1270, ZEND_JMPZ_EX_SPEC_CV) \ + _(1271, ZEND_JMPNZ_EX_SPEC_CONST) \ + _(1272, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ + _(1273, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ + _(1275, ZEND_JMPNZ_EX_SPEC_CV) \ + _(1276, ZEND_CASE_SPEC_TMPVAR_CONST) \ + _(1277, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ + _(1278, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ + _(1280, ZEND_CASE_SPEC_TMPVAR_CV) \ + _(1281, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \ + _(1282, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ + _(1283, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ + _(1288, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED) \ + _(1289, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \ + _(1292, ZEND_CAST_SPEC_CONST) \ + _(1293, ZEND_CAST_SPEC_TMP) \ + _(1294, ZEND_CAST_SPEC_VAR) \ + _(1296, ZEND_CAST_SPEC_CV) \ + _(1297, ZEND_BOOL_SPEC_CONST) \ + _(1298, ZEND_BOOL_SPEC_TMPVAR) \ + _(1299, ZEND_BOOL_SPEC_TMPVAR) \ + _(1301, ZEND_BOOL_SPEC_CV) \ + _(1302, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \ + _(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ + _(1304, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ + _(1306, ZEND_FAST_CONCAT_SPEC_CONST_CV) \ + _(1307, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ + _(1308, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ + _(1309, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ + _(1311, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ _(1312, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ _(1313, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ _(1314, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ _(1316, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ - _(1317, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ - _(1318, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1319, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1321, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ - _(1327, ZEND_FAST_CONCAT_SPEC_CV_CONST) \ - _(1328, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ - _(1329, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ - _(1331, ZEND_FAST_CONCAT_SPEC_CV_CV) \ - _(1332, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \ - _(1333, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ - _(1334, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ - _(1336, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \ - _(1337, ZEND_ROPE_ADD_SPEC_TMP_CONST) \ - _(1338, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ - _(1339, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ - _(1341, ZEND_ROPE_ADD_SPEC_TMP_CV) \ - _(1342, ZEND_ROPE_END_SPEC_TMP_CONST) \ - _(1343, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ - _(1344, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ - _(1346, ZEND_ROPE_END_SPEC_TMP_CV) \ - _(1347, ZEND_BEGIN_SILENCE_SPEC) \ - _(1348, ZEND_END_SILENCE_SPEC_TMP) \ - _(1349, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST) \ - _(1350, ZEND_DO_FCALL_SPEC_RETVAL_UNUSED) \ - _(1351, ZEND_DO_FCALL_SPEC_RETVAL_USED) \ - _(1352, ZEND_DO_FCALL_SPEC_OBSERVER) \ - _(1353, ZEND_DO_FCALL_SPEC_OBSERVER) \ - _(1354, ZEND_INIT_FCALL_SPEC_CONST) \ - _(1355, ZEND_RETURN_SPEC_CONST) \ - _(1356, ZEND_RETURN_SPEC_OBSERVER) \ - _(1357, ZEND_RETURN_SPEC_TMP) \ - _(1358, ZEND_RETURN_SPEC_OBSERVER) \ - _(1359, ZEND_RETURN_SPEC_VAR) \ - _(1360, ZEND_RETURN_SPEC_OBSERVER) \ - _(1363, ZEND_RETURN_SPEC_CV) \ - _(1364, ZEND_RETURN_SPEC_OBSERVER) \ - _(1365, ZEND_RECV_SPEC_UNUSED) \ - _(1366, ZEND_RECV_INIT_SPEC_CONST) \ - _(1367, ZEND_SEND_VAL_SPEC_CONST_CONST) \ - _(1370, ZEND_SEND_VAL_SPEC_CONST_UNUSED) \ + _(1322, ZEND_FAST_CONCAT_SPEC_CV_CONST) \ + _(1323, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ + _(1324, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ + _(1326, ZEND_FAST_CONCAT_SPEC_CV_CV) \ + _(1327, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \ + _(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ + _(1329, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ + _(1331, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \ + _(1332, ZEND_ROPE_ADD_SPEC_TMP_CONST) \ + _(1333, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ + _(1334, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ + _(1336, ZEND_ROPE_ADD_SPEC_TMP_CV) \ + _(1337, ZEND_ROPE_END_SPEC_TMP_CONST) \ + _(1338, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ + _(1339, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ + _(1341, ZEND_ROPE_END_SPEC_TMP_CV) \ + _(1342, ZEND_BEGIN_SILENCE_SPEC) \ + _(1343, ZEND_END_SILENCE_SPEC_TMP) \ + _(1344, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST) \ + _(1345, ZEND_DO_FCALL_SPEC_RETVAL_UNUSED) \ + _(1346, ZEND_DO_FCALL_SPEC_RETVAL_USED) \ + _(1347, ZEND_DO_FCALL_SPEC_OBSERVER) \ + _(1348, ZEND_DO_FCALL_SPEC_OBSERVER) \ + _(1349, ZEND_INIT_FCALL_SPEC_CONST) \ + _(1350, ZEND_RETURN_SPEC_CONST) \ + _(1351, ZEND_RETURN_SPEC_OBSERVER) \ + _(1352, ZEND_RETURN_SPEC_TMP) \ + _(1353, ZEND_RETURN_SPEC_OBSERVER) \ + _(1354, ZEND_RETURN_SPEC_VAR) \ + _(1355, ZEND_RETURN_SPEC_OBSERVER) \ + _(1358, ZEND_RETURN_SPEC_CV) \ + _(1359, ZEND_RETURN_SPEC_OBSERVER) \ + _(1360, ZEND_RECV_SPEC_UNUSED) \ + _(1361, ZEND_RECV_INIT_SPEC_CONST) \ + _(1362, ZEND_SEND_VAL_SPEC_CONST_CONST) \ + _(1365, ZEND_SEND_VAL_SPEC_CONST_UNUSED) \ + _(1367, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ + _(1370, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ _(1372, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ _(1375, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ - _(1377, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ - _(1380, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ - _(1412, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ - _(1413, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ - _(1418, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED) \ - _(1419, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK) \ - _(1432, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ - _(1433, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ - _(1438, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED) \ - _(1439, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK) \ - _(1452, ZEND_SEND_REF_SPEC_VAR_CONST) \ - _(1455, ZEND_SEND_REF_SPEC_VAR_UNUSED) \ - _(1462, ZEND_SEND_REF_SPEC_CV_CONST) \ - _(1465, ZEND_SEND_REF_SPEC_CV_UNUSED) \ - _(1467, ZEND_NEW_SPEC_CONST_UNUSED) \ - _(1469, ZEND_NEW_SPEC_VAR_UNUSED) \ - _(1470, ZEND_NEW_SPEC_UNUSED_UNUSED) \ - _(1472, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \ - _(1473, ZEND_FREE_SPEC_TMPVAR) \ - _(1474, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \ - _(1475, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ - _(1476, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ - _(1477, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \ - _(1478, ZEND_INIT_ARRAY_SPEC_CONST_CV) \ - _(1479, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \ - _(1480, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ - _(1481, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ - _(1482, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \ - _(1483, ZEND_INIT_ARRAY_SPEC_TMP_CV) \ - _(1484, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \ - _(1485, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ - _(1486, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ - _(1487, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ - _(1488, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ - _(1489, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ - _(1490, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ - _(1491, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ - _(1492, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ - _(1493, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ - _(1494, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ - _(1495, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ - _(1496, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ - _(1497, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \ - _(1498, ZEND_INIT_ARRAY_SPEC_CV_CV) \ - _(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \ - _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ - _(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ - _(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \ - _(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \ - _(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \ - _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ - _(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ - _(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \ - _(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \ - _(1509, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \ - _(1510, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ - _(1511, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ - _(1512, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \ - _(1513, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \ - _(1519, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \ - _(1520, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ - _(1521, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ - _(1522, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \ - _(1523, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \ - _(1524, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \ - _(1525, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1526, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ - _(1527, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1528, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ - _(1529, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1532, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \ - _(1533, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1534, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \ - _(1535, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ - _(1536, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ - _(1538, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \ - _(1549, ZEND_UNSET_DIM_SPEC_VAR_CONST) \ - _(1550, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ - _(1551, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ - _(1553, ZEND_UNSET_DIM_SPEC_VAR_CV) \ - _(1559, ZEND_UNSET_DIM_SPEC_CV_CONST) \ - _(1560, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ - _(1561, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ - _(1563, ZEND_UNSET_DIM_SPEC_CV_CV) \ - _(1574, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \ - _(1575, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ - _(1576, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ - _(1578, ZEND_UNSET_OBJ_SPEC_VAR_CV) \ - _(1579, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \ - _(1580, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ - _(1581, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ - _(1583, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \ - _(1584, ZEND_UNSET_OBJ_SPEC_CV_CONST) \ - _(1585, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ - _(1586, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ - _(1588, ZEND_UNSET_OBJ_SPEC_CV_CV) \ - _(1589, ZEND_FE_RESET_R_SPEC_CONST) \ - _(1590, ZEND_FE_RESET_R_SPEC_TMP) \ - _(1591, ZEND_FE_RESET_R_SPEC_VAR) \ - _(1593, ZEND_FE_RESET_R_SPEC_CV) \ - _(1594, ZEND_FE_FETCH_R_SPEC_VAR) \ - _(1595, ZEND_EXIT_SPEC) \ - _(1596, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ - _(1597, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1598, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1600, ZEND_FETCH_R_SPEC_CV_UNUSED) \ - _(1601, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ - _(1602, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1603, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1605, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ + _(1407, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ + _(1408, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ + _(1413, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED) \ + _(1414, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK) \ + _(1427, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ + _(1428, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ + _(1433, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED) \ + _(1434, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK) \ + _(1447, ZEND_SEND_REF_SPEC_VAR_CONST) \ + _(1450, ZEND_SEND_REF_SPEC_VAR_UNUSED) \ + _(1457, ZEND_SEND_REF_SPEC_CV_CONST) \ + _(1460, ZEND_SEND_REF_SPEC_CV_UNUSED) \ + _(1462, ZEND_NEW_SPEC_CONST_UNUSED) \ + _(1464, ZEND_NEW_SPEC_VAR_UNUSED) \ + _(1465, ZEND_NEW_SPEC_UNUSED_UNUSED) \ + _(1467, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \ + _(1468, ZEND_FREE_SPEC_TMPVAR) \ + _(1469, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \ + _(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ + _(1471, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ + _(1472, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \ + _(1473, ZEND_INIT_ARRAY_SPEC_CONST_CV) \ + _(1474, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \ + _(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ + _(1476, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ + _(1477, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \ + _(1478, ZEND_INIT_ARRAY_SPEC_TMP_CV) \ + _(1479, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \ + _(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ + _(1481, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ + _(1482, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ + _(1483, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ + _(1484, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ + _(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1486, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1487, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ + _(1488, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ + _(1489, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ + _(1490, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ + _(1491, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ + _(1492, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \ + _(1493, ZEND_INIT_ARRAY_SPEC_CV_CV) \ + _(1494, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \ + _(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ + _(1496, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ + _(1497, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \ + _(1498, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \ + _(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \ + _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ + _(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ + _(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \ + _(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \ + _(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \ + _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ + _(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ + _(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \ + _(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \ + _(1514, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \ + _(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ + _(1516, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ + _(1517, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \ + _(1518, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \ + _(1519, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \ + _(1520, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ + _(1522, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1523, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ + _(1524, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1527, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \ + _(1528, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1529, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \ + _(1530, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ + _(1531, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ + _(1533, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \ + _(1544, ZEND_UNSET_DIM_SPEC_VAR_CONST) \ + _(1545, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ + _(1546, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ + _(1548, ZEND_UNSET_DIM_SPEC_VAR_CV) \ + _(1554, ZEND_UNSET_DIM_SPEC_CV_CONST) \ + _(1555, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ + _(1556, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ + _(1558, ZEND_UNSET_DIM_SPEC_CV_CV) \ + _(1569, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \ + _(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ + _(1571, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ + _(1573, ZEND_UNSET_OBJ_SPEC_VAR_CV) \ + _(1574, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \ + _(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ + _(1576, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ + _(1578, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \ + _(1579, ZEND_UNSET_OBJ_SPEC_CV_CONST) \ + _(1580, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ + _(1581, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ + _(1583, ZEND_UNSET_OBJ_SPEC_CV_CV) \ + _(1584, ZEND_FE_RESET_R_SPEC_CONST) \ + _(1585, ZEND_FE_RESET_R_SPEC_TMP) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ _(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1608, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1610, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1611, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ - _(1612, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1613, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1615, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1621, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ - _(1622, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1623, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1625, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ - _(1626, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ - _(1627, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1628, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1630, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ + _(1616, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(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) \ + _(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) \ + _(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) \ _(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_TMPVAR_CONST) \ - _(1637, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1638, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1640, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1641, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ - _(1642, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1643, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1645, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ - _(1646, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ - _(1647, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1648, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1650, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ - _(1651, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ - _(1652, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1653, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1655, ZEND_FETCH_W_SPEC_CV_UNUSED) \ - _(1666, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ - _(1667, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1668, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1669, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ - _(1670, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ - _(1676, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ - _(1677, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1678, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1679, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ - _(1680, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ - _(1691, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ - _(1692, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1693, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1695, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ - _(1696, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ - _(1697, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1698, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1700, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ - _(1701, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ - _(1702, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1703, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1705, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ - _(1706, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ - _(1707, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1708, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1710, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ - _(1721, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ - _(1722, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1723, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1724, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ - _(1725, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ - _(1731, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ - _(1732, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1733, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1734, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ - _(1735, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ - _(1746, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ - _(1747, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1748, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1750, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ - _(1751, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ - _(1752, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1753, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1755, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ - _(1756, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ - _(1757, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1758, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1760, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ - _(1761, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ - _(1762, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1763, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1765, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ - _(1766, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ - _(1767, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1768, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1770, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ + _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ _(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1773, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1775, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1776, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ - _(1777, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1778, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1780, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1786, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ - _(1787, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1788, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1790, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ - _(1791, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ - _(1792, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1793, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1795, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ + _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(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) \ + _(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) \ + _(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) \ _(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_TMPVAR_CONST) \ - _(1802, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1803, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1805, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1806, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ - _(1807, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1808, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1810, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ - _(1811, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ - _(1812, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1813, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1815, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ - _(1816, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1817, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1818, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1820, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ - _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ - _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ - _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ - _(1830, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ - _(1831, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ - _(1832, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1833, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1834, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ - _(1841, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ - _(1842, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1843, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1844, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1845, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ - _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ - _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1848, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ - _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ - _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1853, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ - _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ - _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1858, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ - _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1863, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1865, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ - _(1866, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ - _(1867, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1868, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1870, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ - _(1871, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ - _(1872, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1873, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1875, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ - _(1886, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ - _(1887, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1888, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1890, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ - _(1896, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ - _(1897, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1898, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1900, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ - _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ - _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1913, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ - _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ - _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1918, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1920, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ - _(1921, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ - _(1922, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1923, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1925, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ - _(1926, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ - _(1927, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1928, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1930, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ + _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ _(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1933, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1935, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1936, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1937, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1938, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1946, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1947, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1948, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1950, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1951, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ - _(1952, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1958, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ - _(1959, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ - _(1962, ZEND_EXT_STMT_SPEC) \ - _(1963, ZEND_EXT_FCALL_BEGIN_SPEC) \ - _(1964, ZEND_EXT_FCALL_END_SPEC) \ - _(1965, ZEND_EXT_NOP_SPEC) \ - _(1966, ZEND_TICKS_SPEC) \ - _(1967, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ - _(1970, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ - _(1972, ZEND_CATCH_SPEC_CONST) \ - _(1973, ZEND_THROW_SPEC_CONST) \ - _(1974, ZEND_THROW_SPEC_TMPVAR) \ - _(1975, ZEND_THROW_SPEC_TMPVAR) \ - _(1977, ZEND_THROW_SPEC_CV) \ - _(1978, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ - _(1979, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1980, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1981, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ - _(1982, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ - _(1983, ZEND_CLONE_SPEC_CONST) \ - _(1984, ZEND_CLONE_SPEC_TMPVAR) \ - _(1985, ZEND_CLONE_SPEC_TMPVAR) \ - _(1986, ZEND_CLONE_SPEC_UNUSED) \ - _(1987, ZEND_CLONE_SPEC_CV) \ - _(1988, ZEND_RETURN_BY_REF_SPEC_CONST) \ - _(1989, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1990, ZEND_RETURN_BY_REF_SPEC_TMP) \ - _(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1992, ZEND_RETURN_BY_REF_SPEC_VAR) \ - _(1993, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1996, ZEND_RETURN_BY_REF_SPEC_CV) \ - _(1997, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1998, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ - _(1999, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2000, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2002, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ + _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(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) \ + _(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) \ + _(1969, ZEND_THROW_SPEC_TMPVAR) \ + _(1970, ZEND_THROW_SPEC_TMPVAR) \ + _(1972, ZEND_THROW_SPEC_CV) \ + _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ _(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_TMPVAR_CONST) \ - _(2009, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2010, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2012, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2013, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2014, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2015, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2017, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2018, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ - _(2019, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2020, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2022, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ - _(2023, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ - _(2024, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2025, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2026, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ - _(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ - _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ - _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ - _(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ - _(2038, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2039, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2040, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2041, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ - _(2042, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2048, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ - _(2049, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2050, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2052, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ - _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ - _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ + _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ _(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) \ - _(2063, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ - _(2064, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2065, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2073, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ - _(2074, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2075, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2077, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ - _(2078, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2084, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ - _(2085, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ - _(2088, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2094, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ - _(2095, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ - _(2138, ZEND_SEND_VAR_SPEC_VAR_CONST) \ - _(2141, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ - _(2148, ZEND_SEND_VAR_SPEC_CV_CONST) \ - _(2151, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ - _(2153, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ - _(2154, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2155, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2157, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ - _(2158, ZEND_SEND_ARRAY_SPEC) \ - _(2159, ZEND_SEND_USER_SPEC_CONST) \ - _(2160, ZEND_SEND_USER_SPEC_TMP) \ - _(2161, ZEND_SEND_USER_SPEC_VAR) \ - _(2163, ZEND_SEND_USER_SPEC_CV) \ - _(2164, ZEND_STRLEN_SPEC_CONST) \ - _(2165, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2166, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2168, ZEND_STRLEN_SPEC_CV) \ - _(2169, ZEND_DEFINED_SPEC_CONST) \ - _(2170, ZEND_TYPE_CHECK_SPEC_CONST) \ - _(2171, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2172, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2174, ZEND_TYPE_CHECK_SPEC_CV) \ - _(2175, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ - _(2176, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ - _(2177, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ - _(2178, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ - _(2179, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ - _(2180, ZEND_FE_RESET_RW_SPEC_CONST) \ - _(2181, ZEND_FE_RESET_RW_SPEC_TMP) \ - _(2182, ZEND_FE_RESET_RW_SPEC_VAR) \ - _(2184, ZEND_FE_RESET_RW_SPEC_CV) \ - _(2185, ZEND_FE_FETCH_RW_SPEC_VAR) \ - _(2186, ZEND_FE_FREE_SPEC_TMPVAR) \ - _(2187, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ - _(2188, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2189, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2191, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ - _(2192, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ - _(2193, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ - _(2194, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ - _(2195, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ - _(2196, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2197, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2198, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ - _(2199, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ - _(2200, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2201, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ - _(2213, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2214, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2216, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ - _(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2218, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2219, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2221, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ - _(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ - _(2223, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2224, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2226, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ - _(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ - _(2238, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2239, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2241, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ - _(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2243, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2244, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2246, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ - _(2247, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ - _(2248, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2249, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2251, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ - _(2252, ZEND_ECHO_SPEC_CONST) \ - _(2253, ZEND_ECHO_SPEC_TMPVAR) \ - _(2254, ZEND_ECHO_SPEC_TMPVAR) \ - _(2256, ZEND_ECHO_SPEC_CV) \ + _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(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) \ + _(2189, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ + _(2190, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2191, ZEND_DO_UCALL_SPEC_OBSERVER) \ + _(2192, ZEND_DO_UCALL_SPEC_OBSERVER) \ + _(2193, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ + _(2194, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ + _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ + _(2207, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2211, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ + _(2212, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2216, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ + _(2217, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2218, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2221, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ + _(2232, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2233, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2236, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ + _(2237, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2241, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ + _(2242, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2243, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2246, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ + _(2247, ZEND_ECHO_SPEC_CONST) \ + _(2248, ZEND_ECHO_SPEC_TMPVAR) \ + _(2249, ZEND_ECHO_SPEC_TMPVAR) \ + _(2251, ZEND_ECHO_SPEC_CV) \ + _(2258, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2260, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ _(2263, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ _(2265, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ _(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2268, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2270, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2271, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2278, ZEND_INSTANCEOF_SPEC_CV_CONST) \ - _(2280, ZEND_INSTANCEOF_SPEC_CV_VAR) \ - _(2281, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ - _(2283, ZEND_GENERATOR_CREATE_SPEC) \ - _(2286, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ - _(2288, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ - _(2289, ZEND_DECLARE_FUNCTION_SPEC) \ - _(2290, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ - _(2291, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ - _(2292, ZEND_DECLARE_CLASS_SPEC_CONST) \ - _(2293, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ - _(2294, ZEND_DECLARE_ANON_CLASS_SPEC) \ - _(2295, ZEND_ADD_ARRAY_UNPACK_SPEC) \ - _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ - _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2273, ZEND_INSTANCEOF_SPEC_CV_CONST) \ + _(2275, ZEND_INSTANCEOF_SPEC_CV_VAR) \ + _(2276, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ + _(2278, ZEND_GENERATOR_CREATE_SPEC) \ + _(2281, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ + _(2283, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ + _(2284, ZEND_DECLARE_FUNCTION_SPEC) \ + _(2285, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ + _(2286, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ + _(2287, ZEND_DECLARE_CLASS_SPEC_CONST) \ + _(2288, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ + _(2289, ZEND_DECLARE_ANON_CLASS_SPEC) \ + _(2290, ZEND_ADD_ARRAY_UNPACK_SPEC) \ + _(2291, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ + _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ + _(2295, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2305, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ - _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ - _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ - _(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ - _(2317, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2318, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2320, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ - _(2321, ZEND_HANDLE_EXCEPTION_SPEC) \ - _(2322, ZEND_USER_OPCODE_SPEC) \ - _(2323, ZEND_ASSERT_CHECK_SPEC) \ - _(2324, ZEND_JMP_SET_SPEC_CONST) \ - _(2325, ZEND_JMP_SET_SPEC_TMP) \ - _(2326, ZEND_JMP_SET_SPEC_VAR) \ - _(2328, ZEND_JMP_SET_SPEC_CV) \ - _(2329, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ - _(2330, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ - _(2331, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ - _(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ - _(2333, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2334, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2336, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ - _(2337, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ - _(2339, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2340, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2341, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ - _(2342, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ - _(2343, ZEND_CALL_TRAMPOLINE_SPEC) \ - _(2344, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ - _(2345, ZEND_DISCARD_EXCEPTION_SPEC) \ - _(2346, ZEND_YIELD_SPEC_CONST_CONST) \ - _(2347, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2348, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2349, ZEND_YIELD_SPEC_CONST_UNUSED) \ - _(2350, ZEND_YIELD_SPEC_CONST_CV) \ - _(2351, ZEND_YIELD_SPEC_TMP_CONST) \ - _(2352, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2353, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2354, ZEND_YIELD_SPEC_TMP_UNUSED) \ - _(2355, ZEND_YIELD_SPEC_TMP_CV) \ - _(2356, ZEND_YIELD_SPEC_VAR_CONST) \ - _(2357, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2358, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2359, ZEND_YIELD_SPEC_VAR_UNUSED) \ - _(2360, ZEND_YIELD_SPEC_VAR_CV) \ - _(2361, ZEND_YIELD_SPEC_UNUSED_CONST) \ - _(2362, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2363, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2364, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ - _(2365, ZEND_YIELD_SPEC_UNUSED_CV) \ - _(2366, ZEND_YIELD_SPEC_CV_CONST) \ - _(2367, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2368, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2369, ZEND_YIELD_SPEC_CV_UNUSED) \ - _(2370, ZEND_YIELD_SPEC_CV_CV) \ - _(2371, ZEND_GENERATOR_RETURN_SPEC_CONST) \ - _(2372, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2373, ZEND_GENERATOR_RETURN_SPEC_TMP) \ - _(2374, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2375, ZEND_GENERATOR_RETURN_SPEC_VAR) \ - _(2376, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2379, ZEND_GENERATOR_RETURN_SPEC_CV) \ - _(2380, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2381, ZEND_FAST_CALL_SPEC) \ - _(2382, ZEND_FAST_RET_SPEC) \ - _(2383, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ - _(2384, ZEND_SEND_UNPACK_SPEC) \ - _(2385, ZEND_YIELD_FROM_SPEC_CONST) \ - _(2386, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2387, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2389, ZEND_YIELD_FROM_SPEC_CV) \ - _(2390, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ - _(2391, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ - _(2392, ZEND_COALESCE_SPEC_CONST) \ - _(2393, ZEND_COALESCE_SPEC_TMP) \ - _(2394, ZEND_COALESCE_SPEC_VAR) \ - _(2396, ZEND_COALESCE_SPEC_CV) \ - _(2397, ZEND_SPACESHIP_SPEC_CONST_CONST) \ - _(2398, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2399, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2401, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ + _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ + _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ + _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ + _(2316, ZEND_HANDLE_EXCEPTION_SPEC) \ + _(2317, ZEND_USER_OPCODE_SPEC) \ + _(2318, ZEND_ASSERT_CHECK_SPEC) \ + _(2319, ZEND_JMP_SET_SPEC_CONST) \ + _(2320, ZEND_JMP_SET_SPEC_TMP) \ + _(2321, ZEND_JMP_SET_SPEC_VAR) \ + _(2323, ZEND_JMP_SET_SPEC_CV) \ + _(2324, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ + _(2325, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ + _(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ + _(2327, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2328, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ + _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ + _(2331, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ + _(2332, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2334, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ + _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ + _(2336, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ + _(2337, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ + _(2338, ZEND_CALL_TRAMPOLINE_SPEC) \ + _(2339, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ + _(2340, ZEND_DISCARD_EXCEPTION_SPEC) \ + _(2341, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2342, ZEND_YIELD_SPEC_CONST_TMPVAR) \ + _(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \ + _(2344, ZEND_YIELD_SPEC_CONST_UNUSED) \ + _(2345, ZEND_YIELD_SPEC_CONST_CV) \ + _(2346, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2347, ZEND_YIELD_SPEC_TMP_TMPVAR) \ + _(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \ + _(2349, ZEND_YIELD_SPEC_TMP_UNUSED) \ + _(2350, ZEND_YIELD_SPEC_TMP_CV) \ + _(2351, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2352, ZEND_YIELD_SPEC_VAR_TMPVAR) \ + _(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \ + _(2354, ZEND_YIELD_SPEC_VAR_UNUSED) \ + _(2355, ZEND_YIELD_SPEC_VAR_CV) \ + _(2356, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2357, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ + _(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ + _(2359, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ + _(2360, ZEND_YIELD_SPEC_UNUSED_CV) \ + _(2361, ZEND_YIELD_SPEC_CV_CONST) \ + _(2362, ZEND_YIELD_SPEC_CV_TMPVAR) \ + _(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \ + _(2364, ZEND_YIELD_SPEC_CV_UNUSED) \ + _(2365, ZEND_YIELD_SPEC_CV_CV) \ + _(2366, ZEND_GENERATOR_RETURN_SPEC_CONST) \ + _(2367, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2368, ZEND_GENERATOR_RETURN_SPEC_TMP) \ + _(2369, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2370, ZEND_GENERATOR_RETURN_SPEC_VAR) \ + _(2371, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2374, ZEND_GENERATOR_RETURN_SPEC_CV) \ + _(2375, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2376, ZEND_FAST_CALL_SPEC) \ + _(2377, ZEND_FAST_RET_SPEC) \ + _(2378, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ + _(2379, ZEND_SEND_UNPACK_SPEC) \ + _(2380, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2381, ZEND_YIELD_FROM_SPEC_TMPVAR) \ + _(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \ + _(2384, ZEND_YIELD_FROM_SPEC_CV) \ + _(2385, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ + _(2386, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ + _(2387, ZEND_COALESCE_SPEC_CONST) \ + _(2388, ZEND_COALESCE_SPEC_TMP) \ + _(2389, ZEND_COALESCE_SPEC_VAR) \ + _(2391, ZEND_COALESCE_SPEC_CV) \ + _(2392, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2393, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ + _(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ + _(2396, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2397, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2398, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ + _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ + _(2401, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ _(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2406, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ - _(2408, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2409, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2411, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2417, ZEND_SPACESHIP_SPEC_CV_CONST) \ - _(2418, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2419, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2421, ZEND_SPACESHIP_SPEC_CV_CV) \ - _(2422, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ - _(2423, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ - _(2426, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ - _(2428, ZEND_FETCH_STATIC_PROP_R_SPEC) \ - _(2429, ZEND_FETCH_STATIC_PROP_W_SPEC) \ - _(2430, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ - _(2431, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ - _(2432, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ - _(2433, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ - _(2434, ZEND_UNSET_STATIC_PROP_SPEC) \ - _(2435, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ - _(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ - _(2438, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ - _(2439, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ - _(2441, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ - _(2442, ZEND_BIND_STATIC_SPEC_CV_UNUSED) \ - _(2443, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ - _(2444, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ - _(2447, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(2449, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ - _(2450, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ - _(2451, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2452, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2454, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2455, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ - _(2456, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2457, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2459, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2460, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ - _(2461, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ - _(2462, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ - _(2464, ZEND_IN_ARRAY_SPEC_CV_CONST) \ - _(2465, ZEND_COUNT_SPEC_CONST_UNUSED) \ - _(2466, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2467, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2469, ZEND_COUNT_SPEC_CV_UNUSED) \ - _(2470, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ - _(2471, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2472, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2473, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ - _(2474, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ - _(2475, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ - _(2476, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ - _(2477, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ - _(2478, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ - _(2480, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ - _(2481, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ - _(2482, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2483, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2485, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2412, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2413, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ + _(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ + _(2416, ZEND_SPACESHIP_SPEC_CV_CV) \ + _(2417, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ + _(2418, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ + _(2421, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ + _(2423, ZEND_FETCH_STATIC_PROP_R_SPEC) \ + _(2424, ZEND_FETCH_STATIC_PROP_W_SPEC) \ + _(2425, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ + _(2426, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ + _(2427, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ + _(2428, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ + _(2429, ZEND_UNSET_STATIC_PROP_SPEC) \ + _(2430, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ + _(2431, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2434, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2436, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ + _(2437, ZEND_BIND_STATIC_SPEC_CV_UNUSED) \ + _(2438, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ + _(2439, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ + _(2442, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(2444, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ + _(2445, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2446, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2447, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2449, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2450, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2451, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2452, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2454, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2455, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ + _(2456, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ + _(2457, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ + _(2459, ZEND_IN_ARRAY_SPEC_CV_CONST) \ + _(2460, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2461, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ + _(2462, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ + _(2464, ZEND_COUNT_SPEC_CV_UNUSED) \ + _(2465, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2466, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ + _(2467, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ + _(2468, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ + _(2469, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ + _(2470, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ + _(2471, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ + _(2472, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ + _(2473, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ + _(2475, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ + _(2476, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2477, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ + _(2478, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ + _(2480, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2481, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2482, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ + _(2483, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ + _(2485, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ _(2486, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ _(2487, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2488, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2490, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2491, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ - _(2492, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2493, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2495, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ - _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2505, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ - _(2506, ZEND_MATCH_SPEC_CONST_CONST) \ - _(2507, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2508, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2510, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2516, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ - _(2517, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ - _(2518, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ - _(2520, ZEND_CASE_STRICT_SPEC_TMP_CV) \ - _(2521, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ - _(2522, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ - _(2523, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ - _(2525, ZEND_CASE_STRICT_SPEC_VAR_CV) \ - _(2536, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ - _(2537, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2538, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2540, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2541, ZEND_JMP_NULL_SPEC_CONST) \ - _(2542, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2543, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2545, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2546, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ - _(2547, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ - _(2548, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ - _(2549, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2550, ZEND_RECV_NOTYPE_SPEC) \ - _(2551, ZEND_JMP_FORWARD_SPEC) \ + _(2496, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ + _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ + _(2500, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ + _(2501, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2502, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2503, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2505, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2511, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ + _(2512, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ + _(2513, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ + _(2515, ZEND_CASE_STRICT_SPEC_TMP_CV) \ + _(2516, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ + _(2517, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ + _(2518, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ + _(2520, ZEND_CASE_STRICT_SPEC_VAR_CV) \ + _(2531, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2532, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2533, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2535, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2536, ZEND_JMP_NULL_SPEC_CONST) \ + _(2537, ZEND_JMP_NULL_SPEC_TMP) \ + _(2538, ZEND_JMP_NULL_SPEC_VAR) \ + _(2540, ZEND_JMP_NULL_SPEC_CV) \ + _(2541, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ + _(2542, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ + _(2543, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ + _(2544, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ + _(2545, ZEND_RECV_NOTYPE_SPEC) \ + _(2546, ZEND_JMP_FORWARD_SPEC) \ + _(2552, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2553, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2554, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2556, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2557, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2558, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2559, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2561, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2562, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2563, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2564, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2566, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2567, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2568, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2569, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2571, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2577, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2578, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2579, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2581, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2582, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(2583, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2584, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2586, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2587, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2588, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2589, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2591, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2592, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2593, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2594, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2596, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2602, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2603, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2604, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2606, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2607, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2608, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2609, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2611, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2612, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2613, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2614, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2628, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2629, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2631, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2617, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2618, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2619, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2621, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2623, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2624, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2626, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2627, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2628, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2629, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2631, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2632, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2633, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2634, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2636, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2637, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2638, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2639, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2653, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2654, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2656, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2642, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2648, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2649, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2651, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2652, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2653, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2654, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2656, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2657, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(2658, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2659, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2661, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2663, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2664, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2678, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2679, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2681, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2667, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2668, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2669, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2671, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2673, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2674, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2676, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2677, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2678, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2679, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2681, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2682, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2683, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2684, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2686, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2688, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2689, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2691, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2692, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2693, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2694, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2696, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2702, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2703, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2704, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2706, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2707, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2708, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2709, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2711, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2713, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2714, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2716, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2717, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2718, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2719, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2721, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2727, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2728, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2729, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2731, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2732, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(2733, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2734, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2736, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2737, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2738, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2739, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2742, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2743, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2744, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2746, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2752, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2753, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2754, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2756, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2757, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2758, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2759, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2761, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2762, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2763, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2764, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2792, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2793, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2794, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2795, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2797, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2798, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2867, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2868, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2869, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2870, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2871, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2872, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2873, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2942, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2943, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2944, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2945, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2946, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2947, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2948, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3017, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3018, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3019, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3020, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3021, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3022, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3023, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3077, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3081, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3082, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3086, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3091, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3092, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3093, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3099, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3100, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3106, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3107, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3121, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3122, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_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) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3166, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3167, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3168, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3174, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3175, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3176, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3181, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3182, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3183, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3241, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3242, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3243, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3256, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3257, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3258, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3316, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3317, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3318, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3387, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3388, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3389, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3390, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3391, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3392, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3393, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3394, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3395, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3396, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3397, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3398, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3399, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3400, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3401, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3403, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3404, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3405, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3406, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3408, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3409, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3410, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3411, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3413, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3415, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3416, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3418, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(2767, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2768, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2769, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2771, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2787, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2788, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2789, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2790, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2791, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2792, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2793, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2794, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2795, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2801, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2802, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2803, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2816, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2837, 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) \ + _(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) \ + _(2862, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2863, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2864, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2865, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2866, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2867, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2868, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2869, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2870, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2876, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2877, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2878, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2891, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2912, 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) \ + _(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) \ + _(2937, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2938, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2939, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2940, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2941, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2942, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2943, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2944, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2945, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2951, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2952, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2953, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2966, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2987, 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) \ + _(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) \ + _(3012, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3013, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3014, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3015, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3016, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3017, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3018, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3019, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3020, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3026, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3027, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3028, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3041, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3062, 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) \ + _(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_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3076, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3077, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3081, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3085, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3086, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3087, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3088, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3089, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3096, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3097, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3098, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3099, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3100, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3101, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3111, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3112, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3113, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3147, 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) \ + _(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) \ + _(3160, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3161, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3162, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3163, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3164, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3171, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3172, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3173, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3174, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3175, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3176, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3222, 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) \ + _(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) \ + _(3235, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3236, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3237, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3238, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3239, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3246, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3247, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3248, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3297, 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) \ + _(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) \ + _(3310, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3311, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3314, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3321, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3322, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3323, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3372, 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) \ + _(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_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3383, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3384, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3385, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3386, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3387, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3388, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3389, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3390, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3391, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3392, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3393, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3394, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3395, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3396, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3398, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3399, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3400, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3401, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3403, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3404, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3405, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3406, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3408, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3410, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3411, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3413, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3414, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3415, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3416, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3418, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3419, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(3420, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3421, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3423, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3424, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3425, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3426, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3428, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3434, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3435, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3438, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3441, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3443, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3446, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3448, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3449, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3450, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3451, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3452, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3452+1, ZEND_NULL) + _(3429, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3430, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3431, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3433, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3436, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3438, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3441, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3443, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3444, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3445, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3446, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3447, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3447+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 7f88f9e84b690..c3f5e9d427aa4 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -68,7 +68,7 @@ static const char *zend_vm_opcodes_names[203] = { "ZEND_JMP", "ZEND_JMPZ", "ZEND_JMPNZ", - "ZEND_JMPZNZ", + NULL, "ZEND_JMPZ_EX", "ZEND_JMPNZ_EX", "ZEND_CASE", @@ -274,7 +274,7 @@ static uint32_t zend_vm_opcodes_flags[203] = { 0x00000020, 0x00002007, 0x00002007, - 0x03002007, + 0x00000000, 0x00002007, 0x00002007, 0x00000705, @@ -427,7 +427,7 @@ static uint32_t zend_vm_opcodes_flags[203] = { 0x0300030b, 0x00000301, 0x0000010b, - 0x0000200b, + 0x00002003, 0x00000101, 0x00000101, 0x00000101, @@ -449,7 +449,8 @@ ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode) { ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) { zend_uchar opcode; for (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) { - if (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) { + const char *opcode_name = zend_vm_opcodes_names[opcode]; + if (opcode_name && strncmp(opcode_name, name, length) == 0) { return opcode; } } diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 83e409a9233c9..165e914e1cd53 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -128,7 +128,6 @@ END_EXTERN_C() #define ZEND_JMP 42 #define ZEND_JMPZ 43 #define ZEND_JMPNZ 44 -#define ZEND_JMPZNZ 45 #define ZEND_JMPZ_EX 46 #define ZEND_JMPNZ_EX 47 #define ZEND_CASE 48 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 73802757b5e43..2489cd40072e3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,22 +27,11 @@ schedules: - master jobs: - - template: azure/job.yml - parameters: - configurationName: DEBUG_NTS - configurationParameters: '--enable-debug --disable-zts' - - template: azure/job.yml - parameters: - configurationName: RELEASE_ZTS - configurationParameters: '--disable-debug --enable-zts' - - template: azure/i386/job.yml - parameters: - configurationName: I386_DEBUG_ZTS - configurationParameters: '--enable-debug --enable-zts' - - template: azure/macos/job.yml - parameters: - configurationName: MACOS_DEBUG_NTS - configurationParameters: '--enable-debug --disable-zts' + # Azure pipelines don't work atm + # - template: azure/i386/job.yml + # parameters: + # configurationName: I386_DEBUG_ZTS + # configurationParameters: '--enable-debug --enable-zts' - ${{ if eq(variables['Build.Reason'], 'Schedule') }}: - template: azure/job.yml parameters: diff --git a/build/Makefile.global b/build/Makefile.global index ca7f2115f3e80..3c44a52693ae2 100644 --- a/build/Makefile.global +++ b/build/Makefile.global @@ -149,6 +149,9 @@ prof-use: if test ! -z "$(PHP)"; then \ echo Parse $< to generate $@;\ $(PHP) $(top_srcdir)/build/gen_stub.php $<; \ + elif test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \ + echo Parse $< to generate $@;\ + $(PHP_EXECUTABLE) $(top_srcdir)/build/gen_stub.php $<; \ fi; \ fi; diff --git a/build/gen_stub.php b/build/gen_stub.php index 8708bf8ff7d06..6856b5610e92c 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1406,6 +1406,8 @@ class PropertyInfo public $defaultValueString; /** @var bool */ public $isDocReadonly; + /** @var string|null */ + public $link; public function __construct( PropertyName $name, @@ -1414,7 +1416,8 @@ public function __construct( ?Type $phpDocType, ?Expr $defaultValue, ?string $defaultValueString, - bool $isDocReadonly + bool $isDocReadonly, + ?string $link ) { $this->name = $name; $this->flags = $flags; @@ -1423,6 +1426,7 @@ public function __construct( $this->defaultValue = $defaultValue; $this->defaultValueString = $defaultValueString; $this->isDocReadonly = $isDocReadonly; + $this->link = $link; } public function discardInfoForOldPhpVersions(): void { @@ -1548,9 +1552,13 @@ public function getFieldSynopsisElement(DOMDocument $doc): DOMElement $fieldsynopsisElement->appendChild(new DOMText("\n ")); $fieldsynopsisElement->appendChild($this->getFieldSynopsisType()->getTypeForDoc($doc)); - $className = str_replace("\\", "-", $this->name->class->toLowerString()); + $className = str_replace(["\\", "_"], ["-", "-"], $this->name->class->toLowerString()); $varnameElement = $doc->createElement("varname", $this->name->property); - $varnameElement->setAttribute("linkend", "$className.props." . strtolower($this->name->property)); + if ($this->link) { + $varnameElement->setAttribute("linkend", $this->link); + } else { + $varnameElement->setAttribute("linkend", "$className.props." . strtolower(str_replace("_", "-", $this->name->property))); + } $fieldsynopsisElement->appendChild(new DOMText("\n ")); $fieldsynopsisElement->appendChild($varnameElement); @@ -1566,14 +1574,14 @@ public function getFieldSynopsisElement(DOMDocument $doc): DOMElement } private function getFieldSynopsisType(): Type { - if ($this->type) { - return $this->type; - } - if ($this->phpDocType) { return $this->phpDocType; } + if ($this->type) { + return $this->type; + } + throw new Exception("A property must have a type"); } @@ -1748,7 +1756,7 @@ function (Name $item) { } if ($this->alias) { - $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "_", $this->alias) . "\", class_entry);\n"; + $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "\\\\", $this->alias) . "\", class_entry);\n"; } foreach ($this->enumCaseInfos as $enumCase) { @@ -2013,11 +2021,11 @@ private static function createOoElement( } public static function getClassSynopsisFilename(Name $name): string { - return strtolower(implode('-', $name->parts)); + return strtolower(str_replace("_", "-", implode('-', $name->parts))); } public static function getClassSynopsisReference(Name $name): string { - return "class." . strtolower(implode('-', $name->parts)); + return "class." . self::getClassSynopsisFilename($name); } /** @@ -2027,10 +2035,6 @@ public static function getClassSynopsisReference(Name $name): string { */ private function collectInheritedMembers(array &$parentsWithInheritedProperties, array &$parentsWithInheritedMethods, array $classMap): void { - if ($this->type !== "class") { - return; - } - foreach ($this->extends as $parent) { $parentInfo = $classMap[$parent->toString()] ?? null; if (!$parentInfo) { @@ -2041,7 +2045,7 @@ private function collectInheritedMembers(array &$parentsWithInheritedProperties, $parentsWithInheritedProperties[$parent->toString()] = $parent; } - if (!empty($parentInfo->funcInfos) && !isset($parentsWithInheritedMethods[$parent->toString()])) { + if (!isset($parentsWithInheritedMethods[$parent->toString()]) && $parentInfo->hasMethods()) { $parentsWithInheritedMethods[$parent->toString()] = $parent; } @@ -2388,6 +2392,7 @@ function parseProperty( ): PropertyInfo { $phpDocType = null; $isDocReadonly = false; + $link = null; if ($comment) { $tags = parseDocComment($comment); @@ -2396,6 +2401,8 @@ function parseProperty( $phpDocType = $tag->getType(); } elseif ($tag->name === 'readonly') { $isDocReadonly = true; + } elseif ($tag->name === 'link') { + $link = $tag->value; } } } @@ -2423,7 +2430,8 @@ function parseProperty( $phpDocType ? Type::fromString($phpDocType) : null, $property->default, $property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null, - $isDocReadonly + $isDocReadonly, + $link ); } @@ -2998,12 +3006,14 @@ function replaceClassSynopses(string $targetDirectory, array $classMap): array $replacedXml = preg_replace( [ "/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/", + "//i", "//i", "//i", "//i", ], [ "&$1", + "", "", "", "", @@ -3277,7 +3287,7 @@ function initPhpParser() { } $isInitialized = true; - $version = "4.13.0"; + $version = "4.13.2"; $phpParserDir = __DIR__ . "/PHP-Parser-$version"; if (!is_dir($phpParserDir)) { installPhpParser($version, $phpParserDir); diff --git a/build/php.m4 b/build/php.m4 index 01b8250598191..94e824f6cc263 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -2030,7 +2030,7 @@ ifelse([$3],[],,[else $3]) ]) dnl -dnl PHP_SETUP_LIBXML(shared-add [, action-found [, action-not-found]]) +dnl PHP_SETUP_LIBXML(shared-add [, action-found]) dnl dnl Common setup macro for libxml. dnl diff --git a/build/php_cxx_compile_stdcxx.m4 b/build/php_cxx_compile_stdcxx.m4 index 3c8d598e63a1d..f8e97fce708f0 100644 --- a/build/php_cxx_compile_stdcxx.m4 +++ b/build/php_cxx_compile_stdcxx.m4 @@ -6,7 +6,7 @@ dnl PHP_CXX_COMPILE_STDCXX(version, mandatory|optional, var_name_to_put_switch_i dnl dnl ARGUMENTS dnl -dnl first arg - version as 11, 14 or 17 +dnl first arg - version as 11, 14, 17 or 20 dnl second arg - if mandatory, the configure will fail when no features found. dnl Optional will make configure silently continue dnl third arg - a variable name where the corresponding switch would be put. If @@ -26,6 +26,7 @@ AC_DEFUN([PHP_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to PHP_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [ax_cxx_compile_cxx$1_required=true], [$2], [mandatory], [ax_cxx_compile_cxx$1_required=true], @@ -88,19 +89,21 @@ dnl # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. + dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) - dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], @@ -108,12 +111,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +dnl Test body for checking C++17 support + m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ @@ -909,3 +924,33 @@ namespace cxx17 #endif // __cplusplus < 201703L ]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L + +]]) diff --git a/build/pkg.m4 b/build/pkg.m4 index f9075e56c87af..5bf9ba16505b7 100644 --- a/build/pkg.m4 +++ b/build/pkg.m4 @@ -16,8 +16,8 @@ dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a diff --git a/build/shtool b/build/shtool index fc6ae1e6efbbb..ea1119ac1ebea 100755 --- a/build/shtool +++ b/build/shtool @@ -23,7 +23,7 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ## USA, or contact Ralf S. Engelschall . ## ## NOTICE: Given that you include this file verbatim into your own diff --git a/configure.ac b/configure.ac index 6ad00bc22217c..c2886439afa6b 100644 --- a/configure.ac +++ b/configure.ac @@ -260,7 +260,7 @@ AC_MSG_CHECKING([whether we are using musl libc]) if command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl then AC_MSG_RESULT(yes) - CPPFLAGS="$CPPFLAGS -D__MUSL__" + AC_DEFINE([__MUSL__], [1], [Define when using musl libc]) else AC_MSG_RESULT(no) fi @@ -1209,6 +1209,7 @@ AS_CASE([$host_cpu], [arm*], [fiber_cpu="arm32"], [ppc64*|powerpc64*], [fiber_cpu="ppc64"], [ppc*|powerpc*], [fiber_cpu="ppc32"], + [riscv64*], [fiber_cpu="riscv64"], [s390x*], [fiber_cpu="s390x"], [mips64*], [fiber_cpu="mips64"], [mips*], [fiber_cpu="mips32"], @@ -1228,6 +1229,7 @@ AS_CASE([$fiber_cpu], [arm32], [fiber_asm_file_prefix="arm_aapcs"], [ppc64], [fiber_asm_file_prefix="ppc64_sysv"], [ppc32], [fiber_asm_file_prefix="ppc32_sysv"], + [riscv64], [fiber_asm_file_prefix="riscv64_sysv"], [s390x], [fiber_asm_file_prefix="s390x_sysv"], [mips64], [fiber_asm_file_prefix="mips64_n64"], [mips32], [fiber_asm_file_prefix="mips32_o32"], diff --git a/ext/bcmath/tests/bcadd.phpt b/ext/bcmath/tests/bcadd.phpt index b24ce8dbd7927..fa4be8acbe1ae 100644 --- a/ext/bcmath/tests/bcadd.phpt +++ b/ext/bcmath/tests/bcadd.phpt @@ -8,9 +8,13 @@ bcmath.scale=0 --EXPECT-- 3 4.0000 +-6.0000 +-4.0000 8728932003911564969352217864684.00 diff --git a/ext/bcmath/tests/bcadd_variation001.phpt b/ext/bcmath/tests/bcadd_variation001.phpt index 447958b4a2f0f..d6bd89b52231d 100644 --- a/ext/bcmath/tests/bcadd_variation001.phpt +++ b/ext/bcmath/tests/bcadd_variation001.phpt @@ -7,10 +7,16 @@ bcmath.scale=5 --FILE-- --EXPECT-- 6.50 +6.50 +-5.1 -5.1 3.03000 +-11.57000 diff --git a/ext/bcmath/tests/bccomp_variation002.phpt b/ext/bcmath/tests/bccomp_variation002.phpt index ae7ba7fafe819..eb9655083ca3f 100644 --- a/ext/bcmath/tests/bccomp_variation002.phpt +++ b/ext/bcmath/tests/bccomp_variation002.phpt @@ -8,9 +8,15 @@ bcmath.scale=0 --EXPECT-- 0 -1 1 +-1 +1 +1 diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index f3405b5cb6a6b..d09db6a13bc82 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -72,7 +72,7 @@ zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_entry, * zend_object* php_com_object_new(zend_class_entry *ce); zend_object* php_com_object_clone(zend_object *object); void php_com_object_free_storage(zend_object *object); -zend_object_handlers php_com_object_handlers; +extern zend_object_handlers php_com_object_handlers; void php_com_object_enable_event_sink(php_com_dotnet_object *obj, bool enable); /* com_saproxy.c */ diff --git a/ext/curl/tests/bug76675.phpt b/ext/curl/tests/bug76675.phpt index 8f31aa5eed60f..02cdfe4d5710f 100644 --- a/ext/curl/tests/bug76675.phpt +++ b/ext/curl/tests/bug76675.phpt @@ -2,6 +2,8 @@ Bug #76675 (Segfault with H2 server push write/writeheader handlers) --EXTENSIONS-- curl +--XFAIL-- +http2.golang.org/serverpush is gone --SKIPIF-- --FILE-- --FILE-- ptr = *(void**)ptr; } else if (old_type->kind == ZEND_FFI_TYPE_ARRAY - && type->kind == ZEND_FFI_TYPE_POINTER) { - cdata->ptr = &cdata->ptr_holder; - cdata->ptr_holder = old_cdata->ptr; + && type->kind == ZEND_FFI_TYPE_POINTER + && zend_ffi_is_compatible_type(ZEND_FFI_TYPE(old_type->array.type), ZEND_FFI_TYPE(type->pointer.type))) { cdata->ptr = &cdata->ptr_holder; + cdata->ptr = &cdata->ptr_holder; + cdata->ptr_holder = old_cdata->ptr; + } else if (old_type->kind == ZEND_FFI_TYPE_POINTER + && type->kind == ZEND_FFI_TYPE_ARRAY + && zend_ffi_is_compatible_type(ZEND_FFI_TYPE(old_type->pointer.type), ZEND_FFI_TYPE(type->array.type))) { + cdata->ptr = old_cdata->ptr_holder; } else if (type->size > old_type->size) { zend_object_release(&cdata->std); zend_throw_error(zend_ffi_exception_ce, "attempt to cast to larger type"); diff --git a/ext/ffi/tests/gh7867.phpt b/ext/ffi/tests/gh7867.phpt new file mode 100644 index 0000000000000..7728d15b1c616 --- /dev/null +++ b/ext/ffi/tests/gh7867.phpt @@ -0,0 +1,75 @@ +--TEST-- +GH-7867 (FFI::cast() from pointer to array is broken) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +cast from start +object(FFI\CData:char*)#%d (1) { + [0]=> + string(1) "a" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" +} + +cast with offset +object(FFI\CData:char*)#%d (1) { + [0]=> + string(1) "e" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "e" + [1]=> + string(1) "f" + [2]=> + string(1) "g" + [3]=> + string(1) "h" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "e" + [1]=> + string(1) "f" + [2]=> + string(1) "g" + [3]=> + string(1) "h" +} diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 108e8e3259c78..91bf929a9d00e 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -444,10 +444,10 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ switch (is_numeric_string(num, p - num, &lval, &dval, 0)) { case IS_LONG: - zval_ptr_dtor(value); if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) { goto error; } + zval_ptr_dtor(value); ZVAL_DOUBLE(value, (double)lval); break; case IS_DOUBLE: diff --git a/ext/filter/tests/bug81708.phpt b/ext/filter/tests/bug81708.phpt new file mode 100644 index 0000000000000..5f99ae4afd19a --- /dev/null +++ b/ext/filter/tests/bug81708.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #81708 (UAF due to php_filter_float() failing for ints) +--EXTENSIONS-- +filter +--INI-- +opcache.enable_cli=0 +--FILE-- + ['min_range' => -1, 'max_range' => 1]] +); +var_dump($input); +?> +--EXPECT-- +string(3) "+11" diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index b8a1fc3083b06..655eee77b9063 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -336,6 +336,11 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) break; } + /* enable the interlace transform if supported */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + (void)png_set_interlace_handling(png_ptr); +#endif + png_read_update_info(png_ptr, info_ptr); /* allocate space for the PNG image data */ diff --git a/ext/hash/hash.stub.php b/ext/hash/hash.stub.php index ce439d620fdda..6795ecaa87c2f 100644 --- a/ext/hash/hash.stub.php +++ b/ext/hash/hash.stub.php @@ -12,7 +12,7 @@ function hash_file(string $algo, string $filename, bool $binary = false, array $ function hash_hmac(string $algo, string $data, string $key, bool $binary = false): string {} /** @refcount 1 */ -function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false): string|false {} +function hash_hmac_file(string $algo, string $filename, string $key, bool $binary = false): string|false {} /** @refcount 1 */ function hash_init(string $algo, int $flags = 0, string $key = "", array $options = []): HashContext {} diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index 5a8758bfa2d44..8ce7ba03aa519 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 715957cf1785912eed75ce92c2a2708defe1ebd7 */ + * Stub hash: 8b5131fd7bd88d1ec0211bcfcb5a4854418aa3c8 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) @@ -24,7 +24,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_hmac_file, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() diff --git a/ext/hash/tests/hash_hmac_file_error.phpt b/ext/hash/tests/hash_hmac_file_error.phpt index 7cbc347691202..3a4d85ee7e35b 100644 --- a/ext/hash/tests/hash_hmac_file_error.phpt +++ b/ext/hash/tests/hash_hmac_file_error.phpt @@ -43,4 +43,4 @@ hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algo hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algorithm -- Testing hash_hmac_file() function with bad path -- -hash_hmac_file(): Argument #2 ($data) must not contain any null bytes +hash_hmac_file(): Argument #2 ($filename) must not contain any null bytes diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 4850c00624232..39de76a5e4243 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -311,7 +311,7 @@ static int php_iconv_output_handler(void **nothing, php_output_context *output_c mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE; } - if (mimetype != NULL && !(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) { + if (mimetype != NULL && (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN) || (output_context->op & PHP_OUTPUT_HANDLER_START))) { size_t len; char *p = strstr(get_output_encoding(), "//"); @@ -1578,6 +1578,9 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st } err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); + if (err == PHP_ICONV_ERR_SUCCESS) { + err = _php_iconv_appendl(pretval, NULL, 0, cd); + } zend_string_release_ex(decoded_text, 0); if (err != PHP_ICONV_ERR_SUCCESS) { @@ -1718,13 +1721,6 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st *next_pos = p1; } - if (cd != (iconv_t)(-1)) { - _php_iconv_appendl(pretval, NULL, 0, cd); - } - if (cd_pl != (iconv_t)(-1)) { - _php_iconv_appendl(pretval, NULL, 0, cd_pl); - } - smart_str_0(pretval); out: if (cd != (iconv_t)(-1)) { diff --git a/ext/iconv/tests/gh7953.phpt b/ext/iconv/tests/gh7953.phpt new file mode 100644 index 0000000000000..10bab494ca675 --- /dev/null +++ b/ext/iconv/tests/gh7953.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-7953 (ob_clean() only may not set Content-* header) +--EXTENSIONS-- +iconv +--INI-- +input_encoding=UTF-8 +output_encoding=ISO-8859-1 +--CGI-- +--FILE-- + +--EXPECTF-- +%a +--EXPECTHEADERS-- +Content-Type: text/html; charset=ISO-8859-1 diff --git a/ext/iconv/tests/gh7980.phpt b/ext/iconv/tests/gh7980.phpt new file mode 100644 index 0000000000000..11be9e129e02b --- /dev/null +++ b/ext/iconv/tests/gh7980.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug GH-7980 (Unexpected result for iconv_mime_decode) +--EXTENSIONS-- +iconv +--FILE-- +'; +var_dump(iconv_mime_decode($subject, ICONV_MIME_DECODE_STRICT, 'UTF-8')); +?> +--EXPECT-- +string(57) "DSI Chargé de Formation Jean Dupont " diff --git a/ext/intl/breakiterator/breakiterator.stub.php b/ext/intl/breakiterator/breakiterator.stub.php index c78e48da62700..951b4ffc1bdfd 100644 --- a/ext/intl/breakiterator/breakiterator.stub.php +++ b/ext/intl/breakiterator/breakiterator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlBreakIterator implements IteratorAggregate { /** @tentative-return-type */ @@ -69,6 +70,7 @@ public function setText(string $text): ?bool {} // TODO return false instead of public function getIterator(): Iterator {} } +/** @not-serializable */ class IntlRuleBasedBreakIterator extends IntlBreakIterator { public function __construct(string $rules, bool $compiled = false) {} @@ -86,6 +88,7 @@ public function getRuleStatus(): int {} public function getRuleStatusVec(): array|false {} } +/** @not-serializable */ class IntlCodePointBreakIterator extends IntlBreakIterator { /** @tentative-return-type */ diff --git a/ext/intl/breakiterator/breakiterator_arginfo.h b/ext/intl/breakiterator/breakiterator_arginfo.h index 04f834a087eb0..ffb5017ab4263 100644 --- a/ext/intl/breakiterator/breakiterator_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1979da7ee2fa55b27f1c91bb4e0ddc37e8505b08 */ + * Stub hash: 724e0c36ee113b67906cc9a8cea23781f0a961bf */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlBreakIterator_createCharacterInstance, 0, 0, IntlBreakIterator, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") @@ -161,6 +161,7 @@ static zend_class_entry *register_class_IntlBreakIterator(zend_class_entry *clas 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; zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); return class_entry; @@ -172,6 +173,7 @@ static zend_class_entry *register_class_IntlRuleBasedBreakIterator(zend_class_en 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; return class_entry; } @@ -182,6 +184,7 @@ static zend_class_entry *register_class_IntlCodePointBreakIterator(zend_class_en 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; return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_iterators.stub.php b/ext/intl/breakiterator/breakiterator_iterators.stub.php index 7e7603fe6fd54..9d2fa9442819f 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.stub.php +++ b/ext/intl/breakiterator/breakiterator_iterators.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlPartsIterator extends IntlIterator { /** @tentative-return-type */ diff --git a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h index ee5e1279b5d2a..8db11d23739e0 100644 --- a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 267199a0a3532b5acf1d700f14329cdb2f2db0e1 */ + * Stub hash: f72f108e37541ac042bb25249ef226211c344189 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlPartsIterator_getBreakIterator, 0, 0, IntlBreakIterator, 0) ZEND_END_ARG_INFO() @@ -24,6 +24,7 @@ static zend_class_entry *register_class_IntlPartsIterator(zend_class_entry *clas 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; return class_entry; } diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index 3e8684c793669..2f5658a1e1a81 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -31,7 +31,7 @@ static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) { return (RuleBasedBreakIterator*)bio->biter; } -static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) +static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { char *rules; size_t rules_len; @@ -51,6 +51,9 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) RETURN_THROWS(); } + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + // instantiation of ICU object RuleBasedBreakIterator *rbbi; @@ -95,11 +98,13 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU); - zend_restore_error_handling(&error_handling); + _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) diff --git a/ext/intl/calendar/calendar.stub.php b/ext/intl/calendar/calendar.stub.php index 709d0e3667c7f..85c2c8a05e52c 100644 --- a/ext/intl/calendar/calendar.stub.php +++ b/ext/intl/calendar/calendar.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlCalendar { private function __construct() {} @@ -281,6 +282,7 @@ public function setTimeZone($timezone): bool {} public function toDateTime(): DateTime|false {} } +/** @not-serializable */ class IntlGregorianCalendar extends IntlCalendar { /** diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 7be45231f9c90..7b22161f30f5d 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7be0e49d2b898587c4bbefaaf613932ae4786c52 */ + * Stub hash: 0096dc9e60e2256054d23344e024df1d6527a5fa */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlCalendar___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -291,6 +291,7 @@ static zend_class_entry *register_class_IntlCalendar(void) 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; return class_entry; } @@ -301,6 +302,7 @@ static zend_class_entry *register_class_IntlGregorianCalendar(zend_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; return class_entry; } diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index 1803e703a82c9..757b280cd972a 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -44,7 +44,7 @@ static inline GregorianCalendar *fetch_greg(Calendar_object *co) { } static void _php_intlgregcal_constructor_body( - INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) + INTERNAL_FUNCTION_PARAMETERS, bool is_constructor, zend_error_handling *error_handling, bool *error_handling_replaced) { zval *tz_object = NULL; zval args_a[6], @@ -84,6 +84,11 @@ static void _php_intlgregcal_constructor_body( RETURN_THROWS(); } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + // instantion of ICU object Calendar_object *co = Z_INTL_CALENDAR_P(return_value); GregorianCalendar *gcal = NULL; @@ -188,17 +193,19 @@ U_CFUNC PHP_FUNCTION(intlgregcal_create_instance) intl_error_reset(NULL); object_init_ex(return_value, GregorianCalendar_ce_ptr); - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 0, NULL, NULL); } U_CFUNC PHP_METHOD(IntlGregorianCalendar, __construct) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); - zend_restore_error_handling(&error_handling); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 1, &error_handling, &error_handling_replaced); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) diff --git a/ext/intl/collator/collator.stub.php b/ext/intl/collator/collator.stub.php index e0c8487af79ff..bd201ee28be61 100644 --- a/ext/intl/collator/collator.stub.php +++ b/ext/intl/collator/collator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Collator { public function __construct(string $locale) {} diff --git a/ext/intl/collator/collator_arginfo.h b/ext/intl/collator/collator_arginfo.h index f13e1197dd8eb..c693ad925088b 100644 --- a/ext/intl/collator/collator_arginfo.h +++ b/ext/intl/collator/collator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4baf9586ab91f37facc865cf1b3aa6a87e5d732d */ + * Stub hash: c2e08f16cdc3d64e82fc277b4a59250d4b19c84e */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Collator___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -96,6 +96,7 @@ static zend_class_entry *register_class_Collator(void) 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; return class_entry; } diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c index bca1fc19b69b0..5fc4293e9773b 100644 --- a/ext/intl/collator/collator_create.c +++ b/ext/intl/collator/collator_create.c @@ -22,7 +22,7 @@ #include "intl_data.h" /* {{{ */ -static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; size_t locale_len = 0; @@ -38,6 +38,11 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); COLLATOR_METHOD_FETCH_OBJECT; @@ -56,7 +61,7 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( collator_create ) { object_init_ex( return_value, Collator_ce_ptr ); - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -67,14 +72,16 @@ PHP_FUNCTION( collator_create ) PHP_METHOD( Collator, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/common/common.stub.php b/ext/intl/common/common.stub.php index 0e87db6f51920..acadedd39934c 100644 --- a/ext/intl/common/common.stub.php +++ b/ext/intl/common/common.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlIterator implements Iterator { /** @tentative-return-type */ diff --git a/ext/intl/common/common_arginfo.h b/ext/intl/common/common_arginfo.h index 79d63aa5f4fdd..cbf422bf0d4c6 100644 --- a/ext/intl/common/common_arginfo.h +++ b/ext/intl/common/common_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c4698dbe96a069a63265052e9a105f074e3dda0a */ + * Stub hash: 976f2d1417928226d6c04ff444c4feda152d91df */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlIterator_current, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() @@ -37,6 +37,7 @@ static zend_class_entry *register_class_IntlIterator(zend_class_entry *class_ent 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; 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 2a9477fe267ac..daadd3e73d8db 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -87,6 +87,9 @@ if test "$PHP_INTL" != "no"; then PHP_REQUIRE_CXX() PHP_CXX_COMPILE_STDCXX(11, mandatory, PHP_INTL_STDCXX) PHP_INTL_CXX_FLAGS="$INTL_COMMON_FLAGS $PHP_INTL_STDCXX $ICU_CXXFLAGS" + case $host_alias in + *cygwin*) PHP_INTL_CXX_FLAGS="$PHP_INTL_CXX_FLAGS -D_POSIX_C_SOURCE=200809L" + esac if test "$ext_shared" = "no"; then PHP_ADD_SOURCES(PHP_EXT_DIR(intl), $PHP_INTL_CXX_SOURCES, $PHP_INTL_CXX_FLAGS) else diff --git a/ext/intl/converter/converter.stub.php b/ext/intl/converter/converter.stub.php index 9e07341778b20..19a8bbef9512f 100644 --- a/ext/intl/converter/converter.stub.php +++ b/ext/intl/converter/converter.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class UConverter { public function __construct(?string $destination_encoding = null, ?string $source_encoding = null) {} diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index fa88dd2ab630e..cae2a68d4be07 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2a6d8499e1a2d414130e366783a1c084f47a3293 */ + * Stub hash: 0ab2d741996611bbfcfb07462bc184a02f353585 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_UConverter___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, destination_encoding, IS_STRING, 1, "null") @@ -125,6 +125,7 @@ static zend_class_entry *register_class_UConverter(void) 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; return class_entry; } diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php index 11c0d05dc41e6..0ea15225f5a25 100644 --- a/ext/intl/dateformat/dateformat.stub.php +++ b/ext/intl/dateformat/dateformat.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlDateFormatter { /** diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index ccad07cd60a9d..9cb936f530992 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 82f90e7b0528b2b3515c086763dba4de0f92dfa7 */ + * Stub hash: c7c0d08433ab9dbf59777072550895d85294aad4 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) @@ -141,6 +141,7 @@ static zend_class_entry *register_class_IntlDateFormatter(void) 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; return class_entry; } diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index 2abd081385ad6..58867746ef0ca 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -45,7 +45,7 @@ extern "C" { UDAT_PATTERN == (i)) /* {{{ */ -static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { zval *object; char *locale_str; @@ -81,6 +81,11 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_STRING_OR_NULL(pattern_str, pattern_str_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { @@ -189,7 +194,7 @@ return FAILURE; U_CFUNC PHP_FUNCTION( datefmt_create ) { object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -200,18 +205,20 @@ U_CFUNC PHP_FUNCTION( datefmt_create ) U_CFUNC PHP_METHOD( IntlDateFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/dateformat/datepatterngenerator.stub.php b/ext/intl/dateformat/datepatterngenerator.stub.php index c0190fb4e9859..a9ce7c1463120 100644 --- a/ext/intl/dateformat/datepatterngenerator.stub.php +++ b/ext/intl/dateformat/datepatterngenerator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlDatePatternGenerator { public function __construct(?string $locale = null) {} diff --git a/ext/intl/dateformat/datepatterngenerator_arginfo.h b/ext/intl/dateformat/datepatterngenerator_arginfo.h index 63e8df7a5429c..f72e24cd1e7aa 100644 --- a/ext/intl/dateformat/datepatterngenerator_arginfo.h +++ b/ext/intl/dateformat/datepatterngenerator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 74026c524046787844da9f8132029735243176c6 */ + * Stub hash: 4456b13f7ed59847bbf129cd45b0d1f63ce70108 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDatePatternGenerator___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") @@ -32,6 +32,7 @@ static zend_class_entry *register_class_IntlDatePatternGenerator(void) 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; return class_entry; } diff --git a/ext/intl/dateformat/datepatterngenerator_methods.cpp b/ext/intl/dateformat/datepatterngenerator_methods.cpp index 37a0c6c496e88..b473bf5d8669e 100644 --- a/ext/intl/dateformat/datepatterngenerator_methods.cpp +++ b/ext/intl/dateformat/datepatterngenerator_methods.cpp @@ -30,7 +30,7 @@ using icu::DateTimePatternGenerator; using icu::Locale; using icu::StringPiece; -static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) +static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { char *locale_str; size_t locale_len = 0; @@ -44,6 +44,11 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + DTPATTERNGEN_METHOD_FETCH_OBJECT_NO_CHECK; if (dtpgo->dtpg != NULL) { @@ -74,7 +79,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) { object_init_ex( return_value, IntlDatePatternGenerator_ce_ptr ); - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -83,19 +88,21 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c index bea662081c36d..ed1806d6bbc55 100644 --- a/ext/intl/formatter/formatter_main.c +++ b/ext/intl/formatter/formatter_main.c @@ -23,7 +23,7 @@ #include "intl_convert.h" /* {{{ */ -static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; char* pattern = NULL; @@ -40,6 +40,11 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); object = return_value; FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; @@ -74,7 +79,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( numfmt_create ) { object_init_ex( return_value, NumberFormatter_ce_ptr ); - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -85,15 +90,17 @@ PHP_FUNCTION( numfmt_create ) PHP_METHOD( NumberFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c index 5be01e22e0a41..c363dd9706fb2 100644 --- a/ext/intl/msgformat/msgformat.c +++ b/ext/intl/msgformat/msgformat.c @@ -25,7 +25,7 @@ #include "intl_convert.h" /* {{{ */ -static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; char* pattern; @@ -45,6 +45,11 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; @@ -104,7 +109,7 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( msgfmt_create ) { object_init_ex( return_value, MessageFormatter_ce_ptr ); - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -115,17 +120,19 @@ PHP_FUNCTION( msgfmt_create ) PHP_METHOD( MessageFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/msgformat/msgformat.stub.php b/ext/intl/msgformat/msgformat.stub.php index c85a9b92b3a32..20afbd2b42cd4 100644 --- a/ext/intl/msgformat/msgformat.stub.php +++ b/ext/intl/msgformat/msgformat.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class MessageFormatter { public function __construct(string $locale, string $pattern) {} diff --git a/ext/intl/msgformat/msgformat_arginfo.h b/ext/intl/msgformat/msgformat_arginfo.h index 8f0456f6cbb05..4e7146048640d 100644 --- a/ext/intl/msgformat/msgformat_arginfo.h +++ b/ext/intl/msgformat/msgformat_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 44bc7b87c0b6c674bf94764b3f036006e3933713 */ + * Stub hash: d595f5c582996ebb96ab39df8cb56c4cf6c8dfcf */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MessageFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -81,6 +81,7 @@ static zend_class_entry *register_class_MessageFormatter(void) 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; return class_entry; } diff --git a/ext/intl/resourcebundle/resourcebundle.stub.php b/ext/intl/resourcebundle/resourcebundle.stub.php index 4247fca318a4e..47df7a19b3a9f 100644 --- a/ext/intl/resourcebundle/resourcebundle.stub.php +++ b/ext/intl/resourcebundle/resourcebundle.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class ResourceBundle implements IteratorAggregate, Countable { public function __construct(?string $locale, ?string $bundle, bool $fallback = true) {} diff --git a/ext/intl/resourcebundle/resourcebundle_arginfo.h b/ext/intl/resourcebundle/resourcebundle_arginfo.h index 0564b026dc39b..6a478edd430b2 100644 --- a/ext/intl/resourcebundle/resourcebundle_arginfo.h +++ b/ext/intl/resourcebundle/resourcebundle_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d27fa5a4dc092b94e48fc876070f440c247fa6c2 */ + * Stub hash: 7816536650d8513ef6998233096b0bf6a29d7af4 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ResourceBundle___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) @@ -62,6 +62,7 @@ static zend_class_entry *register_class_ResourceBundle(zend_class_entry *class_e 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; 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 589572024f009..aa4671a1b1310 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -74,7 +74,7 @@ static zend_object *ResourceBundle_object_create( zend_class_entry *ce ) /* }}} */ /* {{{ ResourceBundle_ctor */ -static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char *bundlename; size_t bundlename_len = 0; @@ -93,6 +93,11 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + if (rb->me) { zend_throw_error(NULL, "ResourceBundle object is already constructed"); return FAILURE; @@ -139,15 +144,17 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_METHOD( ResourceBundle, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ @@ -155,7 +162,7 @@ PHP_METHOD( ResourceBundle, __construct ) PHP_FUNCTION( resourcebundle_create ) { object_init_ex( return_value, ResourceBundle_ce_ptr ); - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php index 0ff7cc6da7c4a..dc414949b0ab8 100644 --- a/ext/intl/spoofchecker/spoofchecker.stub.php +++ b/ext/intl/spoofchecker/spoofchecker.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Spoofchecker { public function __construct() {} diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index 281ea7f3ed330..c030015d49c86 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d915fb3698e0bde4af2a1175fff882cae1f55668 */ + * Stub hash: f1c86958a39aa8f89ee468a0753f6a5b232c3e1f */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Spoofchecker___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -58,6 +58,7 @@ static zend_class_entry *register_class_Spoofchecker(void) 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; return class_entry; } diff --git a/ext/intl/tests/gh8115.phpt b/ext/intl/tests/gh8115.phpt new file mode 100644 index 0000000000000..47e32658e5a7d --- /dev/null +++ b/ext/intl/tests/gh8115.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-8115 (Can't catch deprecation in IntlDateFormatter) +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +Caught (8192): IntlDateFormatter::__construct(): Passing null to parameter #2 ($dateType) of type int is deprecated +Caught (8192): IntlDateFormatter::__construct(): Passing null to parameter #3 ($timeType) of type int is deprecated +Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parameter #1 ($rules) of type string is deprecated +Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parameter #2 ($compiled) of type bool is deprecated +Caught (8192): Collator::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type int is deprecated +Caught (8192): MessageFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): MessageFormatter::__construct(): Passing null to parameter #2 ($pattern) of type string is deprecated +Caught (8192): ResourceBundle::__construct(): Passing null to parameter #3 ($fallback) of type bool is deprecated diff --git a/ext/intl/timezone/timezone.stub.php b/ext/intl/timezone/timezone.stub.php index cc4f6084fd535..55592a386cc0f 100644 --- a/ext/intl/timezone/timezone.stub.php +++ b/ext/intl/timezone/timezone.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlTimeZone { private function __construct() {} diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index c8a77dcb07829..d0d1e94d2f84f 100644 --- a/ext/intl/timezone/timezone_arginfo.h +++ b/ext/intl/timezone/timezone_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3f945431687a2f45b0ec8c3a6435ef68008c75ad */ + * Stub hash: 2ec7a46ca205dfeb9ef0dc3c8e8d78bce1cf43be */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlTimeZone___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -169,6 +169,7 @@ static zend_class_entry *register_class_IntlTimeZone(void) 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; return class_entry; } diff --git a/ext/intl/transliterator/transliterator.stub.php b/ext/intl/transliterator/transliterator.stub.php index 6d52263e0646f..81c4070352825 100644 --- a/ext/intl/transliterator/transliterator.stub.php +++ b/ext/intl/transliterator/transliterator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Transliterator { public string $id; diff --git a/ext/intl/transliterator/transliterator_arginfo.h b/ext/intl/transliterator/transliterator_arginfo.h index c80be4f5b3460..03aa3b1f0ee9c 100644 --- a/ext/intl/transliterator/transliterator_arginfo.h +++ b/ext/intl/transliterator/transliterator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8a6aaab7dd89a014726bd1fdf1f40f7b6fa98ea5 */ + * Stub hash: 8ef1f285c6138fbc58c1e4cef04d4ac09dfc3fef */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Transliterator___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -61,6 +61,7 @@ static zend_class_entry *register_class_Transliterator(void) 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; zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); diff --git a/ext/intl/uchar/uchar.c b/ext/intl/uchar/uchar.c index 149446706724e..43fe38314fbb2 100644 --- a/ext/intl/uchar/uchar.c +++ b/ext/intl/uchar/uchar.c @@ -38,7 +38,7 @@ static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_l static zend_never_inline int parse_code_point_param(INTERNAL_FUNCTION_PARAMETERS, UChar32 *cp) { zend_string *string_codepoint; - zend_long int_codepoint; + zend_long int_codepoint = 0; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); diff --git a/ext/json/json.c b/ext/json/json.c index 2d7846a5dbed9..b21ed4d14b20e 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -141,10 +141,10 @@ static PHP_MINFO_FUNCTION(json) } /* }}} */ -PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth) /* {{{ */ +PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth) /* {{{ */ { php_json_encoder encoder; - int return_code; + zend_result return_code; php_json_encode_init(&encoder); encoder.max_depth = depth; @@ -156,7 +156,7 @@ PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend } /* }}} */ -PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ +PHP_JSON_API zend_result php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ { return php_json_encode_ex(buf, val, options, JSON_G(encode_max_depth)); } @@ -195,7 +195,7 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ -PHP_JSON_API int php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ +PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ { php_json_parser parser; diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index b0f703041b068..13c5ed0aad683 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -31,7 +31,7 @@ static const char digits[] = "0123456789abcdef"; -static int php_json_escape_string( +static zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder); @@ -71,7 +71,7 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options, php /* }}} */ -static inline int php_json_is_valid_double(double d) /* {{{ */ +static inline bool php_json_is_valid_double(double d) /* {{{ */ { return !zend_isinf(d) && !zend_isnan(d); } @@ -107,7 +107,7 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) } \ } while (0) -static int php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { int i, r, need_comma = 0; HashTable *myht, *prop_ht; @@ -312,11 +312,10 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options, php_jso } /* }}} */ -static int php_json_escape_string( +static zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder) /* {{{ */ { - int status; unsigned int us; size_t pos, checkpoint; char *dst; @@ -371,7 +370,7 @@ static int php_json_escape_string( } us = (unsigned char)s[0]; if (UNEXPECTED(us >= 0x80)) { - + zend_result status; us = php_next_utf8_char((unsigned char *)s, len, &pos, &status); /* check whether UTF8 character is correct */ @@ -526,12 +525,12 @@ static int php_json_escape_string( } /* }}} */ -static int php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(val); HashTable* myht = Z_OBJPROP_P(val); zval retval, fname; - int return_code; + zend_result return_code; if (myht && GC_IS_RECURSIVE(myht)) { encoder->error_code = PHP_JSON_ERROR_RECURSION; @@ -588,7 +587,7 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op } /* }}} */ -static int php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder) +static zend_result php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce->enum_backing_type == IS_UNDEF) { @@ -601,7 +600,7 @@ static int php_json_encode_serializable_enum(smart_str *buf, zval *val, int opti return php_json_encode_zval(buf, value_zv, options, encoder); } -int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { again: switch (Z_TYPE_P(val)) diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 89d04ed7f4d57..d4d8ac421f886 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -97,11 +97,11 @@ PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) ZEND_TSRMLS_CACHE_EXTERN() #endif -PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth); -PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options); -PHP_JSON_API int php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth); +PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth); +PHP_JSON_API zend_result php_json_encode(smart_str *buf, zval *val, int options); +PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth); -static inline int php_json_decode(zval *return_value, const char *str, int str_len, bool assoc, zend_long depth) +static inline zend_result php_json_decode(zval *return_value, const char *str, size_t str_len, bool assoc, zend_long depth) { return php_json_decode_ex(return_value, str, str_len, assoc ? PHP_JSON_OBJECT_AS_ARRAY : 0, depth); } diff --git a/ext/json/php_json_encoder.h b/ext/json/php_json_encoder.h index 51d2d6b59ab49..e1c48e2b50922 100644 --- a/ext/json/php_json_encoder.h +++ b/ext/json/php_json_encoder.h @@ -33,6 +33,6 @@ static inline void php_json_encode_init(php_json_encoder *encoder) memset(encoder, 0, sizeof(php_json_encoder)); } -int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder); +zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder); #endif /* PHP_JSON_ENCODER_H */ diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 449bf3248313e..99d5696ebcf31 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -378,9 +378,9 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) const char buf[] = "Content-Type:"; if (Z_TYPE_P(header) == IS_STRING && !zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) { - char *needle = estrdup("charset="); + char needle[] = "charset="; char *haystack = estrndup(Z_STRVAL_P(header), Z_STRLEN_P(header)); - char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), sizeof("charset=")-1); + char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), strlen(needle)); if (encoding) { char *end; @@ -408,7 +408,6 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) } } efree(haystack); - efree(needle); break; /* found content-type */ } } ZEND_HASH_FOREACH_END(); diff --git a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c index 0a6fe78957084..999b96a60334e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_7bit_8bit = { int mbfl_filt_conv_7bit_any(int c, mbfl_convert_filter *filter) { - return (*filter->output_function)(c, filter->data); + return (*filter->output_function)(c < 0x80 ? c : MBFL_BAD_INPUT, filter->data); } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 2ba32ee04563d..7d389efc79e91 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -33,6 +33,10 @@ #include "unicode_table_big5.h" static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static size_t mb_cp950_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp950(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_big5[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +68,8 @@ const mbfl_encoding mbfl_encoding_big5 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_big5_wchar, &vtbl_wchar_big5, - NULL, - NULL + mb_big5_to_wchar, + mb_wchar_to_big5 }; const mbfl_encoding mbfl_encoding_cp950 = { @@ -77,8 +81,8 @@ const mbfl_encoding mbfl_encoding_cp950 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp950_wchar, &vtbl_wchar_cp950, - NULL, - NULL + mb_cp950_to_wchar, + mb_wchar_to_cp950 }; const struct mbfl_convert_vtbl vtbl_big5_wchar = { @@ -380,3 +384,259 @@ int mbfl_filt_conv_wchar_big5(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c <= 0x7F) { + *out++ = c; + } else if (c > 0xA0 && c <= 0xF9 && c != 0xC8 && p < e) { + unsigned char c2 = *p++; + + if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0xA1 && c2 <= 0xFE)) { + unsigned int w = ((c - 0xA1)*157) + c2 - ((c2 <= 0x7E) ? 0x40 : 0xA1 - 0x3F); + w = (w < big5_ucs_table_size) ? big5_ucs_table[w] : 0; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_big5_table_min && w < ucs_a1_big5_table_max) { + s = ucs_a1_big5_table[w - ucs_a1_big5_table_min]; + } else if (w >= ucs_a2_big5_table_min && w < ucs_a2_big5_table_max) { + s = ucs_a2_big5_table[w - ucs_a2_big5_table_min]; + } else if (w >= ucs_a3_big5_table_min && w < ucs_a3_big5_table_max) { + s = ucs_a3_big5_table[w - ucs_a3_big5_table_min]; + } else if (w >= ucs_i_big5_table_min && w < ucs_i_big5_table_max) { + s = ucs_i_big5_table[w - ucs_i_big5_table_min]; + } else if (w >= ucs_r1_big5_table_min && w < ucs_r1_big5_table_max) { + s = ucs_r1_big5_table[w - ucs_r1_big5_table_min]; + } else if (w >= ucs_r2_big5_table_min && w < ucs_r2_big5_table_max) { + s = ucs_r2_big5_table[w - ucs_r2_big5_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_big5); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s <= 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} + +static size_t mb_cp950_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c <= 0x7F) { + *out++ = c; + } else if (c > 0x80 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + + if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0xA1 && c2 <= 0xFE)) { + unsigned int w = ((c - 0xA1)*157) + c2 - ((c2 <= 0x7E) ? 0x40 : 0xA1 - 0x3F); + w = (w < big5_ucs_table_size) ? big5_ucs_table[w] : 0; + + /* PUA for CP950 */ + if (is_in_cp950_pua(c, c2)) { + unsigned int s = (c << 8) | c2; + + int k; + for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { + if (s >= cp950_pua_tbl[k][2] && s <= cp950_pua_tbl[k][3]) { + break; + } + } + + if ((cp950_pua_tbl[k][2] & 0xFF) == 0x40) { + w = 157*(c - (cp950_pua_tbl[k][2] >> 8)) + c2 - (c2 >= 0xA1 ? 0x62 : 0x40) + cp950_pua_tbl[k][0]; + } else { + w = s - cp950_pua_tbl[k][2] + cp950_pua_tbl[k][0]; + } + } else if (c == 0xA1) { + if (c2 == 0x45) { + w = 0x2027; + } else if (c2 == 0x4E) { + w = 0xFE51; + } else if (c2 == 0x5A) { + w = 0x2574; + } else if (c2 == 0xC2) { + w = 0x00AF; + } else if (c2 == 0xC3) { + w = 0xFFE3; + } else if (c2 == 0xC5) { + w = 0x02CD; + } else if (c2 == 0xE3) { + w = 0xFF5E; + } else if (c2 == 0xF2) { + w = 0x2295; + } else if (c2 == 0xF3) { + w = 0x2299; + } else if (c2 == 0xFE) { + w = 0xFF0F; + } + } else if (c == 0xA2) { + if (c2 == 0x40) { + w = 0xFF3C; + } else if (c2 == 0x41) { + w = 0x2215; + } else if (c2 == 0x42) { + w = 0xFE68; + } else if (c2 == 0x46) { + w = 0xFFE0; + } else if (c2 == 0x47) { + w = 0xFFE1; + } else if (c2 == 0xCC) { + w = 0x5341; + } else if (c2 == 0xCE) { + w = 0x5345; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp950(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_big5_table_min && w < ucs_a1_big5_table_max) { + s = ucs_a1_big5_table[w - ucs_a1_big5_table_min]; + } else if (w >= ucs_a2_big5_table_min && w < ucs_a2_big5_table_max) { + s = ucs_a2_big5_table[w - ucs_a2_big5_table_min]; + } else if (w >= ucs_a3_big5_table_min && w < ucs_a3_big5_table_max) { + s = ucs_a3_big5_table[w - ucs_a3_big5_table_min]; + } else if (w >= ucs_i_big5_table_min && w < ucs_i_big5_table_max) { + s = ucs_i_big5_table[w - ucs_i_big5_table_min]; + } else if (w >= ucs_r1_big5_table_min && w < ucs_r1_big5_table_max) { + s = ucs_r1_big5_table[w - ucs_r1_big5_table_min]; + } else if (w >= ucs_r2_big5_table_min && w < ucs_r2_big5_table_max) { + s = ucs_r2_big5_table[w - ucs_r2_big5_table_min]; + } + + if (w >= 0xE000 && w <= 0xF848) { + int k; + for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { + if (w <= cp950_pua_tbl[k][1]) { + break; + } + } + + int c1 = w - cp950_pua_tbl[k][0]; + if ((cp950_pua_tbl[k][2] & 0xFF) == 0x40) { + int c2 = cp950_pua_tbl[k][2] >> 8; + s = ((c1 / 157) + c2) << 8; + c1 %= 157; + s |= c1 + (c1 >= 0x3F ? 0x62 : 0x40); + } else { + s = c1 + cp950_pua_tbl[k][2]; + } + } else if (w == 0xA2 || w == 0xA3 || w == 0x401 || (w >= 0x414 && w <= 0x41C) || (w >= 0x423 && w <= 0x44F) || w == 0x451 || w == 0x2022 || w == 0x203E || w == 0x223C || (w >= 0x2460 && w <= 0x247D) || w == 0x2609 || w == 0x2641 || w == 0x3005 || (w >= 0x302A && w <= 0x30FF) || w == 0xFF64) { + s = 0; + } else if (w == 0xAF) { + s = 0xA1C2; + } else if (w == 0x2CD) { + s = 0xA1C5; + } else if (w == 0x2027) { + s = 0xA145; + } else if (w == 0x2215) { + s = 0xA241; + } else if (w == 0x2295) { + s = 0xA1F2; + } else if (w == 0x2299) { + s = 0xA1F3; + } else if (w == 0x2574) { + s = 0xA15A; + } else if (w == 0xFE51) { + s = 0xA14E; + } else if (w == 0xFE68) { + s = 0xA242; + } else if (w == 0xFF3C) { + s = 0xA240; + } else if (w == 0xFF5E) { + s = 0xA1E3; + } else if (w == 0xFFE0) { + s = 0xA246; + } else if (w == 0xFFE1) { + s = 0xA247; + } else if (w == 0xFFE3) { + s = 0xA1C3; + } else if (w == 0xFF0F) { + s = 0xA1FE; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_big5); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s <= 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index a67b538bb4311..18686e8bf1ed1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -35,6 +35,10 @@ static int mbfl_filt_conv_cp5022x_wchar_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50220_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50220(int c, mbfl_convert_filter *filter); +static size_t mb_cp5022x_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp50220(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_cp50221(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_cp50222(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); /* Previously, a dubious 'encoding' called 'cp50220raw' was supported * This was just CP50220, but the implementation was less strict regarding @@ -56,8 +60,8 @@ const mbfl_encoding mbfl_encoding_cp50220 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50220_wchar, &vtbl_wchar_cp50220, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50220 }; const mbfl_encoding mbfl_encoding_cp50221 = { @@ -69,8 +73,8 @@ const mbfl_encoding mbfl_encoding_cp50221 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50221_wchar, &vtbl_wchar_cp50221, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50221 }; const mbfl_encoding mbfl_encoding_cp50222 = { @@ -82,8 +86,8 @@ const mbfl_encoding mbfl_encoding_cp50222 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50222_wchar, &vtbl_wchar_cp50222, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50222 }; const struct mbfl_convert_vtbl vtbl_cp50220_wchar = { @@ -627,3 +631,400 @@ static int mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter) return 0; } + +#define ASCII 0 +#define JISX_0201_LATIN 1 +#define JISX_0201_KANA 2 +#define JISX_0208 3 +#define JISX_0212 4 + +static size_t mb_cp5022x_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c == 0x1B) { + /* Escape sequence */ + if ((e - p) < 2) { + *out++ = MBFL_BAD_INPUT; + /* Duplicate error-handling behavior of legacy code */ + if (p < e && (*p == '(' || *p == '$')) + p++; + continue; + } + unsigned char c2 = *p++; + if (c2 == '$') { + unsigned char c3 = *p++; + if (c3 == '@' || c3 == 'B') { + *state = JISX_0208; + } else if (c3 == '(') { + if (p == e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c4 = *p++; + if (c4 == '@' || c4 == 'B') { + *state = JISX_0208; + } else if (c4 == 'D') { + *state = JISX_0212; + } else { + if ((limit - out) < 3) { + p -= 4; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '$'; + *out++ = '('; + p--; + } + } else { + if ((limit - out) < 2) { + p -= 3; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '$'; + p--; + } + } else if (c2 == '(') { + unsigned char c3 = *p++; + if (c3 == 'B' || c3 == 'H') { + *state = ASCII; + } else if (c3 == 'J') { + *state = JISX_0201_LATIN; + } else if (c3 == 'I') { + *state = JISX_0201_KANA; + } else { + if ((limit - out) < 2) { + p -= 3; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '('; + p--; + } + } else { + *out++ = MBFL_BAD_INPUT; + p--; + } + } else if (c == 0xE) { + *state = JISX_0201_KANA; + } else if (c == 0xF) { + *state = ASCII; + } else if (*state == JISX_0201_LATIN && c == 0x5C) { /* YEN SIGN */ + *out++ = 0xA5; + } else if (*state == JISX_0201_LATIN && c == 0x7E) { /* OVER LINE */ + *out++ = 0x203E; + } else if (*state == JISX_0201_KANA && c > 0x20 && c < 0x60) { + *out++ = 0xFF40 + c; + } else if (*state >= JISX_0208 && c > 0x20 && c <= 0x97) { + if (p == e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c2 = *p++; + if (c2 > 0x20 && c2 < 0x7F) { + unsigned int s = (c - 0x21)*94 + c2 - 0x21; + uint32_t w = 0; + if (*state == JISX_0208) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { + w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; + } else if (s >= 94*94 && s < 114*94) { + /* MicroSoft extension */ + w = s - 94*94 + 0xE000; + } + if (!w) + w = MBFL_BAD_INPUT; + } else { + if (s < jisx0212_ucs_table_size) { + w = jisx0212_ucs_table[s]; + } + if (!w) + w = MBFL_BAD_INPUT; + } + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xDF) { + *out++ = 0xFEC0 + c; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static unsigned int lookup_wchar(uint32_t w) +{ + unsigned int s = 0; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w == 0x203E) { /* OVERLINE */ + s = 0x1007E; /* Convert to JISX 0201 OVERLINE */ + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w <= 0xE757) { + /* Private Use Area codepoints */ + s = w - 0xE000; + s = ((s / 94) + 0x7F) << 8 | ((s % 94) + 0x21); + } + + if (!s) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x1005C; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else if (w == 0) { + return 0; + } + } + + /* Above, we do a series of lookups in `ucs_*_jis_table` to find a + * corresponding kuten code for this Unicode codepoint + * If we get zero, that means the codepoint is not in JIS X 0208 + * On the other hand, if we get a result with the high bits set on both + * upper and lower bytes, that is not a code in JIS X 0208 but rather + * in JIS X 0213 + * In either case, check if this codepoint is one of the extensions added + * to JIS X 0208 by MicroSoft (to make CP932) */ + if (!s || s >= 0x8080) { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (w == cp932ext1_ucs_table[i]) { + return (((i / 94) + (cp932ext1_ucs_table_min / 94) + 0x21) << 8) + (i % 94) + 0x21; + } + } + + for (int i = 0; i < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; i++) { + if (w == cp932ext2_ucs_table[i]) { + return (((i / 94) + (cp932ext2_ucs_table_min / 94) + 0x21) << 8) + (i % 94) + 0x21; + } + } + } + + return s; +} + +static void mb_wchar_to_cp50220(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + bool consumed = false; + + while (len--) { + uint32_t w = *in++; + + w = mbfl_convert_kana(w, len ? *in : 0, &consumed, NULL, MBFL_HAN2ZEN_KATAKANA | MBFL_HAN2ZEN_GLUE); + + if (consumed) { + /* Two successive codepoints were converted into one */ + in++; len--; consumed = false; + } + + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'I'); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} + +static void mb_wchar_to_cp50221(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'I'); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} + +static void mb_wchar_to_cp50222(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50222); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + buf->state = ASCII; + } else if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xE); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + } + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + } + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50222); + } + } + + if (end) { + if (buf->state == JISX_0201_KANA) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 1); + out = mb_convert_buf_add(out, 0xF); + } else if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c index 2f7193462e025..7d1a739f3369e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c @@ -35,6 +35,8 @@ #include "cp932_table.h" static int mbfl_filt_conv_cp51932_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp51932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp51932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_eucjp[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -66,8 +68,8 @@ const mbfl_encoding mbfl_encoding_cp51932 = { 0, &vtbl_cp51932_wchar, &vtbl_wchar_cp51932, - NULL, - NULL + mb_cp51932_to_wchar, + mb_wchar_to_cp51932 }; const struct mbfl_convert_vtbl vtbl_cp51932_wchar = { @@ -267,3 +269,142 @@ mbfl_filt_conv_wchar_cp51932(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp51932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int s = (c - 0xA1)*94 + c2 - 0xA1, w = 0; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xDF) { + *out++ = 0xFEC0 + c2; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp51932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } + + if (s >= 0x8080) s = 0; /* We don't support JIS X0213 */ + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s = ((i/94 + 0x2D) << 8) + (i%94) + 0x21; + goto found_it; + } + } + + for (int i = 0; i < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; i++) { + if (cp932ext2_ucs_table[i] == w) { + s = ((i/94 + 0x79) << 8) + (i%94) + 0x21; + goto found_it; + } + } + } +found_it: ; + } + + if (!s || s >= 0x8080) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp51932); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s < 0x100) { + out = mb_convert_buf_add2(out, 0x8E, s); + } else { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c index 06ac6b22b26f2..ef7c47e967415 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c @@ -34,6 +34,8 @@ #include "unicode_table_jis.h" static int mbfl_filt_conv_cp932_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_sjis[] = { /* 0x80-0x9f,0xE0-0xFF */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -65,8 +67,8 @@ const mbfl_encoding mbfl_encoding_cp932 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp932_wchar, &vtbl_wchar_cp932, - NULL, - NULL + mb_cp932_to_wchar, + mb_wchar_to_cp932 }; const struct mbfl_convert_vtbl vtbl_cp932_wchar = { @@ -310,3 +312,151 @@ mbfl_filt_conv_wchar_cp932(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0xA0 && c < 0xE0) { + /* Kana */ + *out++ = 0xFEC0 + c; + } else if (c > 0x80 && c < 0xFD && c != 0xA0 && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0x40 && c2 <= 0xFC && c2 != 0x7F) { + unsigned int s1, s2, w = 0; + SJIS_DECODE(c, c2, s1, s2); + unsigned int s = (s1 - 0x21)*94 + s2 - 0x21; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { + w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; + } else if (s >= (94*94) && s < (114*94)) { + w = s - (94*94) + 0xE000; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s1 = 0, s2 = 0, c1, c2; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s1 = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s1 = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s1 = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s1 = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w < (0xE000 + 20*94)) { + s1 = w - 0xE000; + c1 = s1/94 + 0x7f; + c2 = s1%94 + 0x21; + s1 = (c1 << 8) | c2; + s2 = 1; + } + + if (w == 0xA5) { /* YEN SIGN */ + s1 = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s1 = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s1 = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s1 = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s1 = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s1 = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s1 = 0x224C; + } else if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } + + if (!s1 || (s1 >= 0x8080 && !s2)) { /* not found or X 0212 */ + for (unsigned int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s1 = ((i/94 + 0x2D) << 8) + (i%94 + 0x21); + goto emit_output; + } + } + + for (unsigned int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) { + if (cp932ext3_ucs_table[i] == w) { + s1 = ((i/94 + 0x93) << 8) + (i%94 + 0x21); + goto emit_output; + } + } + + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp932); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + continue; + } + +emit_output: + if (s1 < 0x100) { + out = mb_convert_buf_add(out, s1); + } else { + c1 = (s1 >> 8) & 0xFF; + c2 = s1 & 0xFF; + SJIS_ENCODE(c1, c2, s1, s2); + out = mb_convert_buf_add2(out, s1, s2); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c index f12523dedca2a..5591608afa87d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c @@ -33,6 +33,9 @@ #include "unicode_table_cp936.h" static int mbfl_filt_conv_cp936_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp936_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp936(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); + static const unsigned char mblen_table_cp936[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +67,8 @@ const mbfl_encoding mbfl_encoding_cp936 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp936_wchar, &vtbl_wchar_cp936, - NULL, - NULL + mb_cp936_to_wchar, + mb_wchar_to_cp936 }; const struct mbfl_convert_vtbl vtbl_cp936_wchar = { @@ -267,3 +270,160 @@ int mbfl_filt_conv_wchar_cp936(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp936_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c == 0x80) { + *out++ = 0x20AC; /* Euro sign */ + } else if (c < 0xFF) { + if (p >= e) { + *out++ = MBFL_BAD_INPUT; + continue; + } + + unsigned char c2 = *p++; + + if (((c >= 0xAA && c <= 0xAF) || (c >= 0xF8 && c <= 0xFE)) && (c2 >= 0xA1 && c2 <= 0xFE)) { + /* UDA part 1, 2: U+E000-U+E4C5 */ + *out++ = 94*(c >= 0xF8 ? c - 0xF2 : c - 0xAA) + (c2 - 0xA1) + 0xE000; + } else if (c >= 0xA1 && c <= 0xA7 && c2 >= 0x40 && c2 < 0xA1 && c2 != 0x7F) { + /* UDA part 3: U+E4C6-U+E765*/ + *out++ = 96*(c - 0xA1) + c2 - (c2 >= 0x80 ? 0x41 : 0x40) + 0xE4C6; + } else { + unsigned int w = (c << 8) | c2; + + if ((w >= 0xA2AB && w <= 0xA9FE) || (w >= 0xD7FA && w <= 0xD7FE) || (w >= 0xFE50 && w <= 0xFEA0)) { + for (int k = 0; k < mbfl_cp936_pua_tbl_max; k++) { + if (w >= mbfl_cp936_pua_tbl[k][2] && w <= mbfl_cp936_pua_tbl[k][2] + mbfl_cp936_pua_tbl[k][1] - mbfl_cp936_pua_tbl[k][0]) { + *out++ = w - mbfl_cp936_pua_tbl[k][2] + mbfl_cp936_pua_tbl[k][0]; + goto next_iteration; + } + } + } + + if (c < 0xFF && c > 0x80 && c2 >= 0x40 && c2 < 0xFF && c2 != 0x7F) { + w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + *out++ = cp936_ucs_table[w]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = 0xF8F5; + } +next_iteration: ; + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp936(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + /* U+0000-U+0451 */ + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + /* U+2000-U+26FF */ + if (w == 0x203E) { + s = 0xA3FE; + } else if (w == 0x2218) { + s = 0xA1E3; + } else if (w == 0x223C) { + s = 0xA1AB; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + /* U+2F00-U+33FF */ + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + /* U+4D00-9FFF CJK Unified Ideographs (+ Extension A) */ + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= 0xE000 && w <= 0xE864) { + /* PUA */ + if (w < 0xe766) { + if (w < 0xe4c6) { + unsigned int c1 = w - 0xE000; + s = (c1 % 94) + 0xA1; + c1 /= 94; + s |= (c1 < 0x6 ? c1 + 0xAA : c1 + 0xF2) << 8; + } else { + unsigned int c1 = w - 0xE4C6; + s = ((c1 / 96) + 0xA1) << 8; + c1 %= 96; + s |= c1 + (c1 >= 0x3F ? 0x41 : 0x40); + } + } else { + /* U+E766-U+E864 */ + unsigned int k1 = 0; + unsigned int k2 = mbfl_cp936_pua_tbl_max; + while (k1 < k2) { + int k = (k1 + k2) >> 1; + if (w < mbfl_cp936_pua_tbl[k][0]) { + k2 = k; + } else if (w > mbfl_cp936_pua_tbl[k][1]) { + k1 = k + 1; + } else { + s = w - mbfl_cp936_pua_tbl[k][0] + mbfl_cp936_pua_tbl[k][2]; + break; + } + } + } + } else if (w == 0xF8F5) { + s = 0xFF; + } else if (w >= ucs_ci_cp936_table_min && w < ucs_ci_cp936_table_max) { + /* U+F900-U+FA2F CJK Compatibility Ideographs */ + s = ucs_ci_cp936_table[w - ucs_ci_cp936_table_min]; + } else if (w >= ucs_cf_cp936_table_min && w < ucs_cf_cp936_table_max) { + s = ucs_cf_cp936_table[w - ucs_cf_cp936_table_min]; + } else if (w >= ucs_sfv_cp936_table_min && w < ucs_sfv_cp936_table_max) { + /* U+FE50-U+FE6F Small Form Variants */ + s = ucs_sfv_cp936_table[w - ucs_sfv_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + /* U+FF00-U+FFFF HW/FW Forms */ + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp936); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else if (s <= 0x80 || s == 0xFF) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c index 0465a814ff3d8..f179d602505a2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c @@ -33,6 +33,8 @@ #include "unicode_table_cp936.h" static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euccn_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euccn(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euccn[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +66,8 @@ const mbfl_encoding mbfl_encoding_euc_cn = { 0, &vtbl_euccn_wchar, &vtbl_wchar_euccn, - NULL, - NULL + mb_euccn_to_wchar, + mb_wchar_to_euccn }; const struct mbfl_convert_vtbl vtbl_euccn_wchar = { @@ -216,3 +218,107 @@ static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euccn_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xA9) || (c >= 0xB0 && c <= 0xF7)) && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + if (w == 0x1864) { + w = 0x30FB; + } else if (w == 0x186A) { + w = 0x2015; + } else if ((w >= 0x1921 && w <= 0x192A) || w == 0x1963 || (w >= 0x1C59 && w <= 0x1C7E) || (w >= 0x1DBB && w <= 0x1DC4)) { + w = 0; + } else { + w = cp936_ucs_table[w]; + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euccn(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w != 0xB7 && w != 0x144 && w != 0x148 && w != 0x251 && w != 0x261) { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x2015) { + s = 0xA1AA; + } else if (w != 0x2014 && (w < 0x2170 || w > 0x2179)) { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + if (w == 0x30FB) { + s = 0xA1A4; + } else { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + /* Exclude CP936 extensions */ + if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { + s = 0; + } + + if (!s) { + if (w < 0x80) { + out = mb_convert_buf_add(out, w); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euccn); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c index 49e7f9dccd279..4845abda5c280 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c @@ -35,6 +35,8 @@ #include "cp932_table.h" static int mbfl_filt_conv_eucjpwin_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_eucjpwin_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_eucjpwin(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_eucjp[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -66,8 +68,8 @@ const mbfl_encoding mbfl_encoding_eucjp_win = { 0, &vtbl_eucjpwin_wchar, &vtbl_wchar_eucjpwin, - NULL, - NULL + mb_eucjpwin_to_wchar, + mb_wchar_to_eucjpwin }; const struct mbfl_convert_vtbl vtbl_eucjpwin_wchar = { @@ -337,3 +339,196 @@ int mbfl_filt_conv_wchar_eucjpwin(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_eucjpwin_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int s = (c - 0xA1)*94 + c2 - 0xA1, w = 0; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= (84 * 94)) { + w = s - (84 * 94) + 0xE000; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xDF) { + *out++ = 0xFEC0 + c2; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8F && p < e) { + unsigned char c2 = *p++; + if (p == e) { + *out++ = MBFL_BAD_INPUT; + continue; + } + unsigned char c3 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE && c3 >= 0xA1 && c3 <= 0xFE) { + unsigned int s = (c2 - 0xA1)*94 + c3 - 0xA1, w = 0; + + if (s < jisx0212_ucs_table_size) { + w = jisx0212_ucs_table[s]; + if (w == 0x7E) + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s >= (82*94) && s < (84*94)) { + s = (c2 << 8) | c3; + for (int i = 0; i < cp932ext3_eucjp_table_size; i++) { + if (cp932ext3_eucjp_table[i] == s) { + w = cp932ext3_ucs_table[i]; + break; + } + } + } else if (s >= (84*94)) { + w = s - (84*94) + 0xE000 + (94*10); + } + + if (w == 0xA6) + w = 0xFFE4; /* FULLWIDTH BROKEN BAR */ + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_eucjpwin(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w == 0xAF) { /* U+00AF is MACRON */ + s = 0xA2B4; /* Use JIS X 0212 overline */ + } else if (w == 0x203E) { + s = 0x7E; + } else if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w < (0xE000 + 10*94)) { + s = w - 0xE000; + s = ((s/94 + 0x75) << 8) + (s%94) + 0x21; + } else if (w >= (0xE000 + 10*94) && w < (0xE000 + 20*94)) { + s = w - (0xE000 + 10*94); + s = ((s/94 + 0xF5) << 8) + (s%94) + 0xA1; + } + + if (s == 0xA2F1) + s = 0x2D62; /* NUMERO SIGN */ + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x5C; + } else if (w == 0x2014) { /* EM DASH */ + s = 0x213D; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s = (((i/94) + (cp932ext1_ucs_table_min/94) + 0x21) << 8) + (i%94) + 0x21; + break; + } + } + + if (!s) { + for (int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) { + if (cp932ext3_ucs_table[i] == w) { + s = cp932ext3_eucjp_table[i]; + break; + } + } + } + } + } + + if (!s) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_eucjpwin); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s < 0x100) { + out = mb_convert_buf_add2(out, 0x8E, s); + } else if (s < 0x8080) { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 3); + out = mb_convert_buf_add3(out, 0x8F, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c index 70c4e3f9d5949..fd7bb3b9f7c1e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c @@ -32,6 +32,8 @@ #include "unicode_table_uhc.h" static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euckr_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euckr(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euckr[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -63,8 +65,8 @@ const mbfl_encoding mbfl_encoding_euc_kr = { 0, &vtbl_euckr_wchar, &vtbl_wchar_euckr, - NULL, - NULL + mb_euckr_to_wchar, + mb_wchar_to_euckr }; const struct mbfl_convert_vtbl vtbl_euckr_wchar = { @@ -200,3 +202,92 @@ static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euckr_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xAC) || (c >= 0xB0 && c <= 0xFD)) && c != 0xC9 && p < e) { + unsigned char c2 = *p++; + + if (c >= 0xA1 && c <= 0xC6 && c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xA1)*190 + c2 - 0x41; + ZEND_ASSERT(w < uhc2_ucs_table_size); + w = uhc2_ucs_table[w]; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else if (c >= 0xC7 && c <= 0xFE && c != 0xC9 && c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xC7)*94 + c2 - 0xA1; + ZEND_ASSERT(w < uhc3_ucs_table_size); + w = uhc3_ucs_table[w]; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euckr(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_uhc_table_min && w < ucs_a1_uhc_table_max) { + s = ucs_a1_uhc_table[w - ucs_a1_uhc_table_min]; + } else if (w >= ucs_a2_uhc_table_min && w < ucs_a2_uhc_table_max) { + s = ucs_a2_uhc_table[w - ucs_a2_uhc_table_min]; + } else if (w >= ucs_a3_uhc_table_min && w < ucs_a3_uhc_table_max) { + s = ucs_a3_uhc_table[w - ucs_a3_uhc_table_min]; + } else if (w >= ucs_i_uhc_table_min && w < ucs_i_uhc_table_max) { + s = ucs_i_uhc_table[w - ucs_i_uhc_table_min]; + } else if (w >= ucs_s_uhc_table_min && w < ucs_s_uhc_table_max) { + s = ucs_s_uhc_table[w - ucs_s_uhc_table_min]; + } else if (w >= ucs_r1_uhc_table_min && w < ucs_r1_uhc_table_max) { + s = ucs_r1_uhc_table[w - ucs_r1_uhc_table_min]; + } else if (w >= ucs_r2_uhc_table_min && w < ucs_r2_uhc_table_max) { + s = ucs_r2_uhc_table[w - ucs_r2_uhc_table_min]; + } + + /* Exclude UHC extension area (although we are using the UHC conversion tables) */ + if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { + s = 0; + } + + if (!s) { + if (w < 0x80) { + out = mb_convert_buf_add(out, w); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euckr); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c index f505ca17a3923..571b711bdf6c7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c @@ -33,6 +33,8 @@ #include "unicode_table_cns11643.h" static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euctw[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -65,8 +67,8 @@ const mbfl_encoding mbfl_encoding_euc_tw = { 0, &vtbl_euctw_wchar, &vtbl_wchar_euctw, - NULL, - NULL + mb_euctw_to_wchar, + mb_wchar_to_euctw }; const struct mbfl_convert_vtbl vtbl_euctw_wchar = { @@ -252,3 +254,120 @@ static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xA6) || (c >= 0xC2 && c <= 0xFD)) && c != 0xC3 && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xA1)*94 + (c2 - 0xA1); + if (w < cns11643_1_ucs_table_size) { + w = cns11643_1_ucs_table[w]; + } else { + w = 0; + } + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + + if ((c2 == 0xA1 || c2 == 0xA2 || c2 == 0xAE) && p < e) { + unsigned int plane = c2 - 0xA1; /* This is actually the CNS-11643 plane minus one */ + unsigned char c3 = *p++; + + if (c3 >= 0xA1 && ((plane == 0 && ((c3 >= 0xA1 && c3 <= 0xA6) || (c3 >= 0xC2 && c3 <= 0xFD)) && c3 != 0xC3) || (plane == 1 && c3 <= 0xF2) || (plane == 13 && c3 <= 0xE7)) && p < e) { + unsigned char c4 = *p++; + + if (c2 <= 0xAE && c4 > 0xA0 && c4 < 0xFF) { + unsigned int s = (c3 - 0xA1)*94 + c4 - 0xA1, w = 0; + + /* A later version of CNS-11643 moved all the characters in "plane 14" to "plane 3", + * and added tens of thousands more characters in planes 4, 5, 6, and 7 + * We only support the older version of CNS-11643 + * This is the same as iconv from glibc 2.2 */ + if (plane == 0 && s < cns11643_1_ucs_table_size) { + w = cns11643_1_ucs_table[s]; + } else if (plane == 1 && s < cns11643_2_ucs_table_size) { + w = cns11643_2_ucs_table[s]; + } else if (plane == 13 && s < cns11643_14_ucs_table_size) { + w = cns11643_14_ucs_table[s]; + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + continue; + } + } + } + + *out++ = MBFL_BAD_INPUT; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cns11643_table_min && w < ucs_a1_cns11643_table_max) { + s = ucs_a1_cns11643_table[w - ucs_a1_cns11643_table_min]; + } else if (w >= ucs_a2_cns11643_table_min && w < ucs_a2_cns11643_table_max) { + s = ucs_a2_cns11643_table[w - ucs_a2_cns11643_table_min]; + } else if (w >= ucs_a3_cns11643_table_min && w < ucs_a3_cns11643_table_max) { + s = ucs_a3_cns11643_table[w - ucs_a3_cns11643_table_min]; + } else if (w >= ucs_i_cns11643_table_min && w < ucs_i_cns11643_table_max) { + s = ucs_i_cns11643_table[w - ucs_i_cns11643_table_min]; + } else if (w >= ucs_r_cns11643_table_min && w < ucs_r_cns11643_table_max) { + s = ucs_r_cns11643_table[w - ucs_r_cns11643_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euctw); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else { + unsigned int plane = s >> 16; + if (plane <= 1) { + if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add4(out, 0x8E, 0xA0 + plane, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c index 00494daf358f0..b86b8315a560f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c @@ -34,6 +34,8 @@ #include "unicode_table_gb18030.h" static int mbfl_filt_conv_gb18030_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_gb18030_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_gb18030(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const char *mbfl_encoding_gb18030_aliases[] = {"gb-18030", "gb-18030-2000", NULL}; @@ -46,8 +48,8 @@ const mbfl_encoding mbfl_encoding_gb18030 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_gb18030_wchar, &vtbl_wchar_gb18030, - NULL, - NULL + mb_gb18030_to_wchar, + mb_wchar_to_gb18030 }; const struct mbfl_convert_vtbl vtbl_gb18030_wchar = { @@ -382,3 +384,229 @@ int mbfl_filt_conv_wchar_gb18030(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_gb18030_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0x80 && c < 0xFF && p < e) { + unsigned char c2 = *p++; + unsigned int s = (c << 8) | c2; + + if (((c >= 0x81 && c <= 0x84) || (c >= 0x90 && c <= 0xE3)) && c2 >= 0x30 && c2 <= 0x39) { + if (p >= e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c3 = *p++; + + if (c3 >= 0x81 && c3 <= 0xFE && p < e) { + unsigned char c4 = *p++; + + if (c4 >= 0x30 && c4 <= 0x39) { + if (c >= 0x90 && c <= 0xE3) { + unsigned int w = ((((c - 0x90)*10 + (c2 - 0x30))*126 + (c3 - 0x81)))*10 + (c4 - 0x30) + 0x10000; + *out++ = (w > 0x10FFFF) ? MBFL_BAD_INPUT : w; + } else { + /* Unicode BMP */ + unsigned int w = (((c - 0x81)*10 + (c2 - 0x30))*126 + (c3 - 0x81))*10 + (c4 - 0x30); + if (w <= 39419) { + *out++ = w + mbfl_gb_uni_ofst[mbfl_bisec_srch(w, mbfl_gb2uni_tbl, mbfl_gb_uni_max)]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (((c >= 0xAA && c <= 0xAF) || (c >= 0xF8 && c <= 0xFE)) && (c2 >= 0xA1 && c2 <= 0xFE)) { + /* UDA part 1, 2: U+E000-U+E4C5 */ + *out++ = 94*(c >= 0xF8 ? c - 0xF2 : c - 0xAA) + (c2 - 0xA1) + 0xE000; + } else if (c >= 0xA1 && c <= 0xA7 && c2 >= 0x40 && c2 < 0xA1 && c2 != 0x7F) { + /* UDA part 3: U+E4C6-U+E765 */ + *out++ = 96*(c - 0xA1) + c2 - (c2 >= 0x80 ? 0x41 : 0x40) + 0xE4C6; + } else { + if ((s >= 0xA2AB && s <= 0xA9FE) || (s >= 0xD7FA && s <= 0xD7FE) || (s >= 0xFE50 && s <= 0xFEA0)) { + for (int i = 0; i < mbfl_gb18030_pua_tbl_max; i++) { + if (s >= mbfl_gb18030_pua_tbl[i][2] && s <= mbfl_gb18030_pua_tbl[i][2] + mbfl_gb18030_pua_tbl[i][1] - mbfl_gb18030_pua_tbl[i][0]) { + *out++ = s - mbfl_gb18030_pua_tbl[i][2] + mbfl_gb18030_pua_tbl[i][0]; + goto next_iteration; + } + } + } + + if ((c >= 0xA1 && c <= 0xA9 && c2 >= 0xA1 && c2 <= 0xFE) || + (c >= 0xB0 && c <= 0xf7 && c2 >= 0xa1 && c2 <= 0xfe) || + (c >= 0x81 && c <= 0xa0 && c2 >= 0x40 && c2 <= 0xfe && c2 != 0x7f) || + (c >= 0xAA && c <= 0xfe && c2 >= 0x40 && c2 <= 0xa0 && c2 != 0x7f) || + (c >= 0xA8 && c <= 0xa9 && c2 >= 0x40 && c2 <= 0xa0 && c2 != 0x7F)) { + unsigned int w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + *out++ = cp936_ucs_table[w]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = MBFL_BAD_INPUT; + } +next_iteration: ; + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_gb18030(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w == 0x1F9) { + s = 0xA8Bf; + } else { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x20AC) { /* Euro sign */ + s = 0xA2E3; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= ucs_ci_cp936_table_min && w < ucs_ci_cp936_table_max) { + /* U+F900-U+FA2F CJK Compatibility Ideographs */ + if (w == 0xF92C) { + s = 0xFD9C; + } else if (w == 0xF979) { + s = 0xFD9D; + } else if (w == 0xF995) { + s = 0xFD9E; + } else if (w == 0xF9E7) { + s = 0xFD9F; + } else if (w == 0xF9F1) { + s = 0xFDA0; + } else if (w >= 0xFA0C && w <= 0xFA29) { + s = ucs_ci_s_cp936_table[w - 0xFA0C]; + } + } else if (w >= ucs_cf_cp936_table_min && w < ucs_cf_cp936_table_max) { + /* CJK Compatibility Forms */ + s = ucs_cf_cp936_table[w - ucs_cf_cp936_table_min]; + } else if (w >= ucs_sfv_cp936_table_min && w < ucs_sfv_cp936_table_max) { + /* U+FE50-U+FE6F Small Form Variants */ + s = ucs_sfv_cp936_table[w - ucs_sfv_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + /* U+FF00-U+FFFF HW/FW Forms */ + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } else if (w >= 0xE000 && w <= 0xE864) { + /* PUA */ + if (w < 0xE766) { + if (w < 0xE4C6) { + unsigned int c1 = w - 0xE000; + s = (c1 % 94) + 0xA1; + c1 /= 94; + s |= (c1 + (c1 < 0x06 ? 0xAA : 0xF2)) << 8; + } else { + unsigned int c1 = w - 0xE4C6; + s = ((c1 / 96) + 0xA1) << 8; + c1 %= 96; + s |= c1 + (c1 >= 0x3F ? 0x41 : 0x40); + } + } else { + /* U+E766-U+E864 */ + unsigned int k1 = 0, k2 = mbfl_gb18030_pua_tbl_max; + while (k1 < k2) { + unsigned int k = (k1 + k2) >> 1; + if (w < mbfl_gb18030_pua_tbl[k][0]) { + k2 = k; + } else if (w > mbfl_gb18030_pua_tbl[k][1]) { + k1 = k + 1; + } else { + s = w - mbfl_gb18030_pua_tbl[k][0] + mbfl_gb18030_pua_tbl[k][2]; + break; + } + } + } + } + + /* While GB18030 and CP936 are very similar, some mappings are different between these encodings; + * do a binary search in a table of differing codepoints to see if we have one */ + if (!s && w >= mbfl_gb18030_c_tbl_key[0] && w <= mbfl_gb18030_c_tbl_key[mbfl_gb18030_c_tbl_max-1]) { + int i = mbfl_bisec_srch2(w, mbfl_gb18030_c_tbl_key, mbfl_gb18030_c_tbl_max); + if (i >= 0) { + s = mbfl_gb18030_c_tbl_val[i]; + } + } + + /* If we have not yet found a suitable mapping for this codepoint, it requires a 4-byte code */ + if (!s && w >= 0x80 && w <= 0xFFFF) { + /* BMP */ + int i = mbfl_bisec_srch(w, mbfl_uni2gb_tbl, mbfl_gb_uni_max); + if (i >= 0) { + unsigned int c1 = w - mbfl_gb_uni_ofst[i]; + s = (c1 % 10) + 0x30; + c1 /= 10; + s |= ((c1 % 126) + 0x81) << 8; + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x81) << 24; + } + } else if (w >= 0x10000 && w <= 0x10FFFF) { + /* Code set 3: Unicode U+10000-U+10FFFF */ + unsigned int c1 = w - 0x10000; + s = (c1 % 10) + 0x30; + c1 /= 10; + s |= ((c1 % 126) + 0x81) << 8; + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x90) << 24; + } + + if (!s) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_gb18030); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s > 0xFFFFFF) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + out = mb_convert_buf_add4(out, (s >> 24) & 0xFF, (s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_hz.c b/ext/mbstring/libmbfl/filters/mbfilter_hz.c index 3370cd93ef88b..e10109bc33d8f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_hz.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_hz.c @@ -34,6 +34,8 @@ #include "unicode_table_gb2312.h" static int mbfl_filt_conv_hz_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_hz_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_hz(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); const mbfl_encoding mbfl_encoding_hz = { mbfl_no_encoding_hz, @@ -44,8 +46,8 @@ const mbfl_encoding mbfl_encoding_hz = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_hz_wchar, &vtbl_wchar_hz, - NULL, - NULL + mb_hz_to_wchar, + mb_wchar_to_hz }; const struct mbfl_convert_vtbl vtbl_hz_wchar = { @@ -250,3 +252,153 @@ int mbfl_filt_conv_any_hz_flush(mbfl_convert_filter *filter) filter->status = 0; return 0; } + +#define ASCII 0 +#define GB2312 1 + +static size_t mb_hz_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c == '~') { + if (p == e) { + break; + } + unsigned char c2 = *p++; + + if (c2 == '}' && *state == GB2312) { + *state = ASCII; + } else if (c2 == '{' && *state == ASCII) { + *state = GB2312; + } else if (c2 == '~' && *state == ASCII) { + *out++ = '~'; + } else if (c2 == '\n') { + /* "~\n" is a line continuation; no output is needed, nor should we shift modes */ + } else { + /* Invalid character after ~ */ + *out++ = MBFL_BAD_INPUT; + } + } else if (((c > 0x20 && c <= 0x29) || (c >= 0x30 && c <= 0x77)) && p < e && *state == GB2312) { + unsigned char c2 = *p++; + + if (c > 0x20 && c < 0x7F && c2 > 0x20 && c2 < 0x7F) { + unsigned int s = (c - 1)*192 + c2 + 0x40; + ZEND_ASSERT(s < cp936_ucs_table_size); + + if (s == 0x1864) { + s = 0x30FB; + } else if (s == 0x186A) { + s = 0x2015; + } else if (s == 0x186C) { + s = 0x2225; + } else if ((s >= 0x1920 && s <= 0x192A) || s == 0x1963 || (s >= 0x1C60 && s <= 0x1C7F) || (s >= 0x1DBB && s <= 0x1DC4)) { + s = 0; + } else { + s = cp936_ucs_table[s]; + } + if (!s) + s = MBFL_BAD_INPUT; + *out++ = s; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c < 0x80 && *state == ASCII) { + *out++ = c; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_hz(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w == 0xB7 || w == 0x144 || w == 0x148 || w == 0x251 || w == 0x261 || w == 0x2CA || w == 0x2CB || w == 0x2D9) { + s = 0; + } else { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x2015) { + s = 0xA1AA; + } else if (w == 0x2010 || w == 0x2013 || w == 0x2014 || w == 0x2016 || w == 0x2025 || w == 0x2035 || w == 0x2105 || w == 0x2109 || w == 0x2121 || (w >= 0x2170 && w <= 0x2179) || (w >= 0x2196 && w <= 0x2199) || w == 0x2215 || w == 0x221F || w == 0x2223 || w == 0x2252 || w == 0x2266 || w == 0x2267 || w == 0x2295 || (w >= 0x2550 && w <= 0x2573) || w == 0x22BF || w == 0x2609 || (w >= 0x2581 && w <= 0x258F) || (w >= 0x2593 && w <= 0x2595) || w == 0x25BC || w == 0x25BD || (w >= 0x25E2 && w <= 0x25E5)) { + s = 0; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + if (w == 0x30FB) { + s = 0xA1A4; + } else if (w == 0x3006 || w == 0x3007 || w == 0x3012 || w == 0x3231 || w == 0x32A3 || w >= 0x3300 || (w >= 0x3018 && w <= 0x3040) || (w >= 0x309B && w <= 0x309E) || (w >= 0x30FC && w <= 0x30FE)) { + s = 0; + } else { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } + } else if (w >= ucs_i_gb2312_table_min && w < ucs_i_gb2312_table_max) { + s = ucs_i_gb2312_table[w - ucs_i_gb2312_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w == 0xFFE0 || w == 0xFFE1 || w == 0xFFE3 || w == 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + s &= ~0x8080; + + if ((!s && w) || (s >= 0x80 && s < 0x2121)) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_hz); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s < 0x80) { + /* ASCII */ + if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '}'); + buf->state = ASCII; + } + if (s == '~') { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '~'); + } else { + out = mb_convert_buf_add(out, s); + } + } else { + /* GB 2312-80 */ + if (buf->state != GB2312) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '{'); + buf->state = GB2312; + } + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } + } + + if (end && buf->state != ASCII) { + /* If not in ASCII state, need to emit closing control chars */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, 2); + out = mb_convert_buf_add2(out, '~', '}'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_jis.c b/ext/mbstring/libmbfl/filters/mbfilter_jis.c index b175743a4afbe..3b7f1f8586fa0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_jis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_jis.c @@ -36,6 +36,7 @@ static int mbfl_filt_conv_jis_wchar_flush(mbfl_convert_filter *filter); static size_t mb_iso2022jp_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_iso2022jp(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_jis(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); const mbfl_encoding mbfl_encoding_jis = { mbfl_no_encoding_jis, @@ -47,7 +48,7 @@ const mbfl_encoding mbfl_encoding_jis = { &vtbl_jis_wchar, &vtbl_wchar_jis, mb_iso2022jp_to_wchar, - NULL + mb_wchar_to_jis, }; const mbfl_encoding mbfl_encoding_2022jp = { @@ -667,3 +668,86 @@ static void mb_wchar_to_iso2022jp(uint32_t *in, size_t len, mb_convert_buf *buf, MB_CONVERT_BUF_STORE(buf, out, limit); } + +static void mb_wchar_to_jis(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w == 0x203E) { /* OVERLINE */ + s = 0x1007E; /* Convert to JISX 0201 OVERLINE */ + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x1005C; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else if (w != 0) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_iso2022jp); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + continue; + } + } + + if (s < 0x80) { /* ASCII */ + if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s < 0x8080) { /* JIS X 0208 */ + if (buf->state != JISX_0208) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 5); + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } else if (s < 0x10000) { /* JIS X 0212 */ + if (buf->state != JISX_0212) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 6); + out = mb_convert_buf_add4(out, 0x1B, '$', '(', 'D'); + buf->state = JISX_0212; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } else { /* X 0201 Latin */ + if (buf->state != JISX_0201_LATIN) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index c7f5fb2ac04fa..09796390b3df6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -320,10 +320,10 @@ static size_t mb_ucs4_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf return mb_ucs4le_to_wchar(in, in_len, buf, bufsize, NULL); } else if (*in_len >= 4) { unsigned char *p = *in; - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w == 0xFFFE0000) { @@ -349,10 +349,10 @@ static size_t mb_ucs4be_to_wchar(unsigned char **in, size_t *in_len, uint32_t *b uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; *out++ = w; } @@ -393,10 +393,10 @@ static size_t mb_ucs4le_to_wchar(unsigned char **in, size_t *in_len, uint32_t *b uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c4 << 24) | (c3 << 16) | (c2 << 8) | c1; *out++ = w; } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c index e465fbe2b4d4e..bec134aabd2aa 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c @@ -37,6 +37,8 @@ #include "unicode_table_uhc.h" static int mbfl_filt_conv_uhc_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_uhc_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_uhc(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_uhc[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -68,8 +70,8 @@ const mbfl_encoding mbfl_encoding_uhc = { 0, &vtbl_uhc_wchar, &vtbl_wchar_uhc, - NULL, - NULL + mb_uhc_to_wchar, + mb_wchar_to_uhc }; const struct mbfl_convert_vtbl vtbl_uhc_wchar = { @@ -192,3 +194,91 @@ int mbfl_filt_conv_wchar_uhc(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_uhc_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0x80 && c < 0xFE && c != 0xC9 && p < e) { + unsigned char c2 = *p++; + unsigned int w = 0; + + if (c >= 0x81 && c <= 0xA0 && c2 >= 0x41 && c2 <= 0xFE) { + w = (c - 0x81)*190 + (c2 - 0x41); + if (w < uhc1_ucs_table_size) { + w = uhc1_ucs_table[w]; + } + } else if (c >= 0xA1 && c <= 0xC6 && c2 >= 0x41 && c2 <= 0xFE) { + w = (c - 0xA1)*190 + (c2 - 0x41); + if (w < uhc2_ucs_table_size) { + w = uhc2_ucs_table[w]; + } + } else if (c >= 0xC7 && c < 0xFE && c2 >= 0xA1 && c2 <= 0xFE) { + w = (c - 0xC7)*94 + (c2 - 0xA1); + if (w < uhc3_ucs_table_size) { + w = uhc3_ucs_table[w]; + } + } + if (!w) { + w = MBFL_BAD_INPUT; + } + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_uhc(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_uhc_table_min && w < ucs_a1_uhc_table_max) { + s = ucs_a1_uhc_table[w - ucs_a1_uhc_table_min]; + } else if (w >= ucs_a2_uhc_table_min && w < ucs_a2_uhc_table_max) { + s = ucs_a2_uhc_table[w - ucs_a2_uhc_table_min]; + } else if (w >= ucs_a3_uhc_table_min && w < ucs_a3_uhc_table_max) { + s = ucs_a3_uhc_table[w - ucs_a3_uhc_table_min]; + } else if (w >= ucs_i_uhc_table_min && w < ucs_i_uhc_table_max) { + s = ucs_i_uhc_table[w - ucs_i_uhc_table_min]; + } else if (w >= ucs_s_uhc_table_min && w < ucs_s_uhc_table_max) { + s = ucs_s_uhc_table[w - ucs_s_uhc_table_min]; + } else if (w >= ucs_r1_uhc_table_min && w < ucs_r1_uhc_table_max) { + s = ucs_r1_uhc_table[w - ucs_r1_uhc_table_min]; + } else if (w >= ucs_r2_uhc_table_min && w < ucs_r2_uhc_table_max) { + s = ucs_r2_uhc_table[w - ucs_r2_uhc_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_uhc); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index c654e4cf51020..a6594ed75162e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -252,10 +252,10 @@ static size_t mb_utf32_to_wchar(unsigned char **in, size_t *in_len, uint32_t *bu return mb_utf32le_to_wchar(in, in_len, buf, bufsize, NULL); } else if (*in_len >= 4) { unsigned char *p = *in; - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w == 0xFFFE0000) { @@ -281,10 +281,10 @@ static size_t mb_utf32be_to_wchar(unsigned char **in, size_t *in_len, uint32_t * uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w < MBFL_WCSPLANE_UTF32MAX && (w < 0xD800 || w > 0xDFFF)) { @@ -330,10 +330,10 @@ static size_t mb_utf32le_to_wchar(unsigned char **in, size_t *in_len, uint32_t * uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c4 << 24) | (c3 << 16) | (c2 << 8) | c1; if (w < MBFL_WCSPLANE_UTF32MAX && (w < 0xD800 || w > 0xDFFF)) { diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 1c93b77a9533b..f95e3c3dbd5c7 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -1665,7 +1665,7 @@ mime_header_encoder_result(struct mime_header_encoder_data *pe, mbfl_string *res mbfl_memory_device_strncat(&pe->outdev, "\x3f\x3d", 2); /* ?= */ } else if (pe->tmpdev.pos > 0) { if (pe->outdev.pos > 0) { - if ((pe->outdev.pos - pe->linehead + pe->tmpdev.pos) > 74) { + if ((pe->outdev.pos - pe->linehead + pe->tmpdev.pos + pe->firstindent) > 74) { mbfl_memory_device_strncat(&pe->outdev, pe->lwsp, pe->lwsplen); } else { mbfl_memory_device_output(0x20, &pe->outdev); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index bcf2ee51933db..f43a0131f74fd 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3318,6 +3318,8 @@ PHP_FUNCTION(mb_decode_numericentity) /* }}} */ /* {{{ Sends an email message with MIME scheme */ +#define CRLF "\r\n" + static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t str_len) { const char *ps; @@ -3649,7 +3651,7 @@ PHP_FUNCTION(mb_send_mail) || orig_str.encoding->no_encoding == mbfl_no_encoding_pass) { orig_str.encoding = mbfl_identify_encoding(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection)); } - pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, "\n", sizeof("Subject: [PHP-jp nnnnnnnn]")); + pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, CRLF, sizeof("Subject: [PHP-jp nnnnnnnn]" CRLF) - 1); if (pstr != NULL) { subject_buf = subject = (char *)pstr->val; } @@ -3688,14 +3690,14 @@ PHP_FUNCTION(mb_send_mail) n = ZSTR_LEN(str_headers); mbfl_memory_device_strncat(&device, p, n); if (n > 0 && p[n - 1] != '\n') { - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } zend_string_release_ex(str_headers, 0); } if (!zend_hash_str_exists(&ht_headers, "mime-version", sizeof("mime-version") - 1)) { mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER1, sizeof(PHP_MBSTR_MAIL_MIME_HEADER1) - 1); - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } if (!suppressed_hdrs.cnt_type) { @@ -3706,7 +3708,7 @@ PHP_FUNCTION(mb_send_mail) mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER3, sizeof(PHP_MBSTR_MAIL_MIME_HEADER3) - 1); mbfl_memory_device_strcat(&device, p); } - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } if (!suppressed_hdrs.cnt_trans_enc) { mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER4, sizeof(PHP_MBSTR_MAIL_MIME_HEADER4) - 1); @@ -3715,9 +3717,10 @@ PHP_FUNCTION(mb_send_mail) p = "7bit"; } mbfl_memory_device_strcat(&device, p); - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } + mbfl_memory_device_unput(&device); mbfl_memory_device_unput(&device); mbfl_memory_device_output('\0', &device); str_headers = zend_string_init((char *)device.buffer, strlen((char *)device.buffer), 0); @@ -3754,6 +3757,7 @@ PHP_FUNCTION(mb_send_mail) } } +#undef CRLF #undef MAIL_ASCIIZ_CHECK_MBSTRING #undef PHP_MBSTR_MAIL_MIME_HEADER1 #undef PHP_MBSTR_MAIL_MIME_HEADER2 diff --git a/ext/mbstring/tests/bug52681.phpt b/ext/mbstring/tests/bug52681.phpt index 2086051e9412d..86295d3385dcd 100644 --- a/ext/mbstring/tests/bug52681.phpt +++ b/ext/mbstring/tests/bug52681.phpt @@ -4,15 +4,12 @@ Bug #52681 (mb_send_mail() appends an extra MIME-Version header) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/bug52681.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com diff --git a/ext/mbstring/tests/cp5022x_encoding.phpt b/ext/mbstring/tests/cp5022x_encoding.phpt index 11a4855462a84..cde33e85cc670 100644 --- a/ext/mbstring/tests/cp5022x_encoding.phpt +++ b/ext/mbstring/tests/cp5022x_encoding.phpt @@ -365,6 +365,11 @@ foreach (['CP50220', 'CP50221', 'CP50222'] as $encoding) { } echo "Invalid escape sequences OK\n"; + +// Regression test +if (mb_convert_encoding("\x1BC\xF5", 'UTF-16BE', 'CP50221') !== "\x00%\x00C\x00%") + die("Bad") + ?> --EXPECT-- ASCII support OK diff --git a/ext/mbstring/tests/gh7902.phpt b/ext/mbstring/tests/gh7902.phpt new file mode 100644 index 0000000000000..d9a0fced7913d --- /dev/null +++ b/ext/mbstring/tests/gh7902.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-7902 (mb_send_mail may delimit headers with LF only) +--SKIPIF-- + +--INI-- +sendmail_path={MAIL:{PWD}/gh7902.eml} +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(0) diff --git a/ext/mbstring/tests/gh8208.phpt b/ext/mbstring/tests/gh8208.phpt new file mode 100644 index 0000000000000..06a490310da02 --- /dev/null +++ b/ext/mbstring/tests/gh8208.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-8208 (mb_encode_mimeheader: $indent functionality broken) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +string(84) "Subject: [service-Aufgaben S&W-Team][#19415] VM''s aufsetzen mit + unterschiedlichen" +string(84) "Subject: [service-Aufgaben S&W-Team][#19415] VM''s aufsetzen mit + unterschiedlichen" diff --git a/ext/mbstring/tests/hz_encoding.phpt b/ext/mbstring/tests/hz_encoding.phpt index 665980c9c7f16..a763fe828563f 100644 --- a/ext/mbstring/tests/hz_encoding.phpt +++ b/ext/mbstring/tests/hz_encoding.phpt @@ -118,6 +118,18 @@ while (!empty($badChars)) { echo "Tested UTF-16BE -> HZ (for all GB2312 characters)\n"; +// Regression tests +if (mb_convert_encoding("\x7A\xFA\x00\x00", 'HZ', 'UTF-16BE') !== "~{\x73\x43~}\x00") + die("Bad"); +if (mb_convert_encoding("~", 'UTF-16BE', 'HZ') !== "") + die("Bad"); +// There had once been a bug whereby the output buffer would be overrun by one byte. +// It was found by fuzzing. Reproducing it required a string which was long enough +// and had a GB2312 character at the end. +$str = "\xD9\x96C\xA7\x1B\xF6\xD8\x86\x94\xB0\xA0\xE1\x9D\x8C\xF8G\xBBMk\xD2Y\tt\xF1\x96d\x17JA\xF9\xF8\xCF\xDC\xFE\x8E\x0E\xC1\x84\xDA\xDBM\xC1\x87\x1AZ\xD5\xA6)\xFF%2\\\xCC\x02\x16]Y\xF0\x00\xEA\xE8{)\x81\xD5VQZ\x12\xB5\xBC\x9A\x91\xA0x\x02\xBA\xF6c\xACo\x9BH\xB7qx\xF5\x0F\t\x15\xDByx\xBA[\xC9\xE8r\xCD*:\xBF\x10P\xF1>Q\x07\xEE\xE5\x80\xAD\xB9\xA2\x9B\xF6\xE1,\x82\xC6q\x94E\xD4\x0B\xC6\xBCQe=\xC3\xE0\xC8\xE0R\x97\x14q\x0C\x1A\x7F\xE1\xC4\xB8U\x8A\x86\x93\xB6/\x84\x95\x06\x91W\xB2\xB6\x1F!\t X\x1A\xD5\xD6\xDA<\x81ib\x9A\x1B3\xD3\xB7:\xE2QS\xD0\x91\x99[K\xF2E\xBBjoh_5\x15 \xA4\xCC\xB0\x7F\x06\xB3,\xB3\xA7u\xB9\x82\x00\xE2f$\x1C\x84NsP\xFAiPB{\x8D\xBA\xB3[\x88\xA9\xB1\xA2r\x86\xFF<\xFD\xFB\xF8\xD6\xABq\x00z\xFA\x87\x8C_\xD9N\xF2\xFA\xEA\xEA\xAA\xD7\xFA\xA2\xD4\x85/\xFC\xE1}\xF7\x9C\x86\xDD\x12@\xC3\xDA\nC\x1Di\xA9\xB0\xC3\xB3\x04\xB2\x1A\x07BA\x02\xED\x11\xA4\xDAz\x96\xB5\xD0!p\xE2\xAD\xEDI\xEF\xF7\\\x05d.p\x07\xC4\x8B\x952\xCDz\x90\x8C\xA6U\xDB\xC7\xF4\x94\xE9\x16X\xF1\xCC\xB13\x07a9\x86]\xF9k\xA9\x87E\xCB\x89\x9Fd\x0E\x81m\xC6c\xDA\x9C\xE9\xAF\x80.\xFAq\xD9\xAAd\x1DB\x1F\x854\xE8\x82v)A\xF3\xB4\x1D\xE5\xF0\xFFu\x0E\x0C\xC4q\xF0\xE7\xB4p\x86\xE6]9\xD9\xA5O\xBAw\x1B\x8D&]\x9D\xE2\x0F\xD2\xD5\x13AY#\x81\x90\xB2\xE8\xDA\xD2\xFC>\xA0\x9A\xBD\x0B\xCC\x08>\x1E\xD1\xFEgr1'$\xEE\xA2!\x8A\xBB>\x11j#Pz_!?\xA8\x15\xCF\xCB\x84\x86\xC1\xF78:\xDA\xBCE\xA7\x02SO\x8B\x81>\x96\xBD\xFD2\x84\xC5\xFC\x19\xE5\xF4\xEFp\xF08K\xBB\xAE-[}\xE1\xDB\x8A%6\xC7\xC9"; +if (substr(mb_convert_encoding($str, 'HZ', 'CP51932'), -4) !== "\x45\x49~}") + die("Bad"); + // Test "long" illegal character markers mb_substitute_character("long"); convertInvalidString("~A", "%", "HZ", "UTF-8"); diff --git a/ext/mbstring/tests/mb_send_mail01.phpt b/ext/mbstring/tests/mb_send_mail01.phpt index a71e212543624..4387d9f817433 100644 --- a/ext/mbstring/tests/mb_send_mail01.phpt +++ b/ext/mbstring/tests/mb_send_mail01.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 1 (lang=neutral) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail01.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail02.phpt b/ext/mbstring/tests/mb_send_mail02.phpt index 13f9dd0974775..edc4093825af6 100644 --- a/ext/mbstring/tests/mb_send_mail02.phpt +++ b/ext/mbstring/tests/mb_send_mail02.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 2 (lang=Japanese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail02.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail03.phpt b/ext/mbstring/tests/mb_send_mail03.phpt index 124c94834e6cb..53cbf00a60f19 100644 --- a/ext/mbstring/tests/mb_send_mail03.phpt +++ b/ext/mbstring/tests/mb_send_mail03.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 3 (lang=English) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail03.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail04.phpt b/ext/mbstring/tests/mb_send_mail04.phpt index bf5bfef578bd0..2251771469e16 100644 --- a/ext/mbstring/tests/mb_send_mail04.phpt +++ b/ext/mbstring/tests/mb_send_mail04.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 4 (lang=German) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail04.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail05.phpt b/ext/mbstring/tests/mb_send_mail05.phpt index b03ce8748e61f..251b918bdb85b 100644 --- a/ext/mbstring/tests/mb_send_mail05.phpt +++ b/ext/mbstring/tests/mb_send_mail05.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 5 (lang=Simplified Chinese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail05.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail06.phpt b/ext/mbstring/tests/mb_send_mail06.phpt index 2a81a4a482115..d2fd7a9bbf3ab 100644 --- a/ext/mbstring/tests/mb_send_mail06.phpt +++ b/ext/mbstring/tests/mb_send_mail06.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 6 (lang=Traditional Chinese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail06.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail07.phpt b/ext/mbstring/tests/mb_send_mail07.phpt index 56368942cfd13..662426a47d833 100644 --- a/ext/mbstring/tests/mb_send_mail07.phpt +++ b/ext/mbstring/tests/mb_send_mail07.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 7 (lang=Korean) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail07.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/other_encodings.phpt b/ext/mbstring/tests/other_encodings.phpt index 2845fe6ca6d05..14b63fc809f88 100644 --- a/ext/mbstring/tests/other_encodings.phpt +++ b/ext/mbstring/tests/other_encodings.phpt @@ -14,10 +14,11 @@ mb_substitute_character(0x25); var_dump(mb_convert_encoding("ABC", "7bit", "ASCII")); var_dump(mb_convert_encoding("\x80", "7bit", "ASCII")); var_dump(mb_convert_encoding("ABC", "8bit", "7bit")); +var_dump(mb_check_encoding(chr(255), '7bit')); echo "7bit done\n"; // "8bit" -var_dump(mb_convert_encoding("\x01\x00", "8bit", "UTF-16BE")); // codepoints over 0xFF are illegal or '8-bit' +var_dump(mb_convert_encoding("\x01\x00", "8bit", "UTF-16BE")); // codepoints over 0xFF are illegal for '8-bit' echo "8bit done\n"; ?> @@ -25,6 +26,7 @@ echo "8bit done\n"; string(3) "ABC" string(1) "%" string(3) "ABC" +bool(false) 7bit done string(1) "%" 8bit done diff --git a/ext/mbstring/tests/uhc_encoding.phpt b/ext/mbstring/tests/uhc_encoding.phpt index cc4d72f9f11ea..622569c68c699 100644 --- a/ext/mbstring/tests/uhc_encoding.phpt +++ b/ext/mbstring/tests/uhc_encoding.phpt @@ -11,6 +11,9 @@ if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); include('encoding_tests.inc'); testEncodingFromUTF16ConversionTable(__DIR__ . '/data/CP949.txt', 'UHC'); +// Regression test +convertInvalidString("\xE4\xA4\xB4<", "\x75\x1A\x00%", "UHC", "UTF-16BE"); + // Test "long" illegal character markers mb_substitute_character("long"); convertInvalidString("\x80", "%", "UHC", "UTF-8"); diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 58ee1e7b564da..e53801572f7df 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -980,8 +980,12 @@ PHP_METHOD(mysqli_result, __construct) } if (!result) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql)); + } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)result; @@ -1135,11 +1139,13 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags ZVAL_COPY_VALUE(&dataset, return_value); object_init_ex(return_value, ce); + HashTable *prop_table = zend_symtable_to_proptable(Z_ARR(dataset)); + zval_ptr_dtor(&dataset); if (!ce->default_properties_count && !ce->__set) { - Z_OBJ_P(return_value)->properties = Z_ARR(dataset); + Z_OBJ_P(return_value)->properties = prop_table; } else { - zend_merge_properties(return_value, Z_ARRVAL(dataset)); - zval_ptr_dtor(&dataset); + zend_merge_properties(return_value, prop_table); + zend_array_release(prop_table); } if (ce->constructor) { diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index e0c46a5427bcb..5add2523c54b9 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -4,10 +4,13 @@ final class mysqli_driver { + /** @readonly */ public string $client_info; + /** @readonly */ public int $client_version; + /** @readonly */ public int $driver_version; public bool $reconnect = false; @@ -17,40 +20,58 @@ final class mysqli_driver class mysqli { + /** @link mysqli.affected-rows */ public int|string $affected_rows; + /** @link mysqli.get-client-info */ public string $client_info; + /** @link mysqli.get-client-version */ public int $client_version; + /** @link mysqli.connect-errno */ public int $connect_errno; + /** @link mysqli.connect-error */ public ?string $connect_error; + /** @link mysqli.errno */ public int $errno; + /** @link mysqli.error */ public string $error; + /** @link mysqli.error-list */ public array $error_list; + /** @link mysqli.field-count */ public int $field_count; + /** @link mysqli.get-host-info */ public string $host_info; + /** @link mysqli.info */ public ?string $info; + /** @link mysqli.insert-id */ public int|string $insert_id; + /** @link mysqli.get-server-info */ public string $server_info; + /** @link mysqli.get-server-version */ public int $server_version; + /** @link mysqli.sqlstate */ public string $sqlstate; + /** @link mysqli.get-proto-info */ public int $protocol_version; + /** @link mysqli.thread-id */ public int $thread_id; + /** @link mysqli.warning-count */ public int $warning_count; public function __construct( @@ -352,12 +373,16 @@ public function refresh(int $flags): bool {} class mysqli_result implements IteratorAggregate { + /** @link mysqli-result.current-field */ public int $current_field; + /** @link mysqli-result.field-count */ public int $field_count; + /** @link mysqli-result.lengths */ public ?array $lengths; + /** @link mysqli-result.num-rows */ public int|string $num_rows; public int $type; @@ -455,22 +480,31 @@ public function getIterator(): Iterator {} class mysqli_stmt { + /** @link mysqli-stmt.affected-rows */ public int|string $affected_rows; + /** @link mysqli-stmt.insert-id */ public int|string $insert_id; + /** @link mysqli-stmt.num-rows */ public int|string $num_rows; + /** @link mysqli-stmt.param-count */ public int $param_count; + /** @link mysqli-stmt.field-count */ public int $field_count; + /** @link mysqli-stmt.errno */ public int $errno; + /** @link mysqli-stmt.error */ public string $error; + /** @link mysqli-stmt.error-list */ public array $error_list; + /** @link mysqli-stmt.sqlstate */ public string $sqlstate; public int $id; @@ -613,6 +647,8 @@ public function next(): bool {} final class mysqli_sql_exception extends RuntimeException { protected string $sqlstate = "00000"; + + public function getSqlState(): string {} } /** @refcount 1 */ diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4cd285e347f47..b01179089a507 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: e9f4dd04e7d01864c38033bcaf5e03b63e191deb */ + * Stub hash: 7901d2cbbf9663f2c0cc140870baed0fe04c2bd1 */ 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) @@ -720,6 +720,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_mysqli_warning_next arginfo_mysqli_thread_safe +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_sql_exception_getSqlState, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_FUNCTION(mysqli_affected_rows); ZEND_FUNCTION(mysqli_autocommit); @@ -842,6 +845,7 @@ ZEND_METHOD(mysqli_result, getIterator); ZEND_METHOD(mysqli_stmt, __construct); ZEND_METHOD(mysqli_warning, __construct); ZEND_METHOD(mysqli_warning, next); +ZEND_METHOD(mysqli_sql_exception, getSqlState); static const zend_function_entry ext_functions[] = { @@ -1083,6 +1087,7 @@ static const zend_function_entry class_mysqli_warning_methods[] = { static const zend_function_entry class_mysqli_sql_exception_methods[] = { + ZEND_ME(mysqli_sql_exception, getSqlState, arginfo_class_mysqli_sql_exception_getSqlState, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index 3bc80807a7e98..3d15881863e24 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -63,3 +63,17 @@ void php_mysqli_throw_sql_exception(char *sqlstate, int errorno, char *format, . zend_throw_exception_object(&sql_ex); } + +PHP_METHOD(mysqli_sql_exception, getSqlState) +{ + zval *prop; + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + prop = zend_read_property(mysqli_exception_class_entry, Z_OBJ_P(ZEND_THIS), "sqlstate", sizeof("sqlstate")-1, 1, &rv); + ZVAL_DEREF(prop); + zend_string *str = zval_get_string(prop); + + RETURN_STR(str); +} diff --git a/ext/mysqli/tests/014.phpt b/ext/mysqli/tests/014.phpt index 7da7765de9187..36e61b64e1ec2 100644 --- a/ext/mysqli/tests/014.phpt +++ b/ext/mysqli/tests/014.phpt @@ -4,19 +4,18 @@ mysqli autocommit/commit/rollback mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) { + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +} ?> --FILE-- --CLEAN-- --EXPECT-- Num_of_rows=1 diff --git a/ext/mysqli/tests/015.phpt b/ext/mysqli/tests/015.phpt index f9adb2fe2b0b3..9726afe780230 100644 --- a/ext/mysqli/tests/015.phpt +++ b/ext/mysqli/tests/015.phpt @@ -4,18 +4,18 @@ mysqli autocommit/commit/rollback with innodb mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) { + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +} ?> --FILE-- --CLEAN-- --EXPECT-- array(2) { diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index 7db4a2a1bbcf2..213b27137dd07 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -4,9 +4,8 @@ mysqli_stmt_bind_result (SHOW) mysqli --SKIPIF-- --FILE-- --CLEAN-- --FILE-- real_connect($host, $user, $passwd, $db, $port, $socket); @@ -53,7 +52,7 @@ print "done!"; ?> --CLEAN-- errno, $link->error)); @@ -23,7 +23,7 @@ mysqli.allow_persistent=1 mysqli.max_persistent=1 --FILE-- --CLEAN-- --EXPECT-- array(2) { diff --git a/ext/mysqli/tests/bug51647.phpt b/ext/mysqli/tests/bug51647.phpt index 3e1e15a6e7a1d..38515245e7b0e 100644 --- a/ext/mysqli/tests/bug51647.phpt +++ b/ext/mysqli/tests/bug51647.phpt @@ -4,8 +4,7 @@ Bug #51647 (Certificate file without private key (pk in another file) doesn't wo mysqli --SKIPIF-- close(); ?> --FILE-- errno, $link->error)); mysqli_close($link); - ?> --INI-- mysqli.allow_local_infile=1 --FILE-- --CLEAN-- --FILE-- --FILE-- --FILE-- errno, $link->error)); diff --git a/ext/mysqli/tests/bug69899.phpt b/ext/mysqli/tests/bug69899.phpt index 6585f1048409b..66f997a4d3408 100644 --- a/ext/mysqli/tests/bug69899.phpt +++ b/ext/mysqli/tests/bug69899.phpt @@ -11,7 +11,6 @@ mysqli --SKIPIF-- server_version < 50709) { - die("skip MySQL 5.7.9+ needed. Found [". - intval(substr($link->server_version."", -5, 1)). - ".". - intval(substr($link->server_version."", -4, 2)). - ".". - intval(substr($link->server_version."", -2, 2)). - "]"); - } - } +require_once 'connect.inc'; +if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); +} + +if ($link->server_version < 50709) { + die("skip MySQL 5.7.9+ needed. Found [". + intval(substr($link->server_version."", -5, 1)). + ".". + intval(substr($link->server_version."", -4, 2)). + ".". + intval(substr($link->server_version."", -2, 2)). + "]"); +} ?> --FILE-- --CLEAN-- --EXPECT-- OK diff --git a/ext/mysqli/tests/bug70949.phpt b/ext/mysqli/tests/bug70949.phpt index 567b1131efdd3..995511e1c6624 100644 --- a/ext/mysqli/tests/bug70949.phpt +++ b/ext/mysqli/tests/bug70949.phpt @@ -4,15 +4,14 @@ Bug #70949 (SQL Result Sets With NULL Can Cause Fatal Memory Errors) mysqli --SKIPIF-- --FILE-- query("DROP TABLE IF EXISTS bug70949"); @@ -47,7 +46,7 @@ if ($stmt = $mysql->prepare($sql)) ?> --CLEAN-- --FILE-- --CLEAN-- = 5.6.4. */ if (mysqli_get_server_version($link) < 50604) { @@ -18,7 +18,7 @@ mysqli_close($link); ?> --FILE-- query('DROP TABLE IF EXISTS ts_test;'); @@ -96,7 +96,7 @@ string(13) "11:00:00.4444" string(15) "11:00:00.006054" --CLEAN-- query('DROP TABLE ts_test;'); $link->query('DROP TABLE t_test;'); diff --git a/ext/mysqli/tests/bug77956.phpt b/ext/mysqli/tests/bug77956.phpt index 8a579c0657d12..53c25c09697ce 100644 --- a/ext/mysqli/tests/bug77956.phpt +++ b/ext/mysqli/tests/bug77956.phpt @@ -4,17 +4,18 @@ ensure an error is returned when mysqli.allow_local_infile is off mysqli --SKIPIF-- errno, $link->error)); +mysqli_close($link); ?> --INI-- mysqli.allow_local_infile=0 diff --git a/ext/mysqli/tests/clean_table.inc b/ext/mysqli/tests/clean_table.inc index 229b42f5eddcc..2b03fc6fb2600 100644 --- a/ext/mysqli/tests/clean_table.inc +++ b/ext/mysqli/tests/clean_table.inc @@ -1,5 +1,5 @@ sqlstate is inaccessible +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query("stuff"); +} catch (mysqli_sql_exception $exception) { + var_dump($exception->getSqlState()); +} + +?> +--EXPECT-- +string(5) "42000" diff --git a/ext/mysqli/tests/gh7837.phpt b/ext/mysqli/tests/gh7837.phpt new file mode 100644 index 0000000000000..710d1ef5a4b55 --- /dev/null +++ b/ext/mysqli/tests/gh7837.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug GH-7837 (large bigints may be truncated) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); +$mysql->query("DROP TABLE IF EXISTS test"); +$mysql->query("CREATE TABLE test (`ubigint` bigint unsigned NOT NULL) ENGINE=InnoDB"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (18446744073709551615)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (9223372036854775808)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (1)"); +$result = $mysql->query("SELECT ubigint FROM test"); +var_dump($result->fetch_all()); +?> +--CLEAN-- + +--EXPECT-- +array(3) { + [0]=> + array(1) { + [0]=> + string(20) "18446744073709551615" + } + [1]=> + array(1) { + [0]=> + string(19) "9223372036854775808" + } + [2]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/ext/mysqli/tests/gh7932.phpt b/ext/mysqli/tests/gh7932.phpt new file mode 100644 index 0000000000000..cc0317c314c46 --- /dev/null +++ b/ext/mysqli/tests/gh7932.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-7972 (MariaDB version prefix not always stripped) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +server_info, '5.5.5-')) { + print("Expecting stripped prefix. Found: " . $mysqli->server_info . "\n"); +} +?> +--EXPECT-- diff --git a/ext/mysqli/tests/gh8058.phpt b/ext/mysqli/tests/gh8058.phpt new file mode 100644 index 0000000000000..5480682e93fae --- /dev/null +++ b/ext/mysqli/tests/gh8058.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-8058 (NULL pointer dereference in mysqlnd package (#81706)) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +prepare("select 1,2,3"); +$stmt->bind_result($a,$a,$a); +$stmt->prepare(""); +$stmt->prepare("select ".str_repeat("'A',", 0x1201)."1"); +unset($stmt); // trigger dtor + +// There should be no memory leak +$stmt = $mysqli->prepare("select 1,2,3"); +$stmt->bind_result($a,$a,$a); +$stmt->prepare(""); +$stmt->prepare("select 1"); +unset($stmt); // trigger dtor + +mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); +$stmt = $mysqli->prepare("select 1,2,3"); +try { + // We expect an exception to be thrown + $stmt->prepare(""); +} catch (mysqli_sql_exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECT-- +string(15) "Query was empty" diff --git a/ext/mysqli/tests/gh8068.phpt b/ext/mysqli/tests/gh8068.phpt new file mode 100644 index 0000000000000..5d7f55c9c4d40 --- /dev/null +++ b/ext/mysqli/tests/gh8068.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-8068 (mysqli_fetch_object creates inaccessible properties) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query('SELECT 42'); +$obj = $res->fetch_object(); +var_dump( + $obj, + $obj->{42} +); +?> +--EXPECT-- +object(stdClass)#4 (1) { + ["42"]=> + string(2) "42" +} +string(2) "42" diff --git a/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt b/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt index 963603515400d..627c76ec539c3 100644 --- a/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt +++ b/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt @@ -4,17 +4,17 @@ mysqli.allow_local_infile overrides mysqli.local_infile_directory mysqli --SKIPIF-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} diff --git a/ext/mysqli/tests/mysqli_autocommit.phpt b/ext/mysqli/tests/mysqli_autocommit.phpt index 0b410f1f05243..0da4e488e641f 100644 --- a/ext/mysqli/tests/mysqli_autocommit.phpt +++ b/ext/mysqli/tests/mysqli_autocommit.phpt @@ -4,10 +4,9 @@ mysqli_autocommit() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_autocommit_oo.phpt b/ext/mysqli/tests/mysqli_autocommit_oo.phpt index 6510c62ccbecf..0c0dbee834f34 100644 --- a/ext/mysqli/tests/mysqli_autocommit_oo.phpt +++ b/ext/mysqli/tests/mysqli_autocommit_oo.phpt @@ -4,13 +4,10 @@ mysqli->autocommit() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- my_mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt index c82b2c7fa0527..1e75ccc390402 100644 --- a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt @@ -4,8 +4,7 @@ mysqli_change_user() - LAST_INSERT_ID() - http://bugs.mysql.com/bug.php?id=45184 mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_change_user_new.phpt b/ext/mysqli/tests/mysqli_change_user_new.phpt index acf86ab517d33..d6a9a3bd137c4 100644 --- a/ext/mysqli/tests/mysqli_change_user_new.phpt +++ b/ext/mysqli/tests/mysqli_change_user_new.phpt @@ -4,9 +4,9 @@ mysqli_change_user(), MySQL 5.6+ mysqli --SKIPIF-- = 10_00_00) ?> --FILE-- change_user() mysqli --SKIPIF-- 50100)) { die("skip Your MySQL Server version has a known bug that will cause a crash"); } @@ -16,7 +16,7 @@ if (mysqli_get_server_version($link) >= 50600) ?> --FILE-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_change_user_set_names.phpt b/ext/mysqli/tests/mysqli_change_user_set_names.phpt index e09c7801b90ea..85c37b8a60157 100644 --- a/ext/mysqli/tests/mysqli_change_user_set_names.phpt +++ b/ext/mysqli/tests/mysqli_change_user_set_names.phpt @@ -4,10 +4,10 @@ mysqli_change_user() - SET NAMES mysqli --SKIPIF-- --FILE-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt index 56c90b866bfdc..fd4c1bbf008c6 100644 --- a/ext/mysqli/tests/mysqli_commit_oo.phpt +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -4,18 +4,16 @@ mysqli_commit() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECTF-- mysqli object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_connect_attr.phpt b/ext/mysqli/tests/mysqli_connect_attr.phpt index eadf7b0fa0da7..75de208c4c5a2 100644 --- a/ext/mysqli/tests/mysqli_connect_attr.phpt +++ b/ext/mysqli/tests/mysqli_connect_attr.phpt @@ -4,13 +4,13 @@ mysqli check the session_connect_attrs table for connection attributes mysqli --SKIPIF-- --FILE-- --FILE-- +--CLEAN-- + --EXPECT-- string(32) "t:O,/tmp/mysqli_debug_phpt.trace" done! diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index c252e645dc9c9..00a460a410e1f 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -4,8 +4,7 @@ mysqli_debug() - mysqlnd only control strings mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt index f651e573e3032..e920a7fffb081 100644 --- a/ext/mysqli/tests/mysqli_explain_metadata.phpt +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -4,15 +4,13 @@ EXPLAIN - metadata mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index cc92737f81ec5..3e2bfea66aee4 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -4,17 +4,16 @@ mysqli_fetch_assoc() - BIT mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt index a100057c86988..e2334fa7ece86 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt @@ -4,11 +4,10 @@ mysqli_fetch_assoc() - utf8 mysqli --SKIPIF-- --FILE-- +--CLEAN-- + --EXPECTF-- [003] array(3) { diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt index 031e5af6725b9..9874fff49f8ea 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -4,11 +4,9 @@ mysqli_fetch_field() - flags/field->flags mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index 599376d0b9c26..411b129387532 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -4,7 +4,6 @@ Forking a child and using the same connection. mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --FILE-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt index 9cd13d27c7c8c..d8d210eee12cf 100644 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_get_warnings.phpt @@ -4,14 +4,13 @@ mysqli_get_warnings() - TODO mysqli --SKIPIF-- --FILE-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} @@ -22,7 +22,7 @@ mysqli.allow_local_infile=0 mysqli.local_infile_directory={PWD}/foo --FILE-- --CLEAN-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} @@ -22,7 +22,7 @@ mysqli.allow_local_infile=0 mysqli.local_infile_directory={PWD}/foo/bar --FILE-- --CLEAN-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt index be8c3aafa2e8f..472f88f97e860 100644 --- a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -4,8 +4,7 @@ mysqlnd.net_read_timeout limit check mysqli --SKIPIF-- default_socket_timeout mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_pam_sha256.phpt b/ext/mysqli/tests/mysqli_pam_sha256.phpt index 625e20ad4237e..5dc2ca8230eed 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256.phpt @@ -4,8 +4,6 @@ PAM: SHA-256 mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); ?> diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt index 94db7fabe406c..42a9640f1ea99 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, mysqlnd.sha256_server_public_key mysqli --SKIPIF-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = "test_sha256_ini"; diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt index 497a7300ca60b..e0abe65e24e44 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd")); diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt index 3c6b53d43a7a2..5f13fa4f03f07 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY (invalid) mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd")); diff --git a/ext/mysqli/tests/mysqli_pconn_kill.phpt b/ext/mysqli/tests/mysqli_pconn_kill.phpt index d53ed44995919..17af4fa42ec93 100644 --- a/ext/mysqli/tests/mysqli_pconn_kill.phpt +++ b/ext/mysqli/tests/mysqli_pconn_kill.phpt @@ -4,16 +4,14 @@ Killing a persistent connection. mysqli --SKIPIF-- --INI-- mysqli.allow_persistent=1 mysqli.max_persistent=2 --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_pconn_limits.phpt b/ext/mysqli/tests/mysqli_pconn_limits.phpt index 4dd65c18a1dd2..4d9f8eed01cad 100644 --- a/ext/mysqli/tests/mysqli_pconn_limits.phpt +++ b/ext/mysqli/tests/mysqli_pconn_limits.phpt @@ -4,8 +4,7 @@ Persistent connections - limits (-1, unlimited) mysqli --SKIPIF-- --INI-- mysqli.allow_persistent=1 @@ -13,9 +12,7 @@ mysqli.max_persistent=-1 mysqli.max_links=-1 --FILE-- --CLEAN-- --EXPECT-- Regular connection 1 - 'works..' diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt index 359c26565f216..836870aeb7fb0 100644 --- a/ext/mysqli/tests/mysqli_poll_reference.phpt +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -4,13 +4,13 @@ mysqli_poll() & references mysqli --SKIPIF-- --FILE-- --FILE-- --CLEAN-- --FILE-- @@ -15,7 +14,7 @@ mysqli.allow_persistent=1 mysqli.max_persistent=10 --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d diff --git a/ext/mysqli/tests/mysqli_reconnect.phpt b/ext/mysqli/tests/mysqli_reconnect.phpt index 6cb13c5e36030..f5f2aca11bf6a 100644 --- a/ext/mysqli/tests/mysqli_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_reconnect.phpt @@ -4,16 +4,15 @@ Trying implicit reconnect after wait_timeout and KILL using mysqli_ping() mysqli --SKIPIF-- --INI-- mysqli.reconnect=1 --FILE-- +--CLEAN-- + --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index 64716524c3684..ec969f15cdad7 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -4,20 +4,16 @@ mysqli_release_savepoint() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli_release_savepoint(): Argument #2 ($name) cannot be empty diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index cb4010d0a87ec..110d25726cdbd 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -4,12 +4,10 @@ mysqli_report() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_multi_query(): (%d/%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 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_report_new.phpt b/ext/mysqli/tests/mysqli_report_new.phpt index 9ef80da1d865c..e544bcb3664d6 100644 --- a/ext/mysqli/tests/mysqli_report_new.phpt +++ b/ext/mysqli/tests/mysqli_report_new.phpt @@ -4,9 +4,9 @@ mysqli_report(), change user, MySQL 5.6+ mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d diff --git a/ext/mysqli/tests/mysqli_report_wo_ps.phpt b/ext/mysqli/tests/mysqli_report_wo_ps.phpt index f030051dd5fc1..c757de773db50 100644 --- a/ext/mysqli/tests/mysqli_report_wo_ps.phpt +++ b/ext/mysqli/tests/mysqli_report_wo_ps.phpt @@ -4,9 +4,9 @@ mysqli_report(), MySQL < 5.6 mysqli --SKIPIF-- = 50600) ?> --FILE-- = 50600) if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_OFF))) printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - require('table.inc'); + require 'table.inc'; /* Internal macro MYSQL_REPORT_ERROR @@ -106,7 +101,7 @@ if (mysqli_get_server_version($link) >= 50600) ?> --CLEAN-- --EXPECTF-- Warning: mysqli_multi_query(): (%d/%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 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt index 61a60cb68735b..3a77078c69c58 100644 --- a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt @@ -4,15 +4,13 @@ References to result sets - mysqlnd (no copies but references) mysqli --SKIPIF-- --FILE-- +--CLEAN-- + --EXPECTF-- array(1) refcount(%d){ [0]=> diff --git a/ext/mysqli/tests/mysqli_rollback.phpt b/ext/mysqli/tests/mysqli_rollback.phpt index 0978308e8c3d3..2297a3351acba 100644 --- a/ext/mysqli/tests/mysqli_rollback.phpt +++ b/ext/mysqli/tests/mysqli_rollback.phpt @@ -4,18 +4,16 @@ mysqli_rollback() mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index a34c1aaee1366..71e0b2d21819e 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -4,18 +4,16 @@ mysqli_savepoint() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli_savepoint(): Argument #2 ($name) cannot be empty diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 075e193959e48..5ddc2f4aa8930 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -4,14 +4,12 @@ mysqli_set_charset() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Exception: %s diff --git a/ext/mysqli/tests/mysqli_ssl_set.phpt b/ext/mysqli/tests/mysqli_ssl_set.phpt index 6abc84fb341b5..5ea79b964987c 100644 --- a/ext/mysqli/tests/mysqli_ssl_set.phpt +++ b/ext/mysqli/tests/mysqli_ssl_set.phpt @@ -4,13 +4,15 @@ mysqli_ssl_set() - test is a stub! mysqli --SKIPIF-- --FILE-- --FILE-- --CLEAN-- --EXPECT-- mysqli_stmt object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt index c7269e8cb47d6..3af364dfb550a 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt @@ -4,10 +4,9 @@ mysqli_stmt_execute() - Stored Procedures mysqli --SKIPIF-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt index 64a1b86340bf7..c3a68db0797df 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt @@ -4,20 +4,23 @@ Fetching BIT column values using the PS API mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt index 0dadb7bb4a1df..e372977844bba 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt @@ -4,11 +4,9 @@ mysqli_stmt_get_warnings() - TODO mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- mysqli_stmt object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_stmt_multires.phpt b/ext/mysqli/tests/mysqli_stmt_multires.phpt index 496fca4e4f6c3..7018a8b63e4f0 100644 --- a/ext/mysqli/tests/mysqli_stmt_multires.phpt +++ b/ext/mysqli/tests/mysqli_stmt_multires.phpt @@ -4,16 +4,14 @@ Multiple result set with PS mysqli --SKIPIF-- --FILE-- query('DROP PROCEDURE IF EXISTS p123')) { diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt index 21b0e4625dd32..57e371f360d9b 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt @@ -6,7 +6,7 @@ mysqli --FILE-- 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 07c2e144875cb..b11260cb0cac5 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 @@ -6,7 +6,7 @@ mysqli --FILE-- diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt index f1aaad606b3bb..460334024b3ed 100644 --- a/ext/mysqli/tests/mysqli_warning_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -4,14 +4,13 @@ Trying to clone mysqli_warning object mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc index ebdfae1a94b88..2e770426d4c0b 100644 --- a/ext/mysqli/tests/skipifconnectfailure.inc +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -1,7 +1,6 @@ server_capabilities & CLIENT_PLUGIN_AUTH) - && !strncmp(p, MARIA_DB_VERSION_HACK_PREFIX, sizeof(MARIA_DB_VERSION_HACK_PREFIX)-1)) - { - p += sizeof(MARIA_DB_VERSION_HACK_PREFIX)-1; - } - major = ZEND_STRTOL(p, &p, 10); p += 1; /* consume the dot */ minor = ZEND_STRTOL(p, &p, 10); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 54426700c374b..a7bff8051f731 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -369,12 +369,10 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s) /* {{{ mysqlnd_stmt::prepare */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const query, const size_t query_len) +MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * s, const char * const query, const size_t query_len) { MYSQLND_STMT_DATA * stmt = s? s->data : NULL; MYSQLND_CONN_DATA * conn = stmt? stmt->conn : NULL; - MYSQLND_STMT * s_to_prepare = s; - MYSQLND_STMT_DATA * stmt_to_prepare = stmt; DBG_ENTER("mysqlnd_stmt::prepare"); if (!stmt || !conn) { @@ -390,25 +388,15 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const SET_EMPTY_ERROR(conn->error_info); if (stmt->state > MYSQLND_STMT_INITTED) { - /* See if we have to clean the wire */ - if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { - /* Do implicit use_result and then flush the result */ - stmt->default_rset_handler = s->m->use_result; - stmt->default_rset_handler(s); - } - /* No 'else' here please :) */ - if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE && stmt->result) { - stmt->result->m.skip_result(stmt->result); - } /* - Create a new test statement, which we will prepare, but if anything - fails, we will scrap it. + Create a new prepared statement and destroy the previous one. */ - s_to_prepare = conn->m->stmt_init(conn); - if (!s_to_prepare) { + s->m->dtor(s, TRUE); + s = conn->m->stmt_init(conn); + if (!s) { goto fail; } - stmt_to_prepare = s_to_prepare->data; + stmt = s->data; } { @@ -422,13 +410,13 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const } } - if (FAIL == mysqlnd_stmt_read_prepare_response(s_to_prepare)) { + if (FAIL == mysqlnd_stmt_read_prepare_response(s)) { goto fail; } - if (stmt_to_prepare->param_count) { - if (FAIL == mysqlnd_stmt_skip_metadata(s_to_prepare) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) + if (stmt->param_count) { + if (FAIL == mysqlnd_stmt_skip_metadata(s) || + FAIL == mysqlnd_stmt_prepare_read_eof(s)) { goto fail; } @@ -439,51 +427,31 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const Beware that SHOW statements bypass the PS framework and thus they send no metadata at prepare. */ - if (stmt_to_prepare->field_count) { - MYSQLND_RES * result = conn->m->result_init(stmt_to_prepare->field_count); + if (stmt->field_count) { + MYSQLND_RES * result = conn->m->result_init(stmt->field_count); if (!result) { SET_OOM_ERROR(conn->error_info); goto fail; } /* Allocate the result now as it is needed for the reading of metadata */ - stmt_to_prepare->result = result; + stmt->result = result; result->conn = conn->m->get_reference(conn); result->type = MYSQLND_RES_PS_BUF; if (FAIL == result->m.read_result_metadata(result, conn) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) + FAIL == mysqlnd_stmt_prepare_read_eof(s)) { goto fail; } } - if (stmt_to_prepare != stmt) { - /* swap */ - size_t real_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *); - char * tmp_swap = mnd_emalloc(real_size); - memcpy(tmp_swap, s, real_size); - memcpy(s, s_to_prepare, real_size); - memcpy(s_to_prepare, tmp_swap, real_size); - mnd_efree(tmp_swap); - { - MYSQLND_STMT_DATA * tmp_swap_data = stmt_to_prepare; - stmt_to_prepare = stmt; - stmt = tmp_swap_data; - } - s_to_prepare->m->dtor(s_to_prepare, TRUE); - } stmt->state = MYSQLND_STMT_PREPARED; DBG_INF("PASS"); DBG_RETURN(PASS); fail: - if (stmt_to_prepare != stmt && s_to_prepare) { - s_to_prepare->m->dtor(s_to_prepare, TRUE); - } - stmt->state = MYSQLND_STMT_INITTED; - DBG_INF("FAIL"); DBG_RETURN(FAIL); } diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 644909cc4ba98..7f439b7a3f99c 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -41,6 +41,8 @@ const char mysqlnd_read_body_name[] = "mysqlnd_read_body"; #define ERROR_MARKER 0xFF #define EODATA_MARKER 0xFE +#define MARIADB_RPL_VERSION_HACK "5.5.5-" + /* {{{ mysqlnd_command_to_text */ const char * const mysqlnd_command_to_text[COM_END] = { @@ -369,6 +371,12 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet) DBG_RETURN(PASS); } + /* MariaDB always sends 5.5.5 before version string: 5.5.5 was never released, + so just ignore it */ + if (!strncmp((char *) p, MARIADB_RPL_VERSION_HACK, sizeof(MARIADB_RPL_VERSION_HACK) - 1)) { + p += sizeof(MARIADB_RPL_VERSION_HACK) - 1; + } + packet->server_version = estrdup((char *)p); p+= strlen(packet->server_version) + 1; /* eat the '\0' */ BAIL_IF_NO_MORE_DATA; @@ -1614,9 +1622,9 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fiel } else { uint64_t v = #ifndef PHP_WIN32 - (uint64_t) atoll((char *) p); + strtoull((char *) p, NULL, 10); #else - (uint64_t) _atoi64((char *) p); + _strtoui64((char *) p, NULL, 10); #endif bool uns = fields_metadata[i].flags & UNSIGNED_FLAG? TRUE:FALSE; /* We have to make it ASCIIZ temporarily */ diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE index 6a15be588547f..dffd7eab225d7 100644 --- a/ext/oci8/LICENSE +++ b/ext/oci8/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2021 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/odbc/tests/odbc_exec_002.phpt b/ext/odbc/tests/odbc_exec_002.phpt index 590d58d8a8240..44c1baad5ac8e 100644 --- a/ext/odbc/tests/odbc_exec_002.phpt +++ b/ext/odbc/tests/odbc_exec_002.phpt @@ -23,11 +23,13 @@ $res = odbc_exec($conn, 'SELECT * FROM FOO'); var_dump(odbc_fetch_row($res)); var_dump(odbc_result($res, 'test')); var_dump(odbc_fetch_array($res)); - +?> +--CLEAN-- + --EXPECT-- bool(true) diff --git a/ext/odbc/tests/odbc_free_result_001.phpt b/ext/odbc/tests/odbc_free_result_001.phpt index 8f906a5090d19..653e5a0d9facb 100644 --- a/ext/odbc/tests/odbc_free_result_001.phpt +++ b/ext/odbc/tests/odbc_free_result_001.phpt @@ -39,11 +39,13 @@ try { } catch (TypeError $e) { echo $e->getMessage(), "\n"; } - +?> +--CLEAN-- + --EXPECT-- bool(true) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 1b976d8656ab4..a533a074a2603 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -139,6 +139,40 @@ static void preload_restart(void); # define LOCKVAL(v) (ZCSG(v)) #endif +/** + * Clear AVX/SSE2-aligned memory. + */ +static void bzero_aligned(void *mem, size_t size) +{ +#if defined(__x86_64__) + memset(mem, 0, size); +#elif defined(__AVX__) + char *p = (char*)mem; + char *end = p + size; + __m256i ymm0 = _mm256_setzero_si256(); + + while (p < end) { + _mm256_store_si256((__m256i*)p, ymm0); + _mm256_store_si256((__m256i*)(p+32), ymm0); + p += 64; + } +#elif defined(__SSE2__) + char *p = (char*)mem; + char *end = p + size; + __m128i xmm0 = _mm_setzero_si128(); + + while (p < end) { + _mm_store_si128((__m128i*)p, xmm0); + _mm_store_si128((__m128i*)(p+16), xmm0); + _mm_store_si128((__m128i*)(p+32), xmm0); + _mm_store_si128((__m128i*)(p+48), xmm0); + p += 64; + } +#else + memset(mem, 0, size); +#endif +} + #ifdef ZEND_WIN32 static time_t zend_accel_get_time(void) { @@ -1538,47 +1572,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr memory_used = zend_accel_script_persist_calc(new_persistent_script, 1); /* Allocate shared memory */ -#if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - ZCG(mem) = zend_shared_alloc(memory_used + 64); - if (ZCG(mem)) { - ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); -#if defined(__x86_64__) - memset(ZCG(mem), 0, memory_used); -#elif defined(__AVX__) - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m256i ymm0 = _mm256_setzero_si256(); - - while (p < end) { - _mm256_store_si256((__m256i*)p, ymm0); - _mm256_store_si256((__m256i*)(p+32), ymm0); - p += 64; - } - } -#else - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m128i xmm0 = _mm_setzero_si128(); - - while (p < end) { - _mm_store_si128((__m128i*)p, xmm0); - _mm_store_si128((__m128i*)(p+16), xmm0); - _mm_store_si128((__m128i*)(p+32), xmm0); - _mm_store_si128((__m128i*)(p+48), xmm0); - p += 64; - } - } -#endif - } -#else - ZCG(mem) = zend_shared_alloc(memory_used); - if (ZCG(mem)) { - memset(ZCG(mem), 0, memory_used); - } -#endif + ZCG(mem) = zend_shared_alloc_aligned(memory_used); if (!ZCG(mem)) { zend_shared_alloc_destroy_xlat_table(); zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); @@ -1590,6 +1584,8 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr return new_persistent_script; } + bzero_aligned(ZCG(mem), memory_used); + zend_shared_alloc_clear_xlat_table(); /* Copy into shared memory */ @@ -1961,8 +1957,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) ZCG(cache_opline) = NULL; ZCG(cache_persistent_script) = NULL; return file_cache_compile_file(file_handle, type); - } else if (!ZCG(accelerator_enabled) || - (ZCSG(restart_in_progress) && accel_restart_is_active())) { + } else if ((ZCSG(restart_in_progress) && accel_restart_is_active())) { if (ZCG(accel_directives).file_cache) { return file_cache_compile_file(file_handle, type); } @@ -2178,6 +2173,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) zend_hash_index_del(EG(zend_constants), new_const_num); } } + persistent_script->dynamic_members.last_used = ZCG(request_time); + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } else { #if !ZEND_WIN32 @@ -2214,15 +2212,14 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) } } } + persistent_script->dynamic_members.last_used = ZCG(request_time); + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); + replay_warnings(persistent_script->num_warnings, persistent_script->warnings); from_shared_memory = 1; } - persistent_script->dynamic_members.last_used = ZCG(request_time); - - SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); - /* Fetch jit auto globals used in the script before execution */ if (persistent_script->ping_auto_globals_mask & ~ZCG(auto_globals_mask)) { zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask & ~ZCG(auto_globals_mask)); @@ -4236,52 +4233,14 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s memory_used = zend_accel_script_persist_calc(new_persistent_script, 1); /* Allocate shared memory */ -#if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - ZCG(mem) = zend_shared_alloc(memory_used + 64); - if (ZCG(mem)) { - ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); -#if defined(__x86_64__) - memset(ZCG(mem), 0, memory_used); -#elif defined(__AVX__) - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m256i ymm0 = _mm256_setzero_si256(); - - while (p < end) { - _mm256_store_si256((__m256i*)p, ymm0); - _mm256_store_si256((__m256i*)(p+32), ymm0); - p += 64; - } - } -#else - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m128i xmm0 = _mm_setzero_si128(); - - while (p < end) { - _mm_store_si128((__m128i*)p, xmm0); - _mm_store_si128((__m128i*)(p+16), xmm0); - _mm_store_si128((__m128i*)(p+32), xmm0); - _mm_store_si128((__m128i*)(p+48), xmm0); - p += 64; - } - } -#endif - } -#else - ZCG(mem) = zend_shared_alloc(memory_used); - if (ZCG(mem)) { - memset(ZCG(mem), 0, memory_used); - } -#endif + ZCG(mem) = zend_shared_alloc_aligned(memory_used); if (!ZCG(mem)) { zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Not enough shared memory for preloading. Consider increasing the value for the opcache.memory_consumption directive in php.ini."); return NULL; } + bzero_aligned(ZCG(mem), memory_used); + zend_shared_alloc_restore_xlat_table(checkpoint); /* Copy into shared memory */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 9d18493c7d52a..bd692495a5282 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -311,6 +311,8 @@ extern zend_accel_globals accel_globals; extern char *zps_api_failure_reason; +BEGIN_EXTERN_C() + void accel_shutdown(void); zend_result accel_activate(INIT_FUNC_ARGS); zend_result accel_post_deactivate(void); @@ -333,6 +335,8 @@ zend_string* ZEND_FASTCALL accel_new_interned_string(zend_string *str); uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name); +END_EXTERN_C() + /* memory write protection */ #define SHM_PROTECT() \ do { \ diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 5d365504454a6..8ed75b7b7c797 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -170,8 +170,8 @@ static bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ssa * } while (phi); } - next_use = zend_ssa_next_use(ssa->ops, var, use); - if (next_use < 0) { + if (ssa->cfg.blocks[ssa->cfg.map[use]].loop_header > 0 + || (ssa->cfg.blocks[ssa->cfg.map[use]].flags & ZEND_BB_LOOP_HEADER)) { int b = ssa->cfg.map[use]; int prev_use = ssa->vars[var].use_chain; @@ -183,6 +183,10 @@ static bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ssa * } prev_use = zend_ssa_next_use(ssa->ops, var, prev_use); } + } + + next_use = zend_ssa_next_use(ssa->ops, var, use); + if (next_use < 0) { return 1; } else if (zend_ssa_is_no_val_use(op_array->opcodes + next_use, ssa->ops + next_use, var)) { return 1; @@ -316,7 +320,6 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_INIT_USER_CALL: case ZEND_FAST_CALL: case ZEND_JMP: - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -399,7 +402,6 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_INIT_USER_CALL: case ZEND_FAST_CALL: case ZEND_JMP: - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1954,13 +1956,17 @@ static int zend_jit_compute_liveness(const zend_op_array *op_array, zend_ssa *ss if (ssa->ops[line].op1_use >= 0 && intervals[ssa->ops[line].op1_use] && ssa->ops[line].op1_use_chain < 0 && - !ssa->vars[ssa->ops[line].op1_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op1_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op1_use].type & MAY_BE_ANY)) { zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use); } else if (opline->opcode != ZEND_SUB && ssa->ops[line].op2_use >= 0 && intervals[ssa->ops[line].op2_use] && ssa->ops[line].op2_use_chain < 0 && - !ssa->vars[ssa->ops[line].op2_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op2_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op2_use].type & MAY_BE_ANY)) { zend_jit_add_hint(intervals, i, ssa->ops[line].op2_use); } } @@ -3288,6 +3294,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op op2_def_addr = op2_addr; } op1_info = OP1_INFO(); + if (ra && ssa->vars[ssa_op->op1_use].no_val) { + op1_info |= MAY_BE_UNDEF; // requres type assignment + } if (opline->result_type == IS_UNUSED) { res_addr = 0; res_info = -1; @@ -3426,8 +3435,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op && ((opline+1)->opcode == ZEND_JMPZ || (opline+1)->opcode == ZEND_JMPNZ || (opline+1)->opcode == ZEND_JMPZ_EX - || (opline+1)->opcode == ZEND_JMPNZ_EX - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ_EX) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3460,8 +3468,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3486,8 +3493,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3510,8 +3516,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3606,7 +3611,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto done; } ZEND_FALLTHROUGH; - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: if (opline->result_type == IS_UNDEF) { @@ -3630,8 +3634,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3660,8 +3663,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3717,8 +3719,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -4004,15 +4005,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } is_terminated = 1; break; - case ZEND_JMPZNZ: - if (!zend_jit_handler(&dasm_state, opline, - zend_may_throw(opline, ssa_op, op_array, ssa)) || - !zend_jit_cond_jmp(&dasm_state, OP_JMP_ADDR(opline, opline->op2), ssa->cfg.blocks[b].successors[1]) || - !zend_jit_jmp(&dasm_state, ssa->cfg.blocks[b].successors[0])) { - goto jit_failure; - } - is_terminated = 1; - break; case ZEND_JMPZ: case ZEND_JMPNZ: if (opline > op_array->opcodes + ssa->cfg.blocks[b].start && diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 7bae3752d7137..e574a703c3089 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3330,11 +3330,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra OP_JMP_ADDR(opline, opline->op2) : opline + 1; break; - case ZEND_JMPZNZ: - exit_opline = (trace->opline == OP_JMP_ADDR(opline, opline->op2)) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - OP_JMP_ADDR(opline, opline->op2); - break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: if (opline->op2_type == IS_CV) { @@ -3560,6 +3555,14 @@ static int zend_jit_store_var(dasm_State **Dst, uint32_t info, int var, zend_reg return zend_jit_spill_store(Dst, src, dst, info, set_type); } +static int zend_jit_store_var_type(dasm_State **Dst, int var, uint32_t type) +{ + zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); + + | SET_ZVAL_TYPE_INFO dst, type, TMP1w, TMP2 + return 1; +} + static int zend_jit_store_var_if_necessary(dasm_State **Dst, int var, zend_jit_addr src, uint32_t info) { if (Z_MODE(src) == IS_REG && Z_STORE(src)) { @@ -3615,6 +3618,18 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + if (!Z_LOAD(src) && !Z_STORE(src) && Z_STORE(dst)) { + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + + if (!zend_jit_spill_store(Dst, dst, var_addr, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } + } } else if (Z_MODE(dst) == IS_MEM_ZVAL) { if (!Z_LOAD(src) && !Z_STORE(src)) { if (!zend_jit_spill_store(Dst, src, dst, info, @@ -3804,7 +3819,7 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(op1_def_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL op1_def_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL op1_def_addr, val, TMP2, TMP1 } } else { uint64_t val = 0xc3e0000000000000; @@ -3812,7 +3827,7 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(op1_def_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL op1_def_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL op1_def_addr, val, TMP2, TMP1 } } if (Z_MODE(op1_def_addr) == IS_MEM_ZVAL) { @@ -4143,7 +4158,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(res_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL res_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL res_addr, val, TMP2, TMP1 } break; } else if (opcode == ZEND_SUB) { @@ -4152,7 +4167,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(res_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL res_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL res_addr, val, TMP2, TMP1 } break; } @@ -6305,7 +6320,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 | LOAD_ZVAL_ADDR FCARG2x, op3_addr | LOAD_ADDR CARG3, binary_op | SET_EX_OPLINE opline, REG0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + } | b >9 |.code |1: @@ -6426,7 +6446,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t | LOAD_ZVAL_ADDR FCARG2x, op2_addr | LOAD_ADDR CARG3, binary_op | SET_EX_OPLINE opline, REG0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) + && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + } zend_jit_check_exception(Dst); | b >9 |.code @@ -6496,12 +6521,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (result) { | b => target_label } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - if (!result) { - | b => target_label - } else { - | b => target_label2 - } } else { ZEND_UNREACHABLE(); } @@ -6697,36 +6716,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | beq => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | ble => target_label - } else { - | bge => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | blt => target_label - } else { - | bgt => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else { ZEND_UNREACHABLE(); } @@ -6908,39 +6897,6 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | bvs => target_label2 - | beq => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | bvs => target_label - | bls => target_label - } else { - | bhs => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | bvs => target_label - | blo => target_label - } else { - | bhi => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else if (smart_branch_opcode == ZEND_JMPZ_EX) { switch (opline->opcode) { case ZEND_IS_EQUAL: @@ -7233,25 +7189,6 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_CASE: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - | beq => target_label - break; - case ZEND_IS_SMALLER: - | bge => target_label - break; - case ZEND_IS_SMALLER_OR_EQUAL: - | bgt => target_label - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else { ZEND_UNREACHABLE(); } @@ -7533,9 +7470,6 @@ static int zend_jit_identical(dasm_State **Dst, not_identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - not_identical_label = target_label; - identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -7544,9 +7478,6 @@ static int zend_jit_identical(dasm_State **Dst, identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { not_identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - identical_label = target_label; - not_identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -7922,9 +7853,6 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ false_label = target_label; } else if (branch_opcode == ZEND_JMPNZ) { true_label = target_label; - } else if (branch_opcode == ZEND_JMPZNZ) { - true_label = target_label2; - false_label = target_label; } else if (branch_opcode == ZEND_JMPZ_EX) { set_bool = 1; false_label = target_label; @@ -10194,8 +10122,6 @@ static int zend_jit_smart_true(dasm_State **Dst, const zend_op *opline, int jmp, } } else if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10220,8 +10146,6 @@ static int zend_jit_smart_false(dasm_State **Dst, const zend_op *opline, int jmp if (jmp) { | b >7 } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label } else { ZEND_UNREACHABLE(); } @@ -10249,9 +10173,6 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar undefined_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { defined_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - undefined_label = target_label; - defined_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -10487,9 +10408,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | beq =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | beq =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10574,9 +10492,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | beq =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | beq =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10585,9 +10500,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | bne =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | beq =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | bne =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11747,8 +11659,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, | b =>target_label2 } else if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11780,8 +11690,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, if (smart_branch_opcode == ZEND_JMPZ) { | b =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label } else { ZEND_UNREACHABLE(); } @@ -12909,20 +12817,20 @@ static int zend_jit_incdec_obj(dasm_State **Dst, |3: if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { uint64_t val = 0x43e0000000000000; - | LOAD_64BIT_VAL REG0, val - | SET_ZVAL_LVAL_FROM_REG var_addr, REG0, TMP1 + | LOAD_64BIT_VAL TMP2, val + | SET_ZVAL_LVAL_FROM_REG var_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO var_addr, IS_DOUBLE, TMP1w, TMP2 if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { - | SET_ZVAL_LVAL_FROM_REG res_addr, REG0, TMP1 + | SET_ZVAL_LVAL_FROM_REG res_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE, TMP1w, TMP2 } } else { uint64_t val = 0xc3e0000000000000; - | LOAD_64BIT_VAL REG0, val - | SET_ZVAL_LVAL_FROM_REG var_addr, REG0, TMP1 + | LOAD_64BIT_VAL TMP2, val + | SET_ZVAL_LVAL_FROM_REG var_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO var_addr, IS_DOUBLE, TMP1w, TMP2 if (opline->opcode == ZEND_PRE_DEC_OBJ && opline->result_type != IS_UNUSED) { - | SET_ZVAL_LVAL_FROM_REG res_addr, REG0, TMP1 + | SET_ZVAL_LVAL_FROM_REG res_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE, TMP1w, TMP2 } } @@ -13190,7 +13098,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | LOAD_ZVAL_ADDR FCARG2x, val_addr } | LOAD_ADDR CARG3, binary_op - | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + } | b >9 |.code @@ -13251,7 +13164,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | SET_EX_OPLINE opline, REG0 } | LOAD_ADDR CARG3, binary_op - | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, REG0 + } | b >9 |.code |2: @@ -14306,8 +14224,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui } else if (smart_branch_opcode) { if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } } else { | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 @@ -14337,9 +14253,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui | ble =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bgt =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | ble =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -14687,9 +14600,6 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o | cbz RETVALx, =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | cbnz RETVALx, =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | cbz RETVALx, =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -14985,7 +14895,6 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ZEND_FALLTHROUGH; case ZEND_BOOL: case ZEND_BOOL_NOT: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: return 1; @@ -15193,6 +15102,9 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend if (op1_info & MAY_BE_DOUBLE) { regset = ZEND_REGSET(ZREG_FPR0); } + if (opline->result_type != IS_UNUSED && (op1_info & MAY_BE_LONG)) { + ZEND_REGSET_INCL(regset, ZREG_REG1); + } } break; case ZEND_ADD: @@ -15302,7 +15214,6 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); diff --git a/ext/opcache/jit/zend_jit_disasm.c b/ext/opcache/jit/zend_jit_disasm.c index 4846d17c2bfcb..25e88a3464073 100644 --- a/ext/opcache/jit/zend_jit_disasm.c +++ b/ext/opcache/jit/zend_jit_disasm.c @@ -664,6 +664,7 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_post_inc_typed_ref); REGISTER_HELPER(zend_jit_post_dec_typed_ref); REGISTER_HELPER(zend_jit_assign_op_to_typed_ref); + REGISTER_HELPER(zend_jit_assign_op_to_typed_ref_tmp); REGISTER_HELPER(zend_jit_only_vars_by_reference); REGISTER_HELPER(zend_jit_invalid_array_access); REGISTER_HELPER(zend_jit_invalid_property_read); diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index cd0743df514d2..fd2ee551a0c59 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -365,8 +365,10 @@ static int ZEND_FASTCALL zend_jit_undefined_op_helper_write(HashTable *ht, uint3 GC_ADDREF(ht); } zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(cv)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } return 0; } return EG(exception) == NULL; @@ -377,6 +379,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -390,16 +394,91 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } ZEND_FALLTHROUGH; case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + hval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } + } goto num_index; case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } hval = Z_RES_HANDLE_P(dim); goto num_index; case IS_FALSE: @@ -442,6 +521,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -455,16 +536,91 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } ZEND_FALLTHROUGH; case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + hval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } + } goto num_index; case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } hval = Z_RES_HANDLE_P(dim); goto num_index; case IS_FALSE: @@ -518,16 +674,55 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; + } ZEND_FALLTHROUGH; case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + hval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; + } + } goto num_index; case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; + } hval = Z_RES_HANDLE_P(dim); goto num_index; case IS_FALSE: @@ -615,8 +810,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di execute_data = EG(current_execute_data); opline = EX(opline); zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -643,8 +840,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di execute_data = EG(current_execute_data); opline = EX(opline); zend_use_resource_as_offset(dim); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -723,6 +922,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim ZVAL_NULL(EX_VAR(opline->result.var)); } } + if (opline->opcode == ZEND_ASSIGN_DIM + && ((opline+1)->op1_type & (IS_VAR | IS_TMP_VAR))) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } return NULL; } ZEND_FALLTHROUGH; @@ -740,8 +943,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim execute_data = EG(current_execute_data); opline = EX(opline); zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -768,8 +973,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim execute_data = EG(current_execute_data); opline = EX(opline); zend_use_resource_as_offset(dim); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -1220,6 +1427,8 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval ZVAL_NULL(result); return; } + SEPARATE_ARRAY(object_ptr); + arr = Z_ARRVAL_P(object_ptr); zval *var; if (dim) { if (type == BP_VAR_W) { @@ -1324,6 +1533,8 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim } return; } + SEPARATE_ARRAY(object_ptr); + arr = Z_ARRVAL_P(object_ptr); zval *var = dim ? zend_jit_fetch_dim_w_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); @@ -1402,6 +1613,8 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zend_array_destroy(arr); return; } + SEPARATE_ARRAY(container); + arr = Z_ARRVAL_P(container); zval *var = dim ? zend_jit_fetch_dim_rw_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); @@ -2107,6 +2320,20 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref(zend_reference *ref, z } } +static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref_tmp(zend_reference *ref, zval *val, binary_op_type binary_op) +{ + zval z_copy; + + binary_op(&z_copy, &ref->val, val); + if (EXPECTED(zend_verify_ref_assignable_zval(ref, &z_copy, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) { + zval_ptr_dtor(&ref->val); + ZVAL_COPY_VALUE(&ref->val, &z_copy); + } else { + zval_ptr_dtor(&z_copy); + } + zval_ptr_dtor_nogc(val); +} + static void ZEND_FASTCALL zend_jit_only_vars_by_reference(zval *arg) { ZVAL_NEW_REF(arg, arg); @@ -2173,9 +2400,14 @@ static zval * ZEND_FASTCALL zend_jit_prepare_assign_dim_ref(zval *ref) { return NULL; } if (Z_TYPE_P(val) == IS_FALSE) { + ZVAL_ARR(val, zend_new_array(8)); zend_false_to_array_deprecated(); + if (EG(exception)) { + return NULL; + } + } else { + ZVAL_ARR(val, zend_new_array(8)); } - ZVAL_ARR(val, zend_new_array(8)); } return val; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index b941447f86103..20934a8928327 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -310,7 +310,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op return 1; } break; - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1663,6 +1662,11 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin if (opline->result_type != IS_UNUSED) { break; } + if (op3_type != IS_UNKNOWN + && !zend_jit_supported_binary_op( + opline->extended_value, MAY_BE_ANY, (1<op1_type == IS_CV) { @@ -1738,6 +1742,14 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin } ADD_OP1_TRACE_GUARD(); break; + case ZEND_CONCAT: + case ZEND_FAST_CONCAT: + if ((opline->op1_type == IS_CONST || orig_op1_type == IS_STRING) + && (opline->op2_type == IS_CONST || orig_op2_type == IS_STRING)) { + ADD_OP2_TRACE_GUARD(); + ADD_OP1_TRACE_GUARD(); + } + break; case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: @@ -1756,8 +1768,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_SUB: case ZEND_MUL: // case ZEND_DIV: // TODO: check for division by zero ??? - case ZEND_CONCAT: - case ZEND_FAST_CONCAT: ADD_OP2_TRACE_GUARD(); ZEND_FALLTHROUGH; case ZEND_ECHO: @@ -1835,7 +1845,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin break; case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_BOOL: @@ -3210,7 +3219,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace if (ssa->ops[line].op1_use >= 0 && intervals[ssa->ops[line].op1_use] && ssa->ops[line].op1_use_chain < 0 && - !ssa->vars[ssa->ops[line].op1_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op1_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op1_use].type & MAY_BE_ANY)) { zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op1_use].definition_phi; if (phi && @@ -3223,7 +3234,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace ssa->ops[line].op2_use >= 0 && intervals[ssa->ops[line].op2_use] && ssa->ops[line].op2_use_chain < 0 && - !ssa->vars[ssa->ops[line].op2_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op2_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op2_use].type & MAY_BE_ANY)) { zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op2_use].definition_phi; if (phi && @@ -3345,7 +3358,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace intervals[use]->used_as_hint = NULL; intervals[use]->list_next = NULL; } - } else if (intervals[use] && !ssa->vars[phi->ssa_var].no_val) { + } else if (intervals[use] + && (!ssa->vars[def].no_val + || ssa->var_info[def].type != ssa->var_info[use].type)) { if (ssa->vars[use].use_chain >= 0) { intervals[use]->flags |= ZREG_STORE; } else { @@ -3417,8 +3432,9 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse } } -static bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ssa_opcodes, int var) +static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ssa *ssa, const zend_op **ssa_opcodes, const zend_ssa_op *ssa_op) { + int var = ssa_op->result_def; int i; int use = ssa->vars[var].use_chain; const zend_op *opline; @@ -3459,6 +3475,19 @@ static bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ssa_opc return 0; } + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { + if (opline->op1_type == IS_CV + && (opline+1)->op1_type == IS_CV + && (opline+1)->op1.var == opline->op1.var) { + /* skip $a->prop += $a; */ + return 0; + } + if (!zend_jit_supported_binary_op( + opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { + return 0; + } + } + for (i = ssa->vars[var].definition; i < use; i++) { if (ssa_opcodes[i]->opcode == ZEND_DO_UCALL || ssa_opcodes[i]->opcode == ZEND_DO_FCALL_BY_NAME @@ -4107,7 +4136,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ssa->var_info[i].type &= ~MAY_BE_GUARD; op_type = concrete_type(ssa->var_info[i].type); - if (!zend_jit_type_guard(&dasm_state, opline, i, op_type)) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), op_type)) { goto jit_failure; } SET_STACK_TYPE(stack, i, op_type, 1); @@ -4140,12 +4169,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ZEND_ASSERT(ival->reg != ZREG_NONE); if (info & MAY_BE_GUARD) { - if (!zend_jit_type_guard(&dasm_state, opline, phi->var, concrete_type(info))) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(phi->var), concrete_type(info))) { goto jit_failure; } info &= ~MAY_BE_GUARD; ssa->var_info[phi->ssa_var].type = info; - SET_STACK_TYPE(stack, i, concrete_type(info), 1); + SET_STACK_TYPE(stack, phi->var, concrete_type(info), 1); } SET_STACK_REG_EX(stack, phi->var, ival->reg, ZREG_LOAD); if (!zend_jit_load_var(&dasm_state, ssa->var_info[phi->ssa_var].type, ssa->vars[phi->ssa_var].var, ival->reg)) { @@ -4855,24 +4884,18 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par break; } op2_addr = OP2_REG_ADDR(); + op2_info = OP2_INFO(); if (ra && ssa_op->op2_def >= 0 - && !ssa->vars[ssa_op->op2_def].no_val) { + && (!ssa->vars[ssa_op->op2_def].no_val + || (zend_jit_trace_type_to_info(STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var))) & MAY_BE_ANY) != + (op2_info & MAY_BE_ANY))) { op2_def_addr = OP2_DEF_REG_ADDR(); } else { op2_def_addr = op2_addr; } - op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); - if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG - || (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_DOUBLE) { - if (STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_LONG - && STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_DOUBLE) { - /* type may be not set */ - op1_info |= MAY_BE_NULL; - } - } op1_def_info = OP1_DEF_INFO(); if (op1_type != IS_UNKNOWN && (op1_info & MAY_BE_GUARD)) { if (op1_type < IS_STRING @@ -4887,6 +4910,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } op1_addr = OP1_REG_ADDR(); op1_def_addr = OP1_DEF_REG_ADDR(); + if (Z_MODE(op1_def_addr) != IS_REG && + STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != + STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var))) { + /* type may be not set */ + op1_info |= MAY_BE_NULL; + } if (orig_op1_type != IS_UNKNOWN) { if (orig_op1_type & IS_TRACE_REFERENCE) { if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, @@ -4964,9 +4993,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par res_use_info = zend_jit_trace_type_to_info( STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE); + res_addr = RES_REG_ADDR(); + if (Z_MODE(res_addr) != IS_REG && + STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)) != + STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) { + /* type may be not set */ + res_use_info |= MAY_BE_NULL; + } if (!zend_jit_qm_assign(&dasm_state, opline, op1_info, op1_addr, op1_def_addr, - res_use_info, res_info, RES_REG_ADDR())) { + res_use_info, res_info, res_addr)) { goto jit_failure; } if (opline->op1_type == IS_CV @@ -5343,7 +5379,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); @@ -5363,13 +5398,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { smart_branch_opcode = ZEND_JMPNZ; } - exit_opline = (opline->opcode == ZEND_JMPZNZ) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - opline + 1; - } else if (opline->opcode == ZEND_JMPZNZ) { - ZEND_ASSERT((p+1)->opline == ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value)); - smart_branch_opcode = ZEND_JMPZ; - exit_opline = OP_JMP_ADDR(opline, opline->op2); + exit_opline = opline + 1; } else if ((p+1)->opline == opline + 1) { /* not taken branch */ smart_branch_opcode = opline->opcode; @@ -5884,7 +5913,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_FETCH_THIS: delayed_fetch_this = 0; if (ssa_op->result_def >= 0 && opline->result_type != IS_CV) { - if (zend_jit_may_delay_fetch_this(ssa, ssa_opcodes, ssa_op->result_def)) { + if (zend_jit_may_delay_fetch_this(op_array, ssa, ssa_opcodes, ssa_op)) { ssa->var_info[ssa_op->result_def].delayed_fetch_this = 1; delayed_fetch_this = 1; } @@ -6109,7 +6138,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } if (opline->opcode != ZEND_NOP && opline->opcode != ZEND_JMP) { - if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { + op1_info = OP1_INFO(); + op2_info = OP2_INFO(); + if (op1_info & MAY_BE_GUARD) { + op1_info = MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } + if (op2_info & MAY_BE_GUARD) { + op2_info = MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } + if (!zend_jit_trace_handler(&dasm_state, op_array, opline, + zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info), p + 1)) { goto jit_failure; } } @@ -6256,8 +6294,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par || opline->opcode == ZEND_COALESCE || opline->opcode == ZEND_JMP_NULL || opline->opcode == ZEND_FE_RESET_R) { - if (!ra[ssa_op->op1_use] - || ra[ssa_op->op1_use]->reg != ra[ssa_op->op1_def]->reg) { + if (!ra[ssa_op->op1_use]) { flags |= ZREG_LOAD; } } @@ -6704,6 +6741,22 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (p->stop == ZEND_JIT_TRACE_STOP_LOOP || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { + if (ra) { + zend_ssa_phi *phi = ssa->blocks[1].phis; + + while (phi) { + if (ra[phi->ssa_var] + && ra[phi->sources[1]] + && STACK_MEM_TYPE(stack, phi->var) != STACK_TYPE(stack, phi->var) + && (ra[phi->ssa_var]->flags & (ZREG_LOAD|ZREG_STORE)) == 0 + && (ra[phi->sources[1]]->flags & (ZREG_LOAD|ZREG_STORE)) == 0) { + /* Store actual type to memory to avoid deoptimization mistakes */ + /* TODO: Alternatively, we may try to update alredy generated deoptimization info */ + zend_jit_store_var_type(&dasm_state, phi->var, STACK_TYPE(stack, phi->var)); + } + phi = phi->next; + } + } if (p->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { if ((t->flags & ZEND_JIT_TRACE_USES_INITIAL_IP) && !zend_jit_set_ip(&dasm_state, p->opline)) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 5f09e41eaed3e..e307f86f40f44 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -2956,7 +2956,7 @@ static int zend_jit_setup(void) # elif defined(__GNUC__) && defined(__x86_64__) tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); if (tsrm_ls_cache_tcb_offset == 0) { -#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" @@ -2975,7 +2975,7 @@ static int zend_jit_setup(void) # elif defined(__GNUC__) && defined(__i386__) tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); if (tsrm_ls_cache_tcb_offset == 0) { -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("leal _tsrm_ls_cache@ntpoff,%0\n" @@ -3660,11 +3660,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra OP_JMP_ADDR(opline, opline->op2) : opline + 1; break; - case ZEND_JMPZNZ: - exit_opline = (trace->opline == OP_JMP_ADDR(opline, opline->op2)) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - OP_JMP_ADDR(opline, opline->op2); - break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: if (opline->op2_type == IS_CV) { @@ -3900,6 +3895,14 @@ static int zend_jit_store_var(dasm_State **Dst, uint32_t info, int var, zend_reg return zend_jit_spill_store(Dst, src, dst, info, set_type); } +static int zend_jit_store_var_type(dasm_State **Dst, int var, uint32_t type) +{ + zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); + + | SET_ZVAL_TYPE_INFO dst, type + return 1; +} + static int zend_jit_store_var_if_necessary(dasm_State **Dst, int var, zend_jit_addr src, uint32_t info) { if (Z_MODE(src) == IS_REG && Z_STORE(src)) { @@ -3955,6 +3958,18 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + if (!Z_LOAD(src) && !Z_STORE(src) && Z_STORE(dst)) { + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + + if (!zend_jit_spill_store(Dst, dst, var_addr, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } + } } else if (Z_MODE(dst) == IS_MEM_ZVAL) { if (!Z_LOAD(src) && !Z_STORE(src)) { if (!zend_jit_spill_store(Dst, src, dst, info, @@ -4478,11 +4493,11 @@ static int zend_jit_math_long_long(dasm_State **Dst, (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1))) { if (opcode == ZEND_ADD) { |.if X64 - | mov64 rax, 0x43e0000000000000 + | mov64 Ra(tmp_reg), 0x43e0000000000000 if (Z_MODE(res_addr) == IS_REG) { - | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax + | movd xmm(Z_REG(res_addr)-ZREG_XMM0), Ra(tmp_reg) } else { - | SET_ZVAL_LVAL res_addr, rax + | SET_ZVAL_LVAL res_addr, Ra(tmp_reg) } |.else | SET_ZVAL_LVAL res_addr, 0 @@ -4491,11 +4506,11 @@ static int zend_jit_math_long_long(dasm_State **Dst, break; } else if (opcode == ZEND_SUB) { |.if X64 - | mov64 rax, 0xc3e0000000000000 + | mov64 Ra(tmp_reg), 0xc3e0000000000000 if (Z_MODE(res_addr) == IS_REG) { - | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax + | movd xmm(Z_REG(res_addr)-ZREG_XMM0), Ra(tmp_reg) } else { - | SET_ZVAL_LVAL res_addr, rax + | SET_ZVAL_LVAL res_addr, Ra(tmp_reg) } |.else | SET_ZVAL_LVAL res_addr, 0x00200000 @@ -6112,6 +6127,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 0); } else { zend_jit_addr ref_addr; + zend_reg type_reg = tmp_reg; if (in_cold) { | IF_NOT_ZVAL_TYPE val_addr, IS_REFERENCE, >1 @@ -6120,21 +6136,24 @@ static int zend_jit_simple_assign(dasm_State **Dst, |.cold_code |1: } - if (Z_REG(val_addr) == ZREG_R2) { - | mov aword T1, r2 // save - } | // zend_refcounted *ref = Z_COUNTED_P(retval_ptr); | GET_ZVAL_PTR r2, val_addr | GC_DELREF r2 | // ZVAL_COPY_VALUE(return_value, &ref->value); ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8); if (!res_addr) { - | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg + | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, type_reg, tmp_reg } else { - | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg + | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, type_reg, tmp_reg } | je >2 - | IF_NOT_REFCOUNTED dh, >3 + if (tmp_reg == ZREG_R0) { + | IF_NOT_REFCOUNTED ah, >3 + } else { + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >3 + } + | GET_ZVAL_PTR Ra(tmp_reg), var_addr + if (!res_addr) { | GC_ADDREF Ra(tmp_reg) } else { @@ -6143,17 +6162,19 @@ static int zend_jit_simple_assign(dasm_State **Dst, | jmp >3 |2: if (res_addr) { - | IF_NOT_REFCOUNTED dh, >2 + if (tmp_reg == ZREG_R0) { + | IF_NOT_REFCOUNTED ah, >2 + } else { + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >2 + } + | GET_ZVAL_PTR Ra(tmp_reg), var_addr | GC_ADDREF Ra(tmp_reg) |2: } - if (Z_REG(val_addr) == ZREG_R2) { - | mov r2, aword T1 // restore - } if (save_r1) { | mov aword T1, FCARG1a // save } - | EFREE_REFERENCE aword [Ra(Z_REG(val_addr))+Z_OFFSET(val_addr)] + | EFREE_REFERENCE r2 if (save_r1) { | mov FCARG1a, aword T1 // restore } @@ -6837,7 +6858,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 | PUSH_ADDR binary_op, r0 |.endif | SET_EX_OPLINE opline, r0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -6975,7 +7001,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t | PUSH_ADDR binary_op, r0 |.endif | SET_EX_OPLINE opline, r0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) + && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -7048,12 +7079,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (result) { | jmp => target_label } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - if (!result) { - | jmp => target_label - } else { - | jmp => target_label2 - } } else { ZEND_UNREACHABLE(); } @@ -7250,36 +7275,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | jne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | je => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | jle => target_label - } else { - | jge => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | jl => target_label - } else { - | jg => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else { ZEND_UNREACHABLE(); } @@ -7463,40 +7458,6 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | jne => target_label - | jp => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | jp => target_label2 - | je => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | jbe => target_label - } else { - | jae => target_label - | jp => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | jb => target_label - } else { - | ja => target_label - | jp => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else if (smart_branch_opcode == ZEND_JMPZ_EX) { switch (opline->opcode) { case ZEND_IS_EQUAL: @@ -7793,25 +7754,6 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_CASE: - | jne => target_label - break; - case ZEND_IS_NOT_EQUAL: - | je => target_label - break; - case ZEND_IS_SMALLER: - | jge => target_label - break; - case ZEND_IS_SMALLER_OR_EQUAL: - | jg => target_label - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else { ZEND_UNREACHABLE(); } @@ -8110,9 +8052,6 @@ static int zend_jit_identical(dasm_State **Dst, not_identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - not_identical_label = target_label; - identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -8121,9 +8060,6 @@ static int zend_jit_identical(dasm_State **Dst, identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { not_identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - identical_label = target_label; - not_identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -8501,9 +8437,6 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ false_label = target_label; } else if (branch_opcode == ZEND_JMPNZ) { true_label = target_label; - } else if (branch_opcode == ZEND_JMPZNZ) { - true_label = target_label2; - false_label = target_label; } else if (branch_opcode == ZEND_JMPZ_EX) { set_bool = 1; false_label = target_label; @@ -10846,8 +10779,6 @@ static int zend_jit_smart_true(dasm_State **Dst, const zend_op *opline, int jmp, } } else if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10872,8 +10803,6 @@ static int zend_jit_smart_false(dasm_State **Dst, const zend_op *opline, int jmp if (jmp) { | jmp >7 } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label } else { ZEND_UNREACHABLE(); } @@ -10901,9 +10830,6 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar undefined_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { defined_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - undefined_label = target_label; - defined_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -11141,9 +11067,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | je =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | je =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11225,9 +11148,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | je =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | je =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11236,9 +11156,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | jne =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | je =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jne =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -12452,8 +12369,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, | jmp =>target_label2 } else if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -12485,8 +12400,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, if (smart_branch_opcode == ZEND_JMPZ) { | jmp =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label } else { ZEND_UNREACHABLE(); } @@ -13960,7 +13873,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -14039,7 +13957,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -15196,8 +15119,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui } else if (smart_branch_opcode) { if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } } else { | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE @@ -15226,9 +15147,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui | jle =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jg =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jle =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -15580,9 +15498,6 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o | jz =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jnz =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jz =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -15875,7 +15790,6 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ZEND_FALLTHROUGH; case ZEND_BOOL: case ZEND_BOOL_NOT: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: return 1; @@ -16098,6 +16012,9 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend if (op1_info & MAY_BE_DOUBLE) { regset = ZEND_REGSET(ZREG_XMM0); } + if (opline->result_type != IS_UNUSED && (op1_info & MAY_BE_LONG)) { + ZEND_REGSET_INCL(regset, ZREG_R1); + } } break; case ZEND_ADD: @@ -16203,6 +16120,7 @@ bw_op: if (!(op1_info & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)-MAY_BE_LONG)) && !(op2_info & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)-MAY_BE_LONG))) { if (opline->op2_type == IS_CONST && + opline->op1_type != IS_CONST && Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_LONG && zend_long_is_power_of_two(Z_LVAL_P(RT_CONSTANT(opline, opline->op2))) && OP1_HAS_RANGE() && @@ -16263,7 +16181,6 @@ bw_op: case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); diff --git a/ext/opcache/tests/jit/add_013.phpt b/ext/opcache/tests/jit/add_013.phpt new file mode 100644 index 0000000000000..e2baa69566af3 --- /dev/null +++ b/ext/opcache/tests/jit/add_013.phpt @@ -0,0 +1,20 @@ +--TEST-- +JIT ADD: 013 register allocation (incorrect hinting) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + 4) break; + } +} +?> +DONE +--EXPECT-- +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/assign_049.phpt b/ext/opcache/tests/jit/assign_049.phpt new file mode 100644 index 0000000000000..f085e51f3234a --- /dev/null +++ b/ext/opcache/tests/jit/assign_049.phpt @@ -0,0 +1,29 @@ +--TEST-- +JIT ASSIGN: register allocation on x86 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- +a = a(1); + } +} + +$a = new A; +$a->test(); +$a->test(); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_050.phpt b/ext/opcache/tests/jit/assign_050.phpt new file mode 100644 index 0000000000000..21fcf9ef794aa --- /dev/null +++ b/ext/opcache/tests/jit/assign_050.phpt @@ -0,0 +1,23 @@ +--TEST-- +JIT ASSIGN: incorrect type store elimination +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_051.phpt b/ext/opcache/tests/jit/assign_051.phpt new file mode 100644 index 0000000000000..88264161d4af5 --- /dev/null +++ b/ext/opcache/tests/jit/assign_051.phpt @@ -0,0 +1,23 @@ +--TEST-- +JIT ASSIGN: incorrect assignment optimization +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %sassign_051.php:3 +Stack trace: +#0 %sassign_051.php(7): foo(0) +#1 {main} + thrown in %sassign_051.php on line 3 diff --git a/ext/opcache/tests/jit/assign_052.phpt b/ext/opcache/tests/jit/assign_052.phpt new file mode 100644 index 0000000000000..902d223b423ce --- /dev/null +++ b/ext/opcache/tests/jit/assign_052.phpt @@ -0,0 +1,20 @@ +--TEST-- +JIT ASSIGN: incorrect reference counting +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + $n[$i = $j] = $s = $a . $a = $f; + } +} +@foo(); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_dim_006.phpt b/ext/opcache/tests/jit/assign_dim_006.phpt new file mode 100644 index 0000000000000..d97663dc89fb3 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_006.phpt @@ -0,0 +1,29 @@ +--TEST-- +JIT ASSIGN_DIM: 006 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 +NULL diff --git a/ext/opcache/tests/jit/assign_dim_007.phpt b/ext/opcache/tests/jit/assign_dim_007.phpt new file mode 100644 index 0000000000000..c4aa228df3391 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_007.phpt @@ -0,0 +1,27 @@ +--TEST-- +JIT ASSIGN_DIM: 007 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECT-- +array(0) { +} +array(1) { + [0]=> + int(1) +} diff --git a/ext/opcache/tests/jit/assign_dim_008.phpt b/ext/opcache/tests/jit/assign_dim_008.phpt new file mode 100644 index 0000000000000..c0150809e40f6 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_008.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT ASSIGN_DIM: 008 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_dim_009.phpt b/ext/opcache/tests/jit/assign_dim_009.phpt new file mode 100644 index 0000000000000..bea28098a5e9b --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_009.phpt @@ -0,0 +1,14 @@ +--TEST-- +JIT ASSIGN_DIM: 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_dim_010.phpt b/ext/opcache/tests/jit/assign_dim_010.phpt new file mode 100644 index 0000000000000..3da83cc614e14 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_010.phpt @@ -0,0 +1,24 @@ +--TEST-- +JIT ASSIGN_DIM: 010 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $a in %sassign_dim_010.php on line 4 + +Warning: Undefined variable $y in %sassign_dim_010.php on line 4 +DONE diff --git a/ext/opcache/tests/jit/assign_dim_011.phpt b/ext/opcache/tests/jit/assign_dim_011.phpt new file mode 100644 index 0000000000000..941033a8ac6cd --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_011.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT ASSIGN_DIM: 011 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +getMessage() . "\n"; +} +?> +DONE +--EXPECT-- +Err: Automatic conversion of false to array is deprecated +Exception: Cannot use a scalar value as an array +DONE diff --git a/ext/opcache/tests/jit/assign_dim_012.phpt b/ext/opcache/tests/jit/assign_dim_012.phpt new file mode 100644 index 0000000000000..0753d93618213 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_012.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT ASSIGN_DIM: 012 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE diff --git a/ext/opcache/tests/jit/assign_dim_013.phpt b/ext/opcache/tests/jit/assign_dim_013.phpt new file mode 100644 index 0000000000000..49907b358a21a --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_013.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT ASSIGN_DIM: 013 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +y = set_error_handler(function(){}); + foreach($obj as $y) { + } + $arr = ['' => y]; + } +} +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %sassign_dim_013.php:8 +Stack trace: +#0 %sassign_dim_013.php(11): test() +#1 {main} + thrown in %sassign_dim_013.php on line 8 \ No newline at end of file diff --git a/ext/opcache/tests/jit/assign_dim_014.phpt b/ext/opcache/tests/jit/assign_dim_014.phpt new file mode 100644 index 0000000000000..d5680a4b60764 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_014.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_DIM: 014 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +Error: Undefined variable $y +DONE diff --git a/ext/opcache/tests/jit/assign_dim_op_007.phpt b/ext/opcache/tests/jit/assign_dim_op_007.phpt new file mode 100644 index 0000000000000..e8708a1255131 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_op_007.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT ASSIGN_DIM_OP: overflow +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +member = 9223372036854775807; + $this->member += 1; + } +} +new test(); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/assign_obj_op_001.phpt b/ext/opcache/tests/jit/assign_obj_op_001.phpt new file mode 100644 index 0000000000000..cb7c9a0b39e8a --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_op_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT ASSIGN_OBJ_OP: Unsupported types +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +y.=[];})->call($test); +?> +--EXPECTF-- +Deprecated: Creation of dynamic property Test::$y is deprecated in %sassign_obj_op_001.php on line 6 + +Warning: Undefined property: Test::$y in %sassign_obj_op_001.php on line 6 + +Warning: Array to string conversion in %sassign_obj_op_001.php on line 6 diff --git a/ext/opcache/tests/jit/assign_obj_op_002.phpt b/ext/opcache/tests/jit/assign_obj_op_002.phpt new file mode 100644 index 0000000000000..3d6ac3f897bff --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_op_002.phpt @@ -0,0 +1,31 @@ +--TEST-- +JIT ASSIGN_OBJ_OP: memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +prop .= $a->prop . "leak"; + return "test"; + } +} + +$a = new A; +$prop = &$a->prop; +$a->prop = new B; +var_dump($a); +?> +--EXPECT-- +object(A)#1 (1) { + ["prop"]=> + &string(4) "test" +} diff --git a/ext/opcache/tests/jit/bw_not_002.phpt b/ext/opcache/tests/jit/bw_not_002.phpt new file mode 100644 index 0000000000000..034c6bc90cbdf --- /dev/null +++ b/ext/opcache/tests/jit/bw_not_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +JIT BW_NOT: 002 Exception handling +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: Cannot perform bitwise not on bool in %sbw_not_002.php:5 +Stack trace: +#0 %sbw_not_002.php(8): test() +#1 {main} + thrown in %sbw_not_002.php on line 5 diff --git a/ext/opcache/tests/jit/fetch_dim_r_010.phpt b/ext/opcache/tests/jit/fetch_dim_r_010.phpt new file mode 100644 index 0000000000000..677f4a411b6aa --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_010.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT FETCH_DIM_R: 010 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/fetch_dim_r_011.phpt b/ext/opcache/tests/jit/fetch_dim_r_011.phpt new file mode 100644 index 0000000000000..3ef3733f19c00 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_011.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT FETCH_DIM_R: 011 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/fetch_dim_r_012.phpt b/ext/opcache/tests/jit/fetch_dim_r_012.phpt new file mode 100644 index 0000000000000..6356851290227 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_012.phpt @@ -0,0 +1,38 @@ +--TEST-- +JIT FETCH_DIM_R: 012 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECT-- +array(6) { + [0]=> + &NULL + [1]=> + &NULL + [2]=> + &NULL + [3]=> + &NULL + [4]=> + &NULL + [5]=> + &NULL +} +array(1) { + [" "]=> + int(0) +} diff --git a/ext/opcache/tests/jit/fetch_obj_009.phpt b/ext/opcache/tests/jit/fetch_obj_009.phpt new file mode 100644 index 0000000000000..92d67de08abbf --- /dev/null +++ b/ext/opcache/tests/jit/fetch_obj_009.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT: FETCH_OBJ 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +x[0] = null; + $obj->x > $obj->x[0] = null; + } +} +test(); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/jit/qm_assign_003.phpt b/ext/opcache/tests/jit/qm_assign_003.phpt new file mode 100644 index 0000000000000..1c57a9bea22b5 --- /dev/null +++ b/ext/opcache/tests/jit/qm_assign_003.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT QM_ASSIGN: 003 missing type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_006.phpt b/ext/opcache/tests/jit/reg_alloc_006.phpt new file mode 100644 index 0000000000000..4f4c3fb5fa2b4 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_006.phpt @@ -0,0 +1,34 @@ +--TEST-- +Register Alloction 006: Incorrect type store elimination +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_007.phpt b/ext/opcache/tests/jit/reg_alloc_007.phpt new file mode 100644 index 0000000000000..2c9f13943d770 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_007.phpt @@ -0,0 +1,26 @@ +--TEST-- +Register Alloction 007: Missing store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $a in %sreg_alloc_007.php on line 4 + +Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %sreg_alloc_007.php:6 +Stack trace: +#0 %sreg_alloc_007.php(9): test() +#1 {main} + thrown in %sreg_alloc_007.php on line 6 diff --git a/ext/opcache/tests/jit/reg_alloc_008.phpt b/ext/opcache/tests/jit/reg_alloc_008.phpt new file mode 100644 index 0000000000000..f71578ab4307c --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_008.phpt @@ -0,0 +1,17 @@ +--TEST-- +Register Alloction 008: Incorrect deoptimization code +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $y in %sreg_alloc_008.php on line 4 diff --git a/ext/opcache/tests/jit/reg_alloc_009.phpt b/ext/opcache/tests/jit/reg_alloc_009.phpt new file mode 100644 index 0000000000000..dfcbfc086f85f --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_009.phpt @@ -0,0 +1,24 @@ +--TEST-- +Register Alloction 009: Missing type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +> - $j++; + } +} +test(); +?> +--EXPECTF-- +Warning: Undefined variable $j in %sreg_alloc_009.php on line 4 + +Fatal error: Uncaught ArithmeticError: Bit shift by negative number in %sreg_alloc_009.php:4 +Stack trace: +#0 %sreg_alloc_009.php(7): test() +#1 {main} + thrown in %sreg_alloc_009.php on line 4 diff --git a/ext/opcache/tests/jit/reg_alloc_010.phpt b/ext/opcache/tests/jit/reg_alloc_010.phpt new file mode 100644 index 0000000000000..d14b107295346 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_010.phpt @@ -0,0 +1,24 @@ +--TEST-- +Register Alloction 010: Missed store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $cnt in %sreg_alloc_010.php on line 3 + +Warning: Undefined variable $cnt in %sreg_alloc_010.php on line 3 +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_011.phpt b/ext/opcache/tests/jit/reg_alloc_011.phpt new file mode 100644 index 0000000000000..f628adf7795ae --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_011.phpt @@ -0,0 +1,25 @@ +--TEST-- +Register Alloction 011: Missed type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_012.phpt b/ext/opcache/tests/jit/reg_alloc_012.phpt new file mode 100644 index 0000000000000..c21cd797f1963 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_012.phpt @@ -0,0 +1,22 @@ +--TEST-- +Register Alloction 012: Missed type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_013.phpt b/ext/opcache/tests/jit/reg_alloc_013.phpt new file mode 100644 index 0000000000000..01d4640ddc8ac --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_013.phpt @@ -0,0 +1,19 @@ +--TEST-- +Register Alloction 013: Division by zero +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $j in %sreg_alloc_013.php on line 3 +DONE \ No newline at end of file diff --git a/ext/opcache/tests/jit/reg_alloc_014.phpt b/ext/opcache/tests/jit/reg_alloc_014.phpt new file mode 100644 index 0000000000000..03b7ae0667c1f --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_014.phpt @@ -0,0 +1,21 @@ +--TEST-- +Register Alloction 014: Register clobbering +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $a in %sreg_alloc_014.php on line 4 +DONE \ No newline at end of file diff --git a/ext/opcache/tests/opt/block_pass_003.phpt b/ext/opcache/tests/opt/block_pass_003.phpt new file mode 100644 index 0000000000000..25d32e1e4d70e --- /dev/null +++ b/ext/opcache/tests/opt/block_pass_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Block Pass 003: Inorrect constant substitution in FETCH_LIST_R +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--EXTENSIONS-- +opcache +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/opt/dce_013.phpt b/ext/opcache/tests/opt/dce_013.phpt new file mode 100644 index 0000000000000..ac5211498f6d1 --- /dev/null +++ b/ext/opcache/tests/opt/dce_013.phpt @@ -0,0 +1,12 @@ +--TEST-- +Incorrect DCE of FREE +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/opt/gh8074.phpt b/ext/opcache/tests/opt/gh8074.phpt new file mode 100644 index 0000000000000..86ec3449c476c --- /dev/null +++ b/ext/opcache/tests/opt/gh8074.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-8074 (Wrong type inference of range() result) +--FILE-- + +--EXPECT-- +int(2) +int(3) diff --git a/ext/opcache/tests/opt/gh8140a.phpt b/ext/opcache/tests/opt/gh8140a.phpt new file mode 100644 index 0000000000000..03f097c77c5ce --- /dev/null +++ b/ext/opcache/tests/opt/gh8140a.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-8140 (Wrong first class callable by name optimization) +--FILE-- + +--EXPECT-- +Hello, world! diff --git a/ext/opcache/tests/opt/gh8140b.phpt b/ext/opcache/tests/opt/gh8140b.phpt new file mode 100644 index 0000000000000..60da3a79e1408 --- /dev/null +++ b/ext/opcache/tests/opt/gh8140b.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-8140 (Wrong first class callable by name optimization) +--FILE-- + +--EXPECT-- +Hello, world! diff --git a/ext/opcache/tests/opt/inference_003.phpt b/ext/opcache/tests/opt/inference_003.phpt new file mode 100644 index 0000000000000..046396f212532 --- /dev/null +++ b/ext/opcache/tests/opt/inference_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Type inference 003: instanceof with unlinked class +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +getMessage()); + } +} +?> +--EXPECTF-- +Fatal error: Uncaught Error: Interface "I" not found in %sinference_003.php:2 +Stack trace: +#0 {main} + thrown in %sinference_003.php on line 2 + diff --git a/ext/opcache/tests/opt/sccp_036.phpt b/ext/opcache/tests/opt/sccp_036.phpt new file mode 100644 index 0000000000000..ce660ce1aad30 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_036.phpt @@ -0,0 +1,16 @@ +--TEST-- +SCCP 036: NAN handling +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/opt/sccp_037.phpt b/ext/opcache/tests/opt/sccp_037.phpt new file mode 100644 index 0000000000000..130db36052b39 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_037.phpt @@ -0,0 +1,13 @@ +--TEST-- +SCCP 037: Memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/tests/opt/sccp_038.phpt b/ext/opcache/tests/opt/sccp_038.phpt new file mode 100644 index 0000000000000..fdf663e87c362 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_038.phpt @@ -0,0 +1,18 @@ +--TEST-- +SCCP 038: Memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +$b = ~$b = $a = '##'; + $obj->$a++; +} +foo(); +?> +DONE +--EXPECT-- +DONE diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h index 7cf995f3175e9..755d3f13ec516 100644 --- a/ext/opcache/zend_accelerator_hash.h +++ b/ext/opcache/zend_accelerator_hash.h @@ -60,6 +60,8 @@ typedef struct _zend_accel_hash { uint32_t num_direct_entries; } zend_accel_hash; +BEGIN_EXTERN_C() + void zend_accel_hash_init(zend_accel_hash *accel_hash, uint32_t hash_size); void zend_accel_hash_clean(zend_accel_hash *accel_hash); @@ -90,4 +92,6 @@ static inline bool zend_accel_hash_is_full(zend_accel_hash *accel_hash) } } +END_EXTERN_C() + #endif /* ZEND_ACCELERATOR_HASH_H */ diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index f785303c936a7..b09eb9ff41ad9 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -182,7 +182,7 @@ static ZEND_INI_MH(OnUpdateCounter) *p = val; return SUCCESS; } - zend_error(E_WARNING, "Invalid \"%s\" setting. Should be between 0 and 256", ZSTR_VAL(entry->name)); + zend_error(E_WARNING, "Invalid \"%s\" setting; using default value instead. Should be between 0 and 255", ZSTR_VAL(entry->name)); return FAILURE; } diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h index 1ce661635c19a..53cc1de9effaa 100644 --- a/ext/opcache/zend_accelerator_util_funcs.h +++ b/ext/opcache/zend_accelerator_util_funcs.h @@ -25,6 +25,8 @@ #include "zend.h" #include "ZendAccelerator.h" +BEGIN_EXTERN_C() + zend_persistent_script* create_persistent_script(void); void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements); @@ -42,4 +44,6 @@ unsigned int zend_adler32(unsigned int checksum, unsigned char *buf, uint32_t le unsigned int zend_accel_script_checksum(zend_persistent_script *persistent_script); +END_EXTERN_C() + #endif /* ZEND_ACCELERATOR_UTIL_FUNCS_H */ diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index ef59254d70937..bbfe3771afac6 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -542,9 +542,6 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra case ZEND_FAST_CALL: SERIALIZE_PTR(opline->op1.jmp_addr); break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1369,9 +1366,6 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr case ZEND_FAST_CALL: UNSERIALIZE_PTR(opline->op1.jmp_addr); break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1872,13 +1866,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl goto use_process_mem; } -#if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - buf = zend_shared_alloc(info.mem_size + 64); - buf = (void*)(((zend_uintptr_t)buf + 63L) & ~63L); -#else - buf = zend_shared_alloc(info.mem_size); -#endif + buf = zend_shared_alloc_aligned(info.mem_size); if (!buf) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index a572f5e3be87e..e21fa4cb9af2b 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -590,9 +590,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc case ZEND_FAST_CALL: opline->op1.jmp_addr = &new_opcodes[opline->op1.jmp_addr - op_array->opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1262,6 +1259,7 @@ static void zend_accel_persist_class_table(HashTable *class_table) ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (op_array->type == ZEND_USER_FUNCTION) { if (op_array->scope == ce + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { @@ -1276,7 +1274,8 @@ static void zend_accel_persist_class_table(HashTable *class_table) if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { + if (op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { if ((op_array->scope != ce || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 53c7b61ff3f36..ad6b69b34613e 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -83,11 +83,12 @@ void zend_shared_alloc_create_lock(char *lockfile_path) snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX); lock_file = mkstemp(lockfile_name); - fchmod(lock_file, 0666); - if (lock_file == -1) { zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Unable to create lock file: %s (%d)", strerror(errno), errno); } + + fchmod(lock_file, 0666); + val = fcntl(lock_file, F_GETFD, 0); val |= FD_CLOEXEC; fcntl(lock_file, F_SETFD, val); diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 4e090b98ddadf..de5012b2204ad 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -125,6 +125,8 @@ extern zend_smm_shared_globals *smm_shared_globals; #define SHARED_ALLOC_REATTACHED (SUCCESS+1) +BEGIN_EXTERN_C() + int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size); void zend_shared_alloc_shutdown(void); @@ -132,6 +134,20 @@ void zend_shared_alloc_shutdown(void); void *zend_shared_alloc_pages(size_t requested_size); void *zend_shared_alloc(size_t size); +/** + * Wrapper for zend_shared_alloc() which aligns at 64-byte boundary if + * AVX or SSE2 are used. + */ +static inline void *zend_shared_alloc_aligned(size_t size) { +#if defined(__AVX__) || defined(__SSE2__) + /* Align to 64-byte boundary */ + void *p = zend_shared_alloc(size + 64); + return (void *)(((zend_uintptr_t)p + 63L) & ~63L); +#else + return zend_shared_alloc(size); +#endif +} + /* copy into shared memory */ void *zend_shared_memdup_get_put_free(void *source, size_t size); void *zend_shared_memdup_put_free(void *source, size_t size); @@ -200,4 +216,6 @@ void zend_shared_alloc_lock_win32(void); void zend_shared_alloc_unlock_win32(void); #endif +END_EXTERN_C() + #endif /* ZEND_SHARED_ALLOC_H */ diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 463dca61891cf..8931ba92af538 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1224,7 +1224,7 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi case SIGBUS: add_assoc_double_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr); break; -#ifdef SIGPOLL +#if defined(SIGPOLL) && !defined(__CYGWIN__) case SIGPOLL: add_assoc_long_ex(user_siginfo, "band", sizeof("band")-1, siginfo->si_band); # ifdef si_fd @@ -1563,9 +1563,11 @@ PHP_FUNCTION(pcntl_rfork) flags |= RFPROC; } +#ifdef RFTSIGZMB if ((flags & RFTSIGZMB) != 0) { flags |= RFTSIGFLAGS(csignal); } +#endif pid = rfork(flags); diff --git a/ext/pdo/pdo.stub.php b/ext/pdo/pdo.stub.php index 39a508bafcb15..ebe81b7a51ad8 100644 --- a/ext/pdo/pdo.stub.php +++ b/ext/pdo/pdo.stub.php @@ -4,6 +4,8 @@ class PDOException extends RuntimeException { + /** @var int|string */ + protected $code = 0; public ?array $errorInfo = null; } diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index d4c74eef624f8..72eda0c3ae99a 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 52ee252fdfc80d4d076f1c49842e333c27ed5102 */ + * Stub hash: 8d975a20d009e827f8d72ac19b94b55870b6bf9c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pdo_drivers, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -25,6 +25,12 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent INIT_CLASS_ENTRY(ce, "PDOException", class_PDOException_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + zval property_code_default_value; + ZVAL_LONG(&property_code_default_value, 0); + zend_string *property_code_name = zend_string_init("code", sizeof("code") - 1, 1); + zend_declare_property_ex(class_entry, property_code_name, &property_code_default_value, ZEND_ACC_PROTECTED, NULL); + zend_string_release(property_code_name); + zval property_errorInfo_default_value; ZVAL_NULL(&property_errorInfo_default_value); zend_string *property_errorInfo_name = zend_string_init("errorInfo", sizeof("errorInfo") - 1, 1); diff --git a/ext/pdo_mysql/tests/unsigned_bigint.phpt b/ext/pdo_mysql/tests/unsigned_bigint.phpt new file mode 100644 index 0000000000000..e2fc9604f24ae --- /dev/null +++ b/ext/pdo_mysql/tests/unsigned_bigint.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug GH-7837 (large bigints may be truncated) +--EXTENSIONS-- +pdo +pdo_mysql +mysqlnd +--SKIPIF-- + +--FILE-- +query("DROP TABLE IF EXISTS $tbl"); +$pdo->query("CREATE TABLE $tbl (`ubigint` bigint unsigned NOT NULL) ENGINE=InnoDB"); +$pdo->query("INSERT INTO $tbl (`ubigint`) VALUES (18446744073709551615)"); +$pdo->query("INSERT INTO $tbl (`ubigint`) VALUES (9223372036854775808)"); +$pdo->query("INSERT INTO $tbl (`ubigint`) VALUES (1)"); +$result = $pdo->query("SELECT ubigint FROM $tbl")->fetchAll(PDO::FETCH_ASSOC); +var_dump($result); +?> +--CLEAN-- + +--EXPECT-- +array(3) { + [0]=> + array(1) { + ["ubigint"]=> + string(20) "18446744073709551615" + } + [1]=> + array(1) { + ["ubigint"]=> + string(19) "9223372036854775808" + } + [2]=> + array(1) { + ["ubigint"]=> + int(1) + } +} diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 4f59913937af2..840b7aeb8be3e 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -487,8 +487,16 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ /* Force UID and PWD to be set in the DSN */ if (dbh->username && *dbh->username && !strstr(dbh->data_source, "uid") && !strstr(dbh->data_source, "UID")) { - char *dsn; - spprintf(&dsn, 0, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password); + /* XXX: Do we check if password is null? */ + size_t new_dsn_size = strlen(dbh->data_source) + + strlen(dbh->username) + strlen(dbh->password) + + strlen(";UID=;PWD=") + 1; + char *dsn = pemalloc(new_dsn_size, dbh->is_persistent); + if (dsn == NULL) { + /* XXX: Do we inform the caller? */ + goto fail; + } + snprintf(dsn, new_dsn_size, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password); pefree((char*)dbh->data_source, dbh->is_persistent); dbh->data_source = dsn; } diff --git a/ext/phar/phar.1.in b/ext/phar/phar.1.in index 323e77b0e2a3b..75c3a354825be 100644 --- a/ext/phar/phar.1.in +++ b/ext/phar/phar.1.in @@ -1,4 +1,4 @@ -.TH PHAR 1 "2021" "The PHP Group" "User Commands" +.TH PHAR 1 "2022" "The PHP Group" "User Commands" .SH NAME phar, phar.phar \- PHAR (PHP archive) command line tool .SH SYNOPSIS diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 91310c21e4967..6d5790e3089c4 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2531,7 +2531,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv { char halt_stub[] = "__HALT_COMPILER();"; zend_string *newstub; - char *tmp; phar_entry_info *entry, *newentry; size_t halt_offset; int restore_alias_len, global_flags = 0, closeoldfile; @@ -2635,9 +2634,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv } else { free_user_stub = 0; } - tmp = estrndup(user_stub, len); - if ((pos = php_stristr(tmp, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { - efree(tmp); + if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { if (closeoldfile) { php_stream_close(oldfile); } @@ -2650,8 +2647,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; if ((size_t)len != php_stream_write(newfile, user_stub, len) || 5 != php_stream_write(newfile, " ?>\r\n", 5)) { diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 07b784a0b9df2..3b2e4c2ca76aa 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -967,7 +967,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int int closeoldfile, free_user_stub; size_t signature_length; struct _phar_pass_tar_info pass; - char *buf, *signature, *tmp, sigbuf[8]; + char *buf, *signature, sigbuf[8]; char halt_stub[] = "__HALT_COMPILER();"; entry.flags = PHAR_ENT_PERM_DEF_FILE; @@ -1063,9 +1063,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int free_user_stub = 0; } - tmp = estrndup(user_stub, len); - if ((pos = php_stristr(tmp, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { - efree(tmp); + if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { if (error) { spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname); } @@ -1074,8 +1072,6 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; entry.fp = php_stream_fopen_tmpfile(); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index c5e38cabf7b87..bfa23e9768b32 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -1202,7 +1202,6 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int char *pos; static const char newstub[] = "fname); } @@ -1316,8 +1313,6 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; entry.fp = php_stream_fopen_tmpfile(); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a2832358d6baf..84ef8bdfbb450 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4637,7 +4637,7 @@ ZEND_METHOD(ReflectionClass, getConstants) array_init(return_value); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), key, constant) { - if (UNEXPECTED(zval_update_constant_ex(&constant->value, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&constant->value, constant->ce) != SUCCESS)) { RETURN_THROWS(); } @@ -4696,7 +4696,7 @@ ZEND_METHOD(ReflectionClass, getConstant) GET_REFLECTION_OBJECT_PTR(ce); constants_table = CE_CONSTANTS_TABLE(ce); ZEND_HASH_MAP_FOREACH_PTR(constants_table, c) { - if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, c->ce) != SUCCESS)) { RETURN_THROWS(); } } ZEND_HASH_FOREACH_END(); @@ -6522,9 +6522,7 @@ static int call_attribute_constructor( zval *args, uint32_t argc, HashTable *named_params, zend_string *filename) { zend_function *ctor = ce->constructor; - zend_execute_data *prev_execute_data, dummy_frame; - zend_function dummy_func; - zend_op dummy_opline; + zend_execute_data *call = NULL; ZEND_ASSERT(ctor != NULL); if (!(ctor->common.fn_flags & ZEND_ACC_PUBLIC)) { @@ -6535,30 +6533,43 @@ static int call_attribute_constructor( if (filename) { /* Set up dummy call frame that makes it look like the attribute was invoked * from where it occurs in the code. */ - memset(&dummy_frame, 0, sizeof(zend_execute_data)); - memset(&dummy_func, 0, sizeof(zend_function)); - memset(&dummy_opline, 0, sizeof(zend_op)); + zend_function dummy_func; + zend_op *opline; - prev_execute_data = EG(current_execute_data); - dummy_frame.prev_execute_data = prev_execute_data; - dummy_frame.func = &dummy_func; - dummy_frame.opline = &dummy_opline; + memset(&dummy_func, 0, sizeof(zend_function)); - dummy_func.type = ZEND_USER_FUNCTION; - dummy_func.common.fn_flags = + call = zend_vm_stack_push_call_frame_ex( + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_execute_data), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_function), sizeof(zval)), + 0, &dummy_func, 0, NULL); + + opline = (zend_op*)(call + 1); + memset(opline, 0, sizeof(zend_op)); + opline->opcode = ZEND_DO_FCALL; + opline->lineno = attr->lineno; + + call->opline = opline; + call->call = NULL; + call->return_value = NULL; + call->func = (zend_function*)(call->opline + 1); + call->prev_execute_data = EG(current_execute_data); + + memset(call->func, 0, sizeof(zend_function)); + call->func->type = ZEND_USER_FUNCTION; + call->func->op_array.fn_flags = attr->flags & ZEND_ATTRIBUTE_STRICT_TYPES ? ZEND_ACC_STRICT_TYPES : 0; - dummy_func.op_array.filename = filename; - - dummy_opline.opcode = ZEND_DO_FCALL; - dummy_opline.lineno = attr->lineno; + call->func->op_array.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; + call->func->op_array.filename = filename; - EG(current_execute_data) = &dummy_frame; + EG(current_execute_data) = call; } zend_call_known_function(ctor, obj, obj->ce, NULL, argc, args, named_params); if (filename) { - EG(current_execute_data) = prev_execute_data; + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_call_frame(call); } if (EG(exception)) { diff --git a/ext/reflection/tests/gh8080.phpt b/ext/reflection/tests/gh8080.phpt new file mode 100644 index 0000000000000..c9c861051ab85 --- /dev/null +++ b/ext/reflection/tests/gh8080.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-8080 (ReflectionClass::getConstants() depends on def. order) +--FILE-- + 'Test', + ]; + private const TEST = 'test'; +} + +class B extends A {} + +$r = new ReflectionClass(B::class); +var_dump( + $r->getConstants(), + $r->getConstant("LIST") +); +?> +--EXPECT-- +array(1) { + ["LIST"]=> + array(1) { + ["test"]=> + string(4) "Test" + } +} +array(1) { + ["test"]=> + string(4) "Test" +} diff --git a/ext/session/php_session.h b/ext/session/php_session.h index bc8c3548c7059..ef139196ca900 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -176,6 +176,7 @@ typedef struct _php_ps_globals { } mod_user_names; int mod_user_implemented; int mod_user_is_open; + zend_string *mod_user_class_name; const struct ps_serializer_struct *serializer; zval http_session_vars; bool auto_start; diff --git a/ext/session/session.c b/ext/session/session.c index 32e2f33ae3028..8212ad23cd7bb 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -472,6 +472,9 @@ static void php_session_save_current_state(int write) /* {{{ */ if (write) { IF_SESSION_VARS() { + zend_string *handler_class_name = PS(mod_user_class_name); + const char *handler_function_name; + if (PS(mod_data) || PS(mod_user_implemented)) { zend_string *val; @@ -483,12 +486,15 @@ static void php_session_save_current_state(int write) /* {{{ */ && zend_string_equals(val, PS(session_vars)) ) { ret = PS(mod)->s_update_timestamp(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); + handler_function_name = handler_class_name != NULL ? "updateTimestamp" : "update_timestamp"; } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); + handler_function_name = "write"; } zend_string_release_ex(val, 0); } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), ZSTR_EMPTY_ALLOC(), PS(gc_maxlifetime)); + handler_function_name = "write"; } } @@ -499,9 +505,14 @@ static void php_session_save_current_state(int write) /* {{{ */ "is correct (%s)", PS(mod)->s_name, PS(save_path)); + } else if (handler_class_name != NULL) { + php_error_docref(NULL, E_WARNING, "Failed to write session data using user " + "defined save handler. (session.save_path: %s, handler: %s::%s)", PS(save_path), + ZSTR_VAL(handler_class_name), handler_function_name); } else { php_error_docref(NULL, E_WARNING, "Failed to write session data using user " - "defined save handler. (session.save_path: %s)", PS(save_path)); + "defined save handler. (session.save_path: %s, handler: %s)", PS(save_path), + handler_function_name); } } } @@ -2042,6 +2053,12 @@ PHP_FUNCTION(session_set_save_handler) ++i; } ZEND_HASH_FOREACH_END(); + + if (PS(mod_user_class_name)) { + zend_string_release(PS(mod_user_class_name)); + } + PS(mod_user_class_name) = zend_string_copy(Z_OBJCE_P(obj)->name); + if (register_shutdown) { /* create shutdown function */ php_shutdown_function_entry shutdown_function_entry; @@ -2095,6 +2112,11 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } + if (PS(mod_user_class_name)) { + zend_string_release(PS(mod_user_class_name)); + PS(mod_user_class_name) = NULL; + } + /* remove shutdown function */ remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") - 1); @@ -2775,6 +2797,7 @@ static PHP_GINIT_FUNCTION(ps) /* {{{ */ ps_globals->session_status = php_session_none; ps_globals->default_mod = NULL; ps_globals->mod_user_implemented = 0; + ps_globals->mod_user_class_name = NULL; ps_globals->mod_user_is_open = 0; ps_globals->session_vars = NULL; ps_globals->set_handler = 0; diff --git a/ext/session/tests/gh7787.phpt b/ext/session/tests/gh7787.phpt new file mode 100644 index 0000000000000..b38398827b087 --- /dev/null +++ b/ext/session/tests/gh7787.phpt @@ -0,0 +1,90 @@ +--TEST-- +GH-7787: Provide more SessionHandler failure information +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.use_strict_mode=0 +session.save_handler=files +--FILE-- + true, + fn() => true, + fn() => 'foo|s:3:"foo";', + fn() => false, + fn() => true, + fn() => true, + fn() => sha1(random_bytes(32)), + fn() => true, + fn() => false, +); + +session_start(); +$_SESSION['foo'] = 'bar'; +session_write_close(); + +session_start(); +session_write_close(); + +?> +--EXPECTF-- +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: MySessionHandler::write) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: MySessionHandler::updateTimestamp) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: write) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: update_timestamp) in %s on line %d diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index d4f92082c3b2d..aafedcb99ddd3 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -67,6 +67,9 @@ if test "$PHP_SOCKETS" != "no"; then AC_CACHE_CHECK([if ancillary credentials uses ucred],[ac_cv_ucred], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include ]], [[struct ucred u = {.gid = 0};]])], [ac_cv_ucred=yes], [ac_cv_ucred=no]) diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 773ac5f3e02cd..90a79b83985c5 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1,3 +1,7 @@ +#ifdef __sun +/* to enable 'new' ancillary data layout instead */ +# define _XPG4_2 +#endif #include "sockaddr_conv.h" #include "conversions.h" #include "sendrecvmsg.h" /* for ancillary registry */ diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index f713d44ff8813..ef32661be09ff 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -718,7 +718,7 @@ int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_add return SUCCESS; } -#if !defined(ifr_ifindex) && defined(ifr_index) +#if !defined(ifr_ifindex) && (defined(ifr_index) || defined(__HAIKU__)) #define ifr_ifindex ifr_index #endif diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index 7029478486cb3..01cb773acb1da 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -14,6 +14,10 @@ +----------------------------------------------------------------------+ */ +#ifdef __sun +/* to enable 'new' ancillary data layout instead */ +# define _XPG4_2 +#endif #include #include "php_sockets.h" #include "sendrecvmsg.h" diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 6b52bb5c7cc56..8398e004d0b6c 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -463,7 +463,9 @@ static PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("SOCK_DGRAM", SOCK_DGRAM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_RAW", SOCK_RAW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_SEQPACKET",SOCK_SEQPACKET, CONST_CS | CONST_PERSISTENT); +#ifdef SOCK_RDM REGISTER_LONG_CONSTANT("SOCK_RDM", SOCK_RDM, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("MSG_OOB", MSG_OOB, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MSG_WAITALL", MSG_WAITALL, CONST_CS | CONST_PERSISTENT); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 8a429fdf3f8bc..f6a11e7231da1 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -115,7 +115,7 @@ static inline bool spl_array_is_object(spl_array_object *intern) /* {{{ */ } /* }}} */ -static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht); +static zend_result spl_array_skip_protected(spl_array_object *intern, HashTable *aht); static zend_never_inline void spl_array_create_ht_iter(HashTable *ht, spl_array_object* intern) /* {{{ */ { @@ -552,7 +552,10 @@ static void spl_array_unset_dimension(zend_object *object, zval *offset) /* {{{ spl_array_unset_dimension_ex(1, object, offset); } /* }}} */ -static int spl_array_has_dimension_ex(bool check_inherited, zend_object *object, zval *offset, int check_empty) /* {{{ */ +/* check_empty can take value 0, 1, or 2 + * 0/1 are used as normal boolean, but 2 is used for the case when this function is called from + * the offsetExists() method, in which case it needs to report the offset exist even if the value is null */ +static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object, zval *offset, int check_empty) /* {{{ */ { spl_array_object *intern = spl_array_from_obj(object); zval rv, *value = NULL, *tmp; @@ -873,7 +876,7 @@ static int spl_array_compare_objects(zval *o1, zval *o2) /* {{{ */ return result; } /* }}} */ -static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* {{{ */ +static zend_result spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* {{{ */ { zend_string *string_key; zend_ulong num_key; @@ -903,7 +906,7 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* return FAILURE; } /* }}} */ -static int spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ +static zend_result spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ { uint32_t *pos_ptr = spl_array_get_pos_ptr(aht, intern); @@ -915,7 +918,7 @@ static int spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ } } /* }}} */ -static int spl_array_next(spl_array_object *intern) /* {{{ */ +static zend_result spl_array_next(spl_array_object *intern) /* {{{ */ { HashTable *aht = spl_array_get_hash_table(intern); @@ -993,11 +996,9 @@ static HashTable *spl_array_it_get_gc(zend_object_iterator *iter, zval **table, } /* {{{ spl_array_set_array */ -static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, int just_array) { - if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) { - zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object", 0); - return; - } +static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, bool just_array) { + /* Handled by ZPP prior to this, or for __unserialize() before passing to here */ + ZEND_ASSERT(Z_TYPE_P(array) == IS_ARRAY || Z_TYPE_P(array) == IS_OBJECT); if (Z_TYPE_P(array) == IS_ARRAY) { zval_ptr_dtor(&intern->array); if (Z_REFCOUNT_P(array) == 1) { @@ -1576,7 +1577,7 @@ PHP_METHOD(ArrayObject, unserialize) if (intern->nApplyCount > 0) { zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited"); - return; + RETURN_THROWS(); } /* storage */ @@ -1739,6 +1740,11 @@ PHP_METHOD(ArrayObject, __unserialize) zval_ptr_dtor(&intern->array); ZVAL_UNDEF(&intern->array); } else { + if (Z_TYPE_P(storage_zv) != IS_OBJECT && Z_TYPE_P(storage_zv) != IS_ARRAY) { + /* TODO Use UnexpectedValueException instead? And better error message? */ + zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object", 0); + RETURN_THROWS(); + } spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1); } @@ -1770,7 +1776,7 @@ PHP_METHOD(ArrayObject, __unserialize) PHP_METHOD(ArrayObject, __debugInfo) { if (zend_parse_parameters_none() == FAILURE) { - return; + RETURN_THROWS(); } RETURN_ARR(spl_array_get_debug_info(Z_OBJ_P(ZEND_THIS))); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 5be57bccbf852..b6e53c2921b7d 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1939,7 +1939,11 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje zval retval; /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */ - if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) { + return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL); + } + if (intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + zend_execute_data *execute_data = EG(current_execute_data); spl_filesystem_file_free_line(intern); if (php_stream_eof(intern->u.file.stream)) { @@ -1948,11 +1952,6 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje } return FAILURE; } - if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) { - return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL); - } - - zend_execute_data *execute_data = EG(current_execute_data); zend_call_method_with_0_params(Z_OBJ_P(this_ptr), Z_OBJCE_P(ZEND_THIS), &intern->u.file.func_getCurr, "getCurrentLine", &retval); if (Z_ISUNDEF(retval)) { return FAILURE; @@ -2736,8 +2735,8 @@ PHP_METHOD(SplFileObject, seek) } } if (line_pos > 0) { - intern->u.file.current_line_num++; if (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { + intern->u.file.current_line_num++; spl_filesystem_file_free_line(intern); } } diff --git a/ext/spl/spl_directory.stub.php b/ext/spl/spl_directory.stub.php index 97942df9f0f30..ceb4b7124b5df 100644 --- a/ext/spl/spl_directory.stub.php +++ b/ext/spl/spl_directory.stub.php @@ -123,10 +123,16 @@ public function rewind(): void {} /** @tentative-return-type */ public function valid(): bool {} - /** @return int */ + /** + * @tentative-return-type + * @return int + */ public function key(): mixed {} // TODO change return type to string - /** @return DirectoryIterator */ + /** + * @tentative-return-type + * @return DirectoryIterator + */ public function current(): mixed {} // TODO narrow return type /** @tentative-return-type */ diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 03a0fd044afef..bcdb51ea54254 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: eab71d8a7172dba2dac3c6fa97b2064c7a99191f */ + * Stub hash: 3f2caf1c46760d8ef629ccb2e94ab0dba09f713b */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -102,7 +102,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_DirectoryIterator_valid arginfo_class_SplFileInfo_isWritable -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, IS_MIXED, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() #define arginfo_class_DirectoryIterator_current arginfo_class_DirectoryIterator_key diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index dac31fe8c3001..9fdbc34cb7fe5 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -48,6 +48,8 @@ typedef struct _spl_fixedarray { zend_long size; /* It is possible to resize this, so this can't be combined with the object */ zval *elements; + /* True if this was modified after the last call to get_properties or the hash table wasn't rebuilt. */ + bool should_rebuild_properties; } spl_fixedarray; typedef struct _spl_fixedarray_object { @@ -106,6 +108,7 @@ static void spl_fixedarray_init(spl_fixedarray *array, zend_long size) array->size = 0; /* reset size in case ecalloc() fails */ array->elements = safe_emalloc(size, sizeof(zval), 0); array->size = size; + array->should_rebuild_properties = true; spl_fixedarray_init_elems(array, 0, size); } else { spl_fixedarray_default_ctor(array); @@ -169,6 +172,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) /* nothing to do */ return; } + array->should_rebuild_properties = true; /* first initialization */ if (array->size == 0) { @@ -208,8 +212,28 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) HashTable *ht = zend_std_get_properties(obj); if (!spl_fixedarray_empty(&intern->array)) { + /* + * Usually, the reference count of the hash table is 1, + * except during cyclic reference cycles. + * + * Maintain the DEBUG invariant that a hash table isn't modified during iteration, + * and avoid unnecessary work rebuilding a hash table for unmodified properties. + * + * See https://github.com/php/php-src/issues/8079 and ext/spl/tests/fixedarray_022.phpt + * Also see https://github.com/php/php-src/issues/8044 for alternate considered approaches. + */ + if (!intern->array.should_rebuild_properties) { + /* Return the same hash table so that recursion cycle detection works in internal functions. */ + return ht; + } + intern->array.should_rebuild_properties = false; + zend_long j = zend_hash_num_elements(ht); + if (GC_REFCOUNT(ht) > 1) { + intern->std.properties = zend_array_dup(ht); + GC_TRY_DELREF(ht); + } for (zend_long i = 0; i < intern->array.size; i++) { zend_hash_index_update(ht, i, &intern->array.elements[i]); Z_TRY_ADDREF(intern->array.elements[i]); @@ -219,6 +243,10 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) zend_hash_index_del(ht, i); } } + if (HT_IS_PACKED(ht)) { + /* Engine doesn't expet packed array */ + zend_hash_packed_to_hash(ht); + } } return ht; @@ -362,6 +390,9 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off } spl_fixedarray_object *intern = spl_fixed_array_from_obj(object); + if (type != BP_VAR_IS && type != BP_VAR_R) { + intern->array.should_rebuild_properties = true; + } return spl_fixedarray_object_read_dimension_helper(intern, offset); } @@ -385,6 +416,7 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object * zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { + intern->array.should_rebuild_properties = true; /* Fix #81429 */ zval *ptr = &(intern->array.elements[index]); zval tmp; @@ -425,6 +457,7 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object * zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { + intern->array.should_rebuild_properties = true; zval_ptr_dtor(&(intern->array.elements[index])); ZVAL_NULL(&intern->array.elements[index]); } diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index e5ea360354f4d..ed327aa7aad6b 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -90,7 +90,7 @@ public function offsetGet($object): mixed {} * @implementation-alias SplObjectStorage::attach * @no-verify Cannot specify arg type because ArrayAccess does not */ - public function offsetSet(mixed $object, mixed $info = null): void {} + public function offsetSet($object, mixed $info = null): void {} /** * @param object $object diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 5e9044a088f1e..94991119cb6f1 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a3c87f5b7edd257e25d6651628dd9896e14f5715 */ + * Stub hash: 63dde3294f600164805befd79b1f670fbfb23571 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObserver_update, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, subject, SplSubject, 0) @@ -75,7 +75,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage_offsetSet, 0, 1, IS_VOID, 0) - ZEND_ARG_TYPE_INFO(0, object, IS_MIXED, 0) + ZEND_ARG_INFO(0, object) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, info, IS_MIXED, 0, "null") ZEND_END_ARG_INFO() diff --git a/ext/spl/tests/fixedarray_022.phpt b/ext/spl/tests/fixedarray_022.phpt new file mode 100644 index 0000000000000..c1cff1a926582 --- /dev/null +++ b/ext/spl/tests/fixedarray_022.phpt @@ -0,0 +1,20 @@ +--TEST-- +SPL: FixedArray: Bug GH-8044 (var_export/debug_zval_dump HT_ASSERT_RC1 debug failure for SplFixedArray) +--FILE-- + +--EXPECTF-- +Warning: var_export does not handle circular references in %s on line 5 +SplFixedArray::__set_state(array( + 0 => NULL, +)) +object(SplFixedArray)#2 (1) refcount(4){ + [0]=> + *RECURSION* +} diff --git a/ext/spl/tests/fixedarray_023.phpt b/ext/spl/tests/fixedarray_023.phpt new file mode 100644 index 0000000000000..1d60a2ce6d9f7 --- /dev/null +++ b/ext/spl/tests/fixedarray_023.phpt @@ -0,0 +1,36 @@ +--TEST-- +SPL: FixedArray: Infinite loop in var_export bugfix +--FILE-- + +--EXPECTF-- +Warning: var_export does not handle circular references in %s on line 8 + +Warning: var_export does not handle circular references in %s on line 8 +SplFixedArray::__set_state(array( + 0 => NAN, + 1 => 0.0, + 2 => NULL, + 3 => NULL, +)) +object(SplFixedArray)#2 (4) refcount(6){ + [0]=> + float(NAN) + [1]=> + float(-0) + [2]=> + *RECURSION* + [3]=> + *RECURSION* +} \ No newline at end of file diff --git a/ext/spl/tests/fixedarray_024.phpt b/ext/spl/tests/fixedarray_024.phpt new file mode 100644 index 0000000000000..e0e2606c90a8a --- /dev/null +++ b/ext/spl/tests/fixedarray_024.phpt @@ -0,0 +1,11 @@ +--TEST-- +SPL: FixedArray: Bug GH-8041 (php 8.2.0-dev crashes with assertion for cloning/get_object_vars on non-empty SplFixedArray) +--FILE-- + +DONE +--EXPECT-- +DONE diff --git a/ext/spl/tests/gh8121.csv b/ext/spl/tests/gh8121.csv new file mode 100644 index 0000000000000..05fe5b0ac6242 --- /dev/null +++ b/ext/spl/tests/gh8121.csv @@ -0,0 +1,5 @@ +id,status,on_sale,brand,name,link,meta_title,meta_desc,description +1,2,15,Samsung,M21,samsung-m21,Samsung M21,Samsung M21,Samsung M21 +2,2,15,Samsung,M32,samsung-m32,Samsung M32,Samsung M32,Samsung M32 +3,2,15,Samsung,M21,samsung-m21,Samsung M21,Samsung M21,Samsung M21 +4,2,15,Samsung,M32,samsung-m32,Samsung M32,Samsung M32,Samsung M32 diff --git a/ext/spl/tests/gh8121.phpt b/ext/spl/tests/gh8121.phpt new file mode 100644 index 0000000000000..3e339cb52200c --- /dev/null +++ b/ext/spl/tests/gh8121.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-8121 (SplFileObject - seek and key with csv file inconsistent) +--FILE-- +setFlags($flags); + $file->seek(0); + var_dump($file->key()); + $file->seek(1); + var_dump($file->key()); + $file->seek(2); + var_dump($file->key()); + $file->seek(3); + var_dump($file->key()); +} +?> +--EXPECT-- +flags: 15 +int(0) +int(1) +int(2) +int(3) +flags: 7 +int(0) +int(1) +int(2) +int(3) +flags: 5 +int(0) +int(1) +int(2) +int(3) diff --git a/ext/standard/array.c b/ext/standard/array.c index aa89e3755b123..a3ce0d6c80cf7 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4529,9 +4529,9 @@ PHP_FUNCTION(array_change_key_case) entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } else { if (change_to_upper) { - new_key = php_string_toupper(string_key); + new_key = zend_string_toupper(string_key); } else { - new_key = php_string_tolower(string_key); + new_key = zend_string_tolower(string_key); } entry = zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); zend_string_release_ex(new_key, 0); diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 850c3f7a3051a..10a6cfd7f2af0 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -2175,6 +2175,9 @@ ZEND_END_ARG_INFO() #define arginfo_memory_get_peak_usage arginfo_memory_get_usage +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_memory_reset_peak_usage, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_version_compare, 0, 2, MAY_BE_LONG|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, version1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, version2, IS_STRING, 0) @@ -2824,6 +2827,7 @@ ZEND_FUNCTION(serialize); ZEND_FUNCTION(unserialize); ZEND_FUNCTION(memory_get_usage); ZEND_FUNCTION(memory_get_peak_usage); +ZEND_FUNCTION(memory_reset_peak_usage); ZEND_FUNCTION(version_compare); #if defined(PHP_WIN32) ZEND_FUNCTION(sapi_windows_cp_set); @@ -3479,6 +3483,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(unserialize, arginfo_unserialize) ZEND_FE(memory_get_usage, arginfo_memory_get_usage) ZEND_FE(memory_get_peak_usage, arginfo_memory_get_peak_usage) + ZEND_FE(memory_reset_peak_usage, arginfo_memory_reset_peak_usage) ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(version_compare, arginfo_version_compare) #if defined(PHP_WIN32) ZEND_FE(sapi_windows_cp_set, arginfo_sapi_windows_cp_set) diff --git a/ext/standard/crc32_x86.c b/ext/standard/crc32_x86.c index eec023264002f..fdcbed8782557 100644 --- a/ext/standard/crc32_x86.c +++ b/ext/standard/crc32_x86.c @@ -323,7 +323,7 @@ typedef size_t (*crc32_x86_simd_func_t)(X86_CRC32_TYPE type, uint32_t *crc, cons ZEND_NO_SANITIZE_ADDRESS ZEND_ATTRIBUTE_UNUSED /* clang mistakenly warns about this */ -static crc32_x86_simd_func_t resolve_crc32_x86_simd_update() { +static crc32_x86_simd_func_t resolve_crc32_x86_simd_update(void) { if (zend_cpu_supports_sse42() && zend_cpu_supports_pclmul()) { return crc32_sse42_pclmul_update; } diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index a6c867c949a54..2937f6a6da18a 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -42,6 +42,16 @@ # include #endif +#if defined(__APPLE__) + /* + Apple statvfs has an interger overflow in libc copying to statvfs. + cvt_statfs_to_statvfs(struct statfs *from, struct statvfs *to) { + to->f_blocks = (fsblkcnt_t)from->f_blocks; + */ +# undef HAVE_SYS_STATVFS_H +# undef HAVE_STATVFS +#endif + #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS) # include #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS) diff --git a/ext/standard/html.c b/ext/standard/html.c index b93ce95df1900..779fe549599bf 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -95,7 +95,7 @@ static inline unsigned int get_next_char( const unsigned char *str, size_t str_len, size_t *cursor, - int *status) + zend_result *status) { size_t pos = *cursor; unsigned int this_char = 0; @@ -356,7 +356,7 @@ PHPAPI unsigned int php_next_utf8_char( const unsigned char *str, size_t str_len, size_t *cursor, - int *status) + zend_result *status) { return get_next_char(cs_utf_8, str, str_len, cursor, status); } @@ -1045,8 +1045,8 @@ static inline void find_entity_for_char( *entity_len = c->data.ent.entity_len; } else { /* peek at next char */ - size_t cursor_before = *cursor; - int status = SUCCESS; + size_t cursor_before = *cursor; + zend_result status = SUCCESS; unsigned next_char; if (!(*cursor < oldlen)) @@ -1156,7 +1156,7 @@ PHPAPI zend_string *php_escape_html_entities_ex(const unsigned char *old, size_t const unsigned char *mbsequence = NULL; size_t mbseqlen = 0, cursor_before = cursor; - int status = SUCCESS; + zend_result status = SUCCESS; unsigned int this_char = get_next_char(charset, old, oldlen, &cursor, &status); /* guarantee we have at least 40 bytes to write. diff --git a/ext/standard/html.h b/ext/standard/html.h index 2a4757062165b..e7e9486d406ac 100644 --- a/ext/standard/html.h +++ b/ext/standard/html.h @@ -47,6 +47,6 @@ void register_html_constants(INIT_FUNC_ARGS); PHPAPI zend_string *php_escape_html_entities(const unsigned char *old, size_t oldlen, int all, int flags, const char *hint_charset); PHPAPI zend_string *php_escape_html_entities_ex(const unsigned char *old, size_t oldlen, int all, int flags, const char *hint_charset, bool double_encode, bool quiet); PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int flags, const char *hint_charset); -PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, int *status); +PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, zend_result *status); #endif /* HTML_H */ diff --git a/ext/standard/info.c b/ext/standard/info.c index e97faf627a639..5ac6ccb00ee96 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -270,11 +270,34 @@ char* php_get_windows_name() if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) { if (osvi.dwMajorVersion == 10) { - if( osvi.dwMinorVersion == 0 ) { - if( osvi.wProductType == VER_NT_WORKSTATION ) { - major = "Windows 10"; + if (osvi.dwMinorVersion == 0) { + if (osvi.wProductType == VER_NT_WORKSTATION) { + if (osvi.dwBuildNumber >= 22000) { + major = "Windows 11"; + } else { + major = "Windows 10"; + } } else { - major = "Windows Server 2016"; + if (osvi.dwBuildNumber >= 20348) { + major = "Windows Server 2022"; + } else if (osvi.dwBuildNumber >= 19042) { + major = "Windows Server, version 20H2"; + } else if (osvi.dwBuildNumber >= 19041) { + major = "Windows Server, version 2004"; + } else if (osvi.dwBuildNumber >= 18363) { + major = "Windows Server, version 1909"; + } else if (osvi.dwBuildNumber >= 18362) { + major = "Windows Server, version 1903"; + } else if (osvi.dwBuildNumber >= 17763) { + // could also be Windows Server, version 1809, but there's no easy way to tell + major = "Windows Server 2019"; + } else if (osvi.dwBuildNumber >= 17134) { + major = "Windows Server, version 1803"; + } else if (osvi.dwBuildNumber >= 16299) { + major = "Windows Server, version 1709"; + } else { + major = "Windows Server 2016"; + } } } } diff --git a/ext/standard/mail.c b/ext/standard/mail.c index bc5a06bec9cc3..003fad3ea18c5 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -425,6 +425,10 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co efree(logline); } + if (EG(exception)) { + MAIL_RET(0); + } + if (PG(mail_x_header)) { const char *tmp = zend_get_executed_filename(); zend_string *f; diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 46856874bc2a1..8736d291fb246 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -62,6 +62,7 @@ typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t); typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t); typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t); typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint); +typedef ZEND_SET_ALIGNED(1, int unaligned_int); /* Mapping of byte from char (8bit) to long for machine endian */ static int byte_map[1]; @@ -1043,8 +1044,14 @@ PHP_FUNCTION(unpack) case 'i': /* signed integer, machine size, machine endian */ case 'I': { /* unsigned integer, machine size, machine endian */ - unsigned int x = *((unaligned_uint*) &input[inputpos]); - zend_long v = (type == 'i') ? (int) x : x; + zend_long v; + if (type == 'i') { + int x = *((unaligned_int*) &input[inputpos]); + v = x; + } else { + unsigned int x = *((unaligned_uint*) &input[inputpos]); + v = x; + } ZVAL_LONG(&val, v); zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val); diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index f795e4e2b69f6..0f31ff1e42827 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -59,10 +59,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); - #if defined(_REENTRANT) # ifdef PHP_WIN32 # include diff --git a/ext/standard/string.c b/ext/standard/string.c index 7c2dce4595b0f..593c67cb32248 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1687,9 +1687,7 @@ PHP_FUNCTION(pathinfo) case insensitive strstr */ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len) { - zend_str_tolower(s, s_len); - zend_str_tolower(t, t_len); - return (char*)php_memnstr(s, t, t_len, s + s_len); + return (char*)php_memnistr(s, t, t_len, s + s_len); } /* }}} */ @@ -1735,8 +1733,6 @@ PHP_FUNCTION(stristr) zend_string *haystack, *needle; const char *found = NULL; size_t found_offset; - char *haystack_dup; - char *orig_needle; bool part = 0; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -1746,13 +1742,10 @@ PHP_FUNCTION(stristr) Z_PARAM_BOOL(part) ZEND_PARSE_PARAMETERS_END(); - haystack_dup = estrndup(ZSTR_VAL(haystack), ZSTR_LEN(haystack)); - orig_needle = estrndup(ZSTR_VAL(needle), ZSTR_LEN(needle)); - found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), ZSTR_LEN(needle)); - efree(orig_needle); + found = php_stristr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(haystack), ZSTR_LEN(needle)); if (found) { - found_offset = found - haystack_dup; + found_offset = found - ZSTR_VAL(haystack); if (part) { RETVAL_STRINGL(ZSTR_VAL(haystack), found_offset); } else { @@ -1761,8 +1754,6 @@ PHP_FUNCTION(stristr) } else { RETVAL_FALSE; } - - efree(haystack_dup); } /* }}} */ @@ -1890,7 +1881,6 @@ PHP_FUNCTION(stripos) const char *found = NULL; zend_string *haystack, *needle; zend_long offset = 0; - zend_string *needle_dup = NULL, *haystack_dup; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(haystack) @@ -1907,23 +1897,14 @@ PHP_FUNCTION(stripos) RETURN_THROWS(); } - if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) { - RETURN_FALSE; - } - - haystack_dup = zend_string_tolower(haystack); - needle_dup = zend_string_tolower(needle); - found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset, - ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack)); + found = (char*)php_memnistr(ZSTR_VAL(haystack) + offset, + ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack)); if (found) { - RETVAL_LONG(found - ZSTR_VAL(haystack_dup)); + RETVAL_LONG(found - ZSTR_VAL(haystack)); } else { RETVAL_FALSE; } - - zend_string_release_ex(haystack_dup, 0); - zend_string_release_ex(needle_dup, 0); } /* }}} */ @@ -3139,7 +3120,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha char *e; if (ZSTR_LEN(needle) == str_len) { - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); end = lc_haystack + ZSTR_LEN(haystack); for (p = lc_haystack; (r = (char*)php_memnstr(p, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle), end)); p = r + ZSTR_LEN(lc_needle)) { if (!new_str) { @@ -3160,7 +3141,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha const char *n; const char *endp = o + ZSTR_LEN(haystack); - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); n = ZSTR_VAL(lc_needle); while ((o = (char*)php_memnstr(o, n, ZSTR_LEN(lc_needle), endp))) { @@ -3204,7 +3185,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha nothing_todo: return zend_string_copy(haystack); } else { - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); if (memcmp(lc_haystack, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle))) { zend_string_release_ex(lc_needle, 0); @@ -5425,32 +5406,6 @@ static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case) } /* }}} */ -PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive) /* {{{ */ -{ - zend_string *tmp_str1, *tmp_str2; - zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); - zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); - - ZVAL_LONG(result, strnatcmp_ex(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2), case_insensitive)); - - zend_tmp_string_release(tmp_str1); - zend_tmp_string_release(tmp_str2); - return SUCCESS; -} -/* }}} */ - -PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */ -{ - return string_natural_compare_function_ex(result, op1, op2, 1); -} -/* }}} */ - -PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */ -{ - return string_natural_compare_function_ex(result, op1, op2, 0); -} -/* }}} */ - /* {{{ Returns the result of string comparison using 'natural' algorithm */ PHP_FUNCTION(strnatcmp) { @@ -6075,7 +6030,7 @@ static zend_string *php_utf8_decode(const char *s, size_t len) str = zend_string_alloc(len, 0); ZSTR_LEN(str) = 0; while (pos < len) { - int status = FAILURE; + zend_result status = FAILURE; c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status); /* The lower 256 codepoints of Unicode are identical to Latin-1, diff --git a/ext/standard/tests/mail/gh7875.phpt b/ext/standard/tests/mail/gh7875.phpt new file mode 100644 index 0000000000000..0947dcb3538f1 --- /dev/null +++ b/ext/standard/tests/mail/gh7875.phpt @@ -0,0 +1,46 @@ +--TEST-- +GH-7875 (mails are sent even if failure to log throws exception) +--SKIPIF-- + +--INI-- +sendmail_path={MAIL:{PWD}/gh7875.mail.out} +mail.log={PWD}/gh7875.mail.log +--FILE-- +getMessage(), PHP_EOL; + var_dump(file_exists(__DIR__ . "/gh7875.mail.out")); +} +?> +--CLEAN-- + +--EXPECTF-- +mail(%s): Failed to open stream: Permission denied +bool(false) diff --git a/ext/standard/tests/serialize/serialization_objects_016.phpt b/ext/standard/tests/serialize/serialization_objects_016.phpt new file mode 100644 index 0000000000000..92b83f5f3c9df --- /dev/null +++ b/ext/standard/tests/serialize/serialization_objects_016.phpt @@ -0,0 +1,32 @@ +--TEST-- +Object serialization / unserialization: circular object with rc=1 +--FILE-- +y=$t; +$y=(array)$t; +unset($t); +var_dump($y); +$s=serialize($y); +var_dump($s); +$x=unserialize($s); +var_dump($x); +vaR_dump(serialize($x)); +?> +--EXPECTF-- +array(1) { + ["y"]=> + object(stdClass)#%d (1) { + ["y"]=> + *RECURSION* + } +} +string(45) "a:1:{s:1:"y";O:8:"stdClass":1:{s:1:"y";r:2;}}" +array(1) { + ["y"]=> + object(stdClass)#%d (1) { + ["y"]=> + *RECURSION* + } +} +string(45) "a:1:{s:1:"y";O:8:"stdClass":1:{s:1:"y";r:2;}}" diff --git a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt index b2fd29ad88098..b4bef8add4103 100644 --- a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt @@ -17,4 +17,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 1 *** -Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d +Fatal error: %rAllowed memory size of %d bytes exhausted%s\(tried to allocate %d bytes\)|Possible integer overflow in memory allocation \(4294901777 \+ 2097152\)%r in %s on line %d diff --git a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt index 0f777fbd38605..c83a37f00edb4 100644 --- a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt @@ -16,4 +16,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 2 *** -Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + 65556) in %s on line %d +Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + %r65556|65560%r) in %s on line %d diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt index 753821f654299..84e69008284d4 100644 --- a/ext/standard/tests/strings/pack64.phpt +++ b/ext/standard/tests/strings/pack64.phpt @@ -31,6 +31,11 @@ print_r(unpack("q", pack("q", 0))); print_r(unpack("q", pack("q", 0x8000000000000002))); print_r(unpack("q", pack("q", -1))); print_r(unpack("q", pack("q", 0x8000000000000000))); + +print_r(unpack("i", pack("i", 2147483647))); // Max int32 +print_r(unpack("i", pack("i", -2147483647))); +print_r(unpack("i", pack("i", -2147483648))); // Min int32 +print_r(unpack("I", pack("I", 4294967295))); // Max uint32 ?> --EXPECT-- Array @@ -113,3 +118,19 @@ Array ( [1] => -9223372036854775808 ) +Array +( + [1] => 2147483647 +) +Array +( + [1] => -2147483647 +) +Array +( + [1] => -2147483648 +) +Array +( + [1] => 4294967295 +) diff --git a/ext/standard/var.c b/ext/standard/var.c index ef4b019fb6e76..dc9f8639b146f 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -662,7 +662,11 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) / data->n += 1; - if (!is_ref && (Z_TYPE_P(var) != IS_OBJECT || Z_REFCOUNT_P(var) == 1)) { + if (is_ref) { + /* pass */ + } else if (Z_TYPE_P(var) != IS_OBJECT) { + return 0; + } else if (Z_REFCOUNT_P(var) == 1 && (Z_OBJ_P(var)->properties == NULL || GC_REFCOUNT(Z_OBJ_P(var)->properties) == 1)) { return 0; } @@ -1474,6 +1478,14 @@ PHP_FUNCTION(memory_get_peak_usage) { } /* }}} */ +/* {{{ Resets the peak PHP memory usage */ +PHP_FUNCTION(memory_reset_peak_usage) { + ZEND_PARSE_PARAMETERS_NONE(); + + zend_memory_reset_peak_usage(); +} +/* }}} */ + PHP_INI_BEGIN() STD_PHP_INI_ENTRY("unserialize_max_depth", "4096", PHP_INI_ALL, OnUpdateLong, unserialize_max_depth, php_basic_globals, basic_globals) PHP_INI_END() diff --git a/ext/xml/xml.c b/ext/xml/xml.c index be69940545cda..3753320dd0144 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -550,8 +550,8 @@ static zend_string *xml_utf8_decode(const XML_Char *s, size_t len, const XML_Cha str = zend_string_alloc(len, 0); ZSTR_LEN(str) = 0; while (pos < len) { - int status = FAILURE; - c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status); + zend_result status = FAILURE; + c = php_next_utf8_char((const unsigned char*)s, len, &pos, &status); if (status == FAILURE || c > 0xFFU) { c = '?'; diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index b8ad6c5b46c03..63a141e15057a 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -37,6 +37,9 @@ static zend_class_entry *zend_test_class; static zend_class_entry *zend_test_child_class; static zend_class_entry *zend_test_trait; static zend_class_entry *zend_test_attribute; +static zend_class_entry *zend_test_parameter_attribute; +static zend_class_entry *zend_test_class_with_method_with_parameter_attribute; +static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute; static zend_class_entry *zend_test_ns_foo_class; static zend_class_entry *zend_test_ns2_foo_class; static zend_class_entry *zend_test_ns2_ns_foo_class; @@ -313,6 +316,17 @@ static ZEND_FUNCTION(namespaced_func) RETURN_TRUE; } +static ZEND_FUNCTION(zend_test_parameter_with_attribute) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(1); +} + static zend_object *zend_test_class_new(zend_class_entry *class_type) { zend_object *obj = zend_objects_new(class_type); @@ -425,6 +439,50 @@ static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method) ZEND_PARSE_PARAMETERS_NONE(); } +static ZEND_METHOD(ZendTestParameterAttribute, __construct) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter); +} + +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(2); +} + +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(3); +} + +static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(4); +} + PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals) @@ -460,6 +518,61 @@ PHP_MINIT_FUNCTION(zend_test) attr->validator = zend_attribute_validate_zendtestattribute; } + zend_test_parameter_attribute = register_class_ZendTestParameterAttribute(); + zend_internal_attribute_register(zend_test_parameter_attribute, ZEND_ATTRIBUTE_TARGET_PARAMETER); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value1"); + } + + zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute(); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value2"); + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value3"); + } + + zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value4"); + } + zend_test_ns_foo_class = register_class_ZendTestNS_Foo(); zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo(); zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo(); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index b8dff45c340de..9361d81c267d8 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -45,6 +45,21 @@ final class ZendTestAttribute { } + final class ZendTestParameterAttribute { + public string $parameter; + + public function __construct(string $parameter) {} + } + + class ZendTestClassWithMethodWithParameterAttribute { + final public function no_override(string $parameter): int {} + public function override(string $parameter): int {} + } + + class ZendTestChildClassWithMethodWithParameterAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int {} + } + enum ZendTestUnitEnum { case Foo; case Bar; @@ -92,6 +107,8 @@ function zend_weakmap_remove(object $object): bool {} function zend_weakmap_dump(): array {} function zend_get_unit_enum(): ZendTestUnitEnum {} + + function zend_test_parameter_with_attribute(string $parameter): int {} } namespace ZendTestNS { diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 19cf8ffbd2539..22290c580d059 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7326163f8ce5340c12e74af72d47a8926eb39786 */ + * Stub hash: bf10c37919483ac04bc1f788ac6e59b5edab295e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -71,6 +71,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_parameter_with_attribute, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -91,6 +95,16 @@ ZEND_END_ARG_INFO() #define arginfo_class__ZendTestTrait_testMethod arginfo_ZendTestNS2_ZendSubNS_namespaced_func +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestParameterAttribute___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + #define arginfo_class_ZendTestNS_Foo_method arginfo_zend_test_void_return #define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return @@ -116,6 +130,7 @@ static ZEND_FUNCTION(zend_weakmap_attach); static ZEND_FUNCTION(zend_weakmap_remove); static ZEND_FUNCTION(zend_weakmap_dump); static ZEND_FUNCTION(zend_get_unit_enum); +static ZEND_FUNCTION(zend_test_parameter_with_attribute); static ZEND_FUNCTION(namespaced_func); static ZEND_METHOD(_ZendTestClass, is_object); static ZEND_METHOD(_ZendTestClass, __toString); @@ -123,6 +138,10 @@ static ZEND_METHOD(_ZendTestClass, returnsStatic); static ZEND_METHOD(_ZendTestClass, returnsThrowable); static ZEND_METHOD(_ZendTestChildClass, returnsThrowable); static ZEND_METHOD(_ZendTestTrait, testMethod); +static ZEND_METHOD(ZendTestParameterAttribute, __construct); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override); +static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override); static ZEND_METHOD(ZendTestNS_Foo, method); static ZEND_METHOD(ZendTestNS2_Foo, method); static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method); @@ -147,6 +166,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove) ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump) ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum) + ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute) ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func) ZEND_FE_END }; @@ -183,6 +203,25 @@ static const zend_function_entry class_ZendTestAttribute_methods[] = { }; +static const zend_function_entry class_ZendTestParameterAttribute_methods[] = { + ZEND_ME(ZendTestParameterAttribute, __construct, arginfo_class_ZendTestParameterAttribute___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + +static const zend_function_entry class_ZendTestClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, no_override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + +static const zend_function_entry class_ZendTestChildClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestChildClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + static const zend_function_entry class_ZendTestUnitEnum_methods[] = { ZEND_FE_END }; @@ -314,6 +353,43 @@ static zend_class_entry *register_class_ZendTestAttribute(void) return class_entry; } +static zend_class_entry *register_class_ZendTestParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; + + zval property_parameter_default_value; + ZVAL_UNDEF(&property_parameter_default_value); + zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, 1); + zend_declare_typed_property(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_parameter_name); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_class_entry *class_entry_ZendTestClassWithMethodWithParameterAttribute) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute); + + return class_entry; +} + static zend_class_entry *register_class_ZendTestUnitEnum(void) { zend_class_entry *class_entry = zend_register_internal_enum("ZendTestUnitEnum", IS_UNDEF, class_ZendTestUnitEnum_methods); diff --git a/ext/zend_test/tests/attribute_arguments.phpt b/ext/zend_test/tests/attribute_arguments.phpt new file mode 100644 index 0000000000000..e1ec8a89d9a00 --- /dev/null +++ b/ext/zend_test/tests/attribute_arguments.phpt @@ -0,0 +1,169 @@ +--TEST-- +Verify that parameter attributes for native functions correctly support arguments. +--EXTENSIONS-- +zend_test +--FILE-- +getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestClassWithMethodWithParameterAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestClassWithMethodWithParameterAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestChildClassWithMethodWithParameterAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestChildClassWithMethodWithParameterAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +class ChildClassWithNoAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int + { + return 5; + } +} + +$reflection = new ReflectionMethod("ChildClassWithNoAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithNoAttribute", "override"); +var_dump(count($reflection->getParameters()[0]->getAttributes())); + +class ChildClassWithSameAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[ZendTestParameterAttribute("value5")] string $parameter): int + { + return 6; + } +} + +$reflection = new ReflectionMethod("ChildClassWithSameAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithSameAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class SomeAttribute { + public function __construct(public string $someParam) { } +} + +class ChildClassWithDifferentAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[SomeAttribute("value6")] string $parameter): int + { + return 7; + } +} + +$reflection = new ReflectionMethod("ChildClassWithDifferentAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithDifferentAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +?> +--EXPECTF-- +array(1) { + [0]=> + string(6) "value1" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value1" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value3" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value3" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value4" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value4" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +int(0) +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value5" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value5" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value6" +} +object(SomeAttribute)#%d (1) { + ["someParam"]=> + string(6) "value6" +} diff --git a/ext/zend_test/tests/attribute_hash_table_leak.phpt b/ext/zend_test/tests/attribute_hash_table_leak.phpt new file mode 100644 index 0000000000000..10c786393589e --- /dev/null +++ b/ext/zend_test/tests/attribute_hash_table_leak.phpt @@ -0,0 +1,68 @@ +--TEST-- +Verify that parameter attributes for native functions do not leak. +--EXTENSIONS-- +zend_test +--FILE-- +no_override("foo")); +var_dump($o->override("foo")); + +$o = new ZendTestChildClassWithMethodWithParameterAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +class ChildClassWithNoAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int + { + return 5; + } +} + +$o = new ChildClassWithNoAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +class ChildClassWithSameAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[ZendTestParameterAttribute] string $parameter): int + { + return 6; + } +} + +$o = new ChildClassWithSameAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class SomeAttribute { + +} + +class ChildClassWithDifferentAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[SomeAttribute] string $parameter): int + { + return 7; + } +} + +$o = new ChildClassWithDifferentAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +?> +--EXPECT-- +int(1) +int(2) +int(3) +int(2) +int(4) +int(2) +int(5) +int(2) +int(6) +int(2) +int(7) diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt new file mode 100644 index 0000000000000..1d1e3c4256e0e --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_1.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #81430 (Attribute instantiation frame accessing invalid frame pointer) +--EXTENSIONS-- +zend-test +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + + diff --git a/ext/zend_test/tests/observer_bug81430_2.phpt b/ext/zend_test/tests/observer_bug81430_2.phpt new file mode 100644 index 0000000000000..a575fb9d7a038 --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_2.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #81430 (Attribute instantiation leaves dangling execute_data pointer) +--EXTENSIONS-- +zend-test +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d + + diff --git a/ext/zlib/tests/gh7953.phpt b/ext/zlib/tests/gh7953.phpt new file mode 100644 index 0000000000000..e5cc283e62fb5 --- /dev/null +++ b/ext/zlib/tests/gh7953.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-7953 (ob_clean() only may not set Content-* header) +--EXTENSIONS-- +zlib +--CGI-- +--ENV-- +HTTP_ACCEPT_ENCODING=gzip +--FILE-- + +--EXPECTF-- +%a +--EXPECTHEADERS-- +Content-Encoding: gzip +Vary: Accept-Encoding diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 81a23c48c8444..09188dc76941e 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -281,7 +281,7 @@ static int php_zlib_output_handler(void **handler_context, php_output_context *o return FAILURE; } - if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) { + if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN) || (output_context->op & PHP_OUTPUT_HANDLER_START)) { int flags; if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags)) { diff --git a/main/fastcgi.c b/main/fastcgi.c index e3acd9ac3a186..6020cf4fda9a4 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1742,7 +1742,7 @@ void fcgi_free_mgmt_var_cb(zval *zv) pefree(Z_STR_P(zv), 1); } -const char *fcgi_get_last_client_ip() +const char *fcgi_get_last_client_ip(void) { static char str[INET6_ADDRSTRLEN]; diff --git a/main/main.c b/main/main.c index a0f1a658c661a..2a417987f3148 100644 --- a/main/main.c +++ b/main/main.c @@ -2278,6 +2278,9 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod module->version = PHP_VERSION; module->info_func = PHP_MINFO(php_core); } + + /* freeze the list of observer fcall_init handlers */ + zend_observer_post_startup(); /* Extensions that add engine hooks after this point do so at their own peril */ zend_finalize_system_id(); diff --git a/main/php.h b/main/php.h index 91ecbb21dc726..e8fcea5b6f607 100644 --- a/main/php.h +++ b/main/php.h @@ -344,6 +344,7 @@ END_EXTERN_C() #define phpin zendin #define php_memnstr zend_memnstr +#define php_memnistr zend_memnistr /* functions */ BEGIN_EXTERN_C() diff --git a/main/php_ini.c b/main/php_ini.c index c41da5b432c38..d080163663851 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -686,8 +686,9 @@ int php_init_config(void) if (VCWD_STAT(ini_file, &sb) == 0) { if (S_ISREG(sb.st_mode)) { zend_file_handle fh; - zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file); - if (fh.handle.fp) { + FILE *file = VCWD_FOPEN(ini_file, "r"); + if (file) { + zend_stream_init_fp(&fh, file, ini_file); if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) { /* Here, add it to the list of ini files read */ l = (int)strlen(ini_file); @@ -695,8 +696,8 @@ int php_init_config(void) p = estrndup(ini_file, l); zend_llist_add_element(&scanned_ini_list, &p); } + zend_destroy_file_handle(&fh); } - zend_destroy_file_handle(&fh); } } free(namelist[i]); diff --git a/main/php_variables.c b/main/php_variables.c index 127196779f221..0261cf0098ee4 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -571,11 +571,15 @@ void _php_import_environment_variables(zval *array_ptr) import_environment_variable(Z_ARRVAL_P(array_ptr), *env); } #else - char *environment = GetEnvironmentStringsA(); - for (char *env = environment; env != NULL && *env; env += strlen(env) + 1) { - import_environment_variable(Z_ARRVAL_P(array_ptr), env); + wchar_t *environmentw = GetEnvironmentStringsW(); + for (wchar_t *envw = environmentw; envw != NULL && *envw; envw += wcslen(envw) + 1) { + char *env = php_win32_cp_w_to_any(envw); + if (env != NULL) { + import_environment_variable(Z_ARRVAL_P(array_ptr), env); + free(env); + } } - FreeEnvironmentStringsA(environment); + FreeEnvironmentStringsW(environmentw); #endif tsrm_env_unlock(); diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 75511ef3bd701..7d5f444d1c54a 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1020,7 +1020,7 @@ static void php_cgi_usage(char *argv0) if (prog) { prog++; } else { - prog = "php"; + prog = "php-cgi"; } php_printf( "Usage: %s [-q] [-h] [-s] [-v] [-i] [-f ]\n" diff --git a/sapi/cli/php.1.in b/sapi/cli/php.1.in index 98c8dc76f2603..e8b84ad3d12a9 100644 --- a/sapi/cli/php.1.in +++ b/sapi/cli/php.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@php 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php \- PHP Command Line Interface 'CLI' .P diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c index 603ca7e24a80e..bcb5b4cef7a70 100644 --- a/sapi/fpm/fpm/fpm_children.c +++ b/sapi/fpm/fpm/fpm_children.c @@ -299,7 +299,7 @@ void fpm_children_bury() /* {{{ */ } } } else { - zlog(ZLOG_ALERT, "oops, unknown child (%d) exited %s. Please open a bug report (https://bugs.php.net).", pid, buf); + zlog(ZLOG_ALERT, "oops, unknown child (%d) exited %s. Please open a bug report (https://github.com/php/php-src/issues).", pid, buf); } } } diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 5380d184901bf..ec28af49d7c4b 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -226,6 +226,63 @@ void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard) { scoreboard->lock = 0; } +struct fpm_scoreboard_s *fpm_scoreboard_copy(struct fpm_scoreboard_s *scoreboard, int copy_procs) +{ + struct fpm_scoreboard_s *scoreboard_copy; + struct fpm_scoreboard_proc_s *scoreboard_proc_p; + size_t scoreboard_size, scoreboard_nprocs_size; + int i; + void *mem; + + if (!scoreboard) { + scoreboard = fpm_scoreboard_get(); + } + + if (copy_procs) { + scoreboard_size = sizeof(struct fpm_scoreboard_s); + scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs; + + mem = malloc(scoreboard_size + scoreboard_nprocs_size); + } else { + mem = malloc(sizeof(struct fpm_scoreboard_s)); + } + + if (!mem) { + zlog(ZLOG_ERROR, "scoreboard: failed to allocate memory for copy"); + return NULL; + } + + scoreboard_copy = mem; + + scoreboard = fpm_scoreboard_acquire(scoreboard, FPM_SCOREBOARD_LOCK_NOHANG); + if (!scoreboard) { + free(mem); + zlog(ZLOG_ERROR, "scoreboard: failed to lock (already locked)"); + return NULL; + } + + *scoreboard_copy = *scoreboard; + + if (copy_procs) { + mem += scoreboard_size; + + for (i = 0; i < scoreboard->nprocs; i++, mem += sizeof(struct fpm_scoreboard_proc_s)) { + scoreboard_proc_p = fpm_scoreboard_proc_acquire(scoreboard, i, FPM_SCOREBOARD_LOCK_HANG); + scoreboard_copy->procs[i] = *scoreboard_proc_p; + fpm_scoreboard_proc_release(scoreboard_proc_p); + } + } + + fpm_scoreboard_release(scoreboard); + + return scoreboard_copy; +} + +void fpm_scoreboard_free_copy(struct fpm_scoreboard_s *scoreboard) +{ + free(scoreboard); +} + struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang) /* {{{ */ { struct fpm_scoreboard_proc_s *proc; diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 17b73ae76066d..946b8262af44b 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -15,6 +15,9 @@ #define FPM_SCOREBOARD_ACTION_SET 0 #define FPM_SCOREBOARD_ACTION_INC 1 +#define FPM_SCOREBOARD_LOCK_HANG 0 +#define FPM_SCOREBOARD_LOCK_NOHANG 1 + struct fpm_scoreboard_proc_s { union { atomic_t lock; @@ -87,6 +90,9 @@ void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid); void fpm_scoreboard_proc_free(struct fpm_child_s *child); int fpm_scoreboard_proc_alloc(struct fpm_child_s *child); +struct fpm_scoreboard_s *fpm_scoreboard_copy(struct fpm_scoreboard_s *scoreboard, int copy_procs); +void fpm_scoreboard_free_copy(struct fpm_scoreboard_s *scoreboard); + #ifdef HAVE_TIMES float fpm_scoreboard_get_tick(void); #endif diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 09d2302806b6d..9514979ac1ce2 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -336,6 +336,7 @@ static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /* if (port == 0) { zlog(ZLOG_ERROR, "invalid port value '%s'", port_str); + free(dup_address); return -1; } diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index b086566cc5498..514d60d176e39 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -136,8 +136,8 @@ int fpm_status_export_to_zval(zval *status) int fpm_status_handle_request(void) /* {{{ */ { - struct fpm_scoreboard_s scoreboard, *scoreboard_p; - struct fpm_scoreboard_proc_s proc; + struct fpm_scoreboard_s *scoreboard_p; + struct fpm_scoreboard_proc_s *proc; char *buffer, *time_format, time_buffer[64]; time_t now_epoch; int full, encode, has_start_time; @@ -170,9 +170,17 @@ int fpm_status_handle_request(void) /* {{{ */ if (fpm_status_uri && !strcmp(fpm_status_uri, SG(request_info).request_uri)) { fpm_request_executing(); + /* full status ? */ + _GET_str = zend_string_init("_GET", sizeof("_GET")-1, 0); + full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL); + short_syntax = short_post = NULL; + full_separator = full_pre = full_syntax = full_post = NULL; + encode = 0; + has_start_time = 1; + scoreboard_p = fpm_scoreboard_get(); - if (scoreboard_p->shared) { - scoreboard_p = scoreboard_p->shared; + if (scoreboard_p) { + scoreboard_p = fpm_scoreboard_copy(scoreboard_p->shared ? scoreboard_p->shared : scoreboard_p, full); } if (!scoreboard_p) { zlog(ZLOG_ERROR, "status: unable to find or access status shared memory"); @@ -184,21 +192,9 @@ int fpm_status_handle_request(void) /* {{{ */ return 1; } - if (!fpm_spinlock(&scoreboard_p->lock, 1)) { - zlog(ZLOG_NOTICE, "[pool %s] status: scoreboard already in used.", scoreboard_p->pool); - SG(sapi_headers).http_response_code = 503; - sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); - sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); - sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); - PUTS("Server busy. Please try again later."); - return 1; - } - /* copy the scoreboard not to bother other processes */ - scoreboard = *scoreboard_p; - fpm_unlock(scoreboard_p->lock); - - if (scoreboard.idle < 0 || scoreboard.active < 0) { - zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard.pool); + if (scoreboard_p->idle < 0 || scoreboard_p->active < 0) { + fpm_scoreboard_free_copy(scoreboard_p); + zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard_p->pool); SG(sapi_headers).http_response_code = 500; sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); @@ -214,17 +210,10 @@ int fpm_status_handle_request(void) /* {{{ */ /* handle HEAD */ if (SG(request_info).headers_only) { + fpm_scoreboard_free_copy(scoreboard_p); return 1; } - /* full status ? */ - _GET_str = zend_string_init("_GET", sizeof("_GET")-1, 0); - full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL); - short_syntax = short_post = NULL; - full_separator = full_pre = full_syntax = full_post = NULL; - encode = 0; - has_start_time = 1; - /* HTML */ if (fpm_php_get_string_from_table(_GET_str, "html")) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1); @@ -430,7 +419,8 @@ int fpm_status_handle_request(void) /* {{{ */ "phpfpm_max_children_reached %u\n" "# 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"; + "phpfpm_slow_requests %lu\n" + "# EOF\n"; has_start_time = 0; if (!full) { @@ -485,37 +475,37 @@ int fpm_status_handle_request(void) /* {{{ */ now_epoch = time(NULL); if (has_start_time) { - strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard.start_epoch)); + strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard_p->start_epoch)); spprintf(&buffer, 0, short_syntax, - scoreboard.pool, - PM2STR(scoreboard.pm), + scoreboard_p->pool, + PM2STR(scoreboard_p->pm), time_buffer, - (unsigned long) (now_epoch - scoreboard.start_epoch), - scoreboard.requests, - scoreboard.lq, - scoreboard.lq_max, - scoreboard.lq_len, - scoreboard.idle, - scoreboard.active, - scoreboard.idle + scoreboard.active, - scoreboard.active_max, - scoreboard.max_children_reached, - scoreboard.slow_rq); + (unsigned long) (now_epoch - scoreboard_p->start_epoch), + scoreboard_p->requests, + scoreboard_p->lq, + scoreboard_p->lq_max, + scoreboard_p->lq_len, + scoreboard_p->idle, + scoreboard_p->active, + scoreboard_p->idle + scoreboard_p->active, + scoreboard_p->active_max, + scoreboard_p->max_children_reached, + scoreboard_p->slow_rq); } else { spprintf(&buffer, 0, short_syntax, - scoreboard.pool, - PM2STR(scoreboard.pm), - (unsigned long) (now_epoch - scoreboard.start_epoch), - scoreboard.requests, - scoreboard.lq, - scoreboard.lq_max, - scoreboard.lq_len, - scoreboard.idle, - scoreboard.active, - scoreboard.idle + scoreboard.active, - scoreboard.active_max, - scoreboard.max_children_reached, - scoreboard.slow_rq); + scoreboard_p->pool, + PM2STR(scoreboard_p->pm), + (unsigned long) (now_epoch - scoreboard_p->start_epoch), + scoreboard_p->requests, + scoreboard_p->lq, + scoreboard_p->lq_max, + scoreboard_p->lq_len, + scoreboard_p->idle, + scoreboard_p->active, + scoreboard_p->idle + scoreboard_p->active, + scoreboard_p->active_max, + scoreboard_p->max_children_reached, + scoreboard_p->slow_rq); } PUTS(buffer); @@ -546,7 +536,7 @@ int fpm_status_handle_request(void) /* {{{ */ if (!scoreboard_p->procs[i].used) { continue; } - proc = scoreboard_p->procs[i]; + proc = &scoreboard_p->procs[i]; if (first) { first = 0; @@ -558,44 +548,44 @@ int fpm_status_handle_request(void) /* {{{ */ query_string = NULL; tmp_query_string = NULL; - if (proc.query_string[0] != '\0') { + if (proc->query_string[0] != '\0') { if (!encode) { - query_string = proc.query_string; + query_string = proc->query_string; } else { - tmp_query_string = php_escape_html_entities_ex((const unsigned char *) proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, /* double_encode */ 1, /* quiet */ 0); + tmp_query_string = php_escape_html_entities_ex((const unsigned char *) proc->query_string, strlen(proc->query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, /* double_encode */ 1, /* quiet */ 0); query_string = ZSTR_VAL(tmp_query_string); } } /* prevent NaN */ - if (proc.cpu_duration.tv_sec == 0 && proc.cpu_duration.tv_usec == 0) { + if (proc->cpu_duration.tv_sec == 0 && proc->cpu_duration.tv_usec == 0) { cpu = 0.; } else { - cpu = (proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cutime + proc.last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.; + cpu = (proc->last_request_cpu.tms_utime + proc->last_request_cpu.tms_stime + proc->last_request_cpu.tms_cutime + proc->last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc->cpu_duration.tv_sec + proc->cpu_duration.tv_usec / 1000000.) * 100.; } - if (proc.request_stage == FPM_REQUEST_ACCEPTING) { - duration = proc.duration; + if (proc->request_stage == FPM_REQUEST_ACCEPTING) { + duration = proc->duration; } else { - timersub(&now, &proc.accepted, &duration); + timersub(&now, &proc->accepted, &duration); } - strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc.start_epoch)); + strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc->start_epoch)); spprintf(&buffer, 0, full_syntax, - (int) proc.pid, - fpm_request_get_stage_name(proc.request_stage), + (int) proc->pid, + fpm_request_get_stage_name(proc->request_stage), time_buffer, - (unsigned long) (now_epoch - proc.start_epoch), - proc.requests, + (unsigned long) (now_epoch - proc->start_epoch), + proc->requests, duration.tv_sec * 1000000UL + duration.tv_usec, - proc.request_method[0] != '\0' ? proc.request_method : "-", - proc.request_uri[0] != '\0' ? proc.request_uri : "-", + proc->request_method[0] != '\0' ? proc->request_method : "-", + proc->request_uri[0] != '\0' ? proc->request_uri : "-", query_string ? "?" : "", query_string ? query_string : "", - proc.content_length, - proc.auth_user[0] != '\0' ? proc.auth_user : "-", - proc.script_filename[0] != '\0' ? proc.script_filename : "-", - proc.request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0., - proc.request_stage == FPM_REQUEST_ACCEPTING ? proc.memory : 0); + proc->content_length, + proc->auth_user[0] != '\0' ? proc->auth_user : "-", + proc->script_filename[0] != '\0' ? proc->script_filename : "-", + proc->request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0., + proc->request_stage == FPM_REQUEST_ACCEPTING ? proc->memory : 0); PUTS(buffer); efree(buffer); @@ -609,6 +599,7 @@ int fpm_status_handle_request(void) /* {{{ */ } } + fpm_scoreboard_free_copy(scoreboard_p); return 1; } diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c index 4808447f5c924..350d75d1952e6 100644 --- a/sapi/fpm/fpm/zlog.c +++ b/sapi/fpm/fpm/zlog.c @@ -286,14 +286,8 @@ static zlog_bool zlog_stream_buf_alloc_ex(struct zlog_stream *stream, size_t nee { char *buf; size_t size = stream->buf.size ?: stream->buf_init_size; - - if (stream->buf.data) { - size = MIN(zlog_limit, MAX(size * 2, needed)); - buf = realloc(stream->buf.data, size); - } else { - size = MIN(zlog_limit, MAX(size, needed)); - buf = malloc(size); - } + size = MIN(zlog_limit, MAX((stream->buf.data ? (size << 1) : size), needed)); + buf = realloc(stream->buf.data, size); if (buf == NULL) { return 0; @@ -637,10 +631,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (suffix != NULL) { stream->msg_suffix_len = strlen(suffix); len = stream->msg_suffix_len + 1; - stream->msg_suffix = malloc(len); if (stream->msg_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_suffix = malloc(len); if (stream->msg_suffix == NULL) { return ZLOG_FALSE; } @@ -650,10 +644,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (final_suffix != NULL) { stream->msg_final_suffix_len = strlen(final_suffix); len = stream->msg_final_suffix_len + 1; - stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix == NULL) { return ZLOG_FALSE; } diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index 905946e70b119..6525c1eadad64 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -1,4 +1,4 @@ -.TH PHP-FPM 8 "2021" "The PHP Group" "Scripting Language" +.TH PHP-FPM 8 "2022" "The PHP Group" "Scripting Language" .SH NAME .TP 15 php-fpm \- PHP FastCGI Process Manager 'PHP-FPM' diff --git a/sapi/fpm/tests/status.inc b/sapi/fpm/tests/status.inc index c8275567665f3..0e3f314b42209 100644 --- a/sapi/fpm/tests/status.inc +++ b/sapi/fpm/tests/status.inc @@ -241,7 +241,8 @@ class Status "phpfpm_max_children_reached " . $fields['max children reached'] . "\n" . "# 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'] . ")"; + "phpfpm_slow_requests " . $fields['slow requests'] . "\n" . + "# EOF)\n"; if (!preg_match($pattern, $body)) { echo "ERROR: Expected body does not match pattern\n"; diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index 3189d514c02e3..3ecd27d3fd991 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -16,6 +16,10 @@ #include
+#if defined(__FreeBSD__) +# include +#endif + #include "fuzzer.h" #include "fuzzer-sapi.h" #include "zend_exceptions.h" @@ -140,7 +144,13 @@ ZEND_ATTRIBUTE_UNUSED char *get_opcache_path(void) { /* Try relative to binary location. */ char path[MAXPATHLEN]; +#if defined(__FreeBSD__) + size_t pathlen = sizeof(path); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + if (sysctl(mib, 4, path, &pathlen, NULL, 0) < 0) { +#else if (readlink("/proc/self/exe", path, sizeof(path)) < 0) { +#endif ZEND_ASSERT(0 && "Failed to get binary path"); return NULL; } diff --git a/sapi/phpdbg/phpdbg.1.in b/sapi/phpdbg/phpdbg.1.in index 29f832407db75..926a1edcc4ed9 100644 --- a/sapi/phpdbg/phpdbg.1.in +++ b/sapi/phpdbg/phpdbg.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpdbg 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpdbg 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpdbg \- The interactive PHP debugger .SH SYNOPSIS diff --git a/scripts/man1/php-config.1.in b/scripts/man1/php-config.1.in index 20f09d611f114..5ed77c574cb42 100644 --- a/scripts/man1/php-config.1.in +++ b/scripts/man1/php-config.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php\-config 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@php\-config 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php\-config \- get information about PHP configuration and compile options .SH SYNOPSIS diff --git a/scripts/man1/phpize.1.in b/scripts/man1/phpize.1.in index 308b51e03d009..bf50aa0c1df37 100644 --- a/scripts/man1/phpize.1.in +++ b/scripts/man1/phpize.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpize 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpize 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpize \- prepare a PHP extension for compiling .SH SYNOPSIS diff --git a/tests/basic/gh7896.phpt b/tests/basic/gh7896.phpt new file mode 100644 index 0000000000000..2ad2958d1cd9a --- /dev/null +++ b/tests/basic/gh7896.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-7896 (Environment vars may be mangled on Windows) +--SKIPIF-- + +--ENV-- +FÖÖ=GüИter传 +--FILE-- + +--EXPECT-- +string(11) "GüИter传" +string(11) "GüИter传" +string(11) "GüИter传" diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 1b12c4a8ff77f..9bf1bf28141d4 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3101,9 +3101,11 @@ function toolset_get_compiler_name(short) version = probe_binary(PHP_CL).substr(0, 5).replace('.', ''); - if (version >= 1930) { + if (version >= 1940) { return name; - } if (version >= 1920) { + } else if (version >= 1930) { + name = short ? "VS17" : "Visual C++ 2022"; + } else if (version >= 1920) { /* NOTE - VS is intentional. Due to changes in recent Visual Studio versioning scheme referring to the exact VC++ version is hardly predictable. From this version on, it refers to diff --git a/win32/build/default.manifest b/win32/build/default.manifest index aa5da5c4d08c4..a73c2fb53d3ab 100644 --- a/win32/build/default.manifest +++ b/win32/build/default.manifest @@ -15,7 +15,7 @@ - + diff --git a/win32/winutil.c b/win32/winutil.c index 3d41873310f6a..e09944d131b9b 100644 --- a/win32/winutil.c +++ b/win32/winutil.c @@ -448,7 +448,7 @@ static zend_always_inline BOOL is_compatible(HMODULE handle, BOOL is_smaller, ch DWORD minor = pNTHeader->OptionalHeader.MinorLinkerVersion; #if PHP_LINKER_MAJOR == 14 - /* VS 2015, 2017 and 2019 are binary compatible, but only forward compatible. + /* VS 2015, 2017, 2019 and 2022 are binary compatible, but only forward compatible. It should be fine, if we load a module linked with an older one into the core linked with the newer one, but not the otherway round. Analogously, it should be fine, if a PHP build linked with an older version